OAuth 2.1 Security Implementation
Plugged.in implements OAuth 2.1 security best practices to ensure the highest level of security for MCP server authentication. This document outlines the security measures in place.OAuth 2.1 Overview
OAuth 2.1 is the next evolution of the OAuth 2.0 framework, consolidating security best practices from various OAuth extensions and eliminating insecure patterns.Key Difference: OAuth 2.1 is NOT a separate specification, but rather a consolidation of OAuth 2.0 + security best practices (PKCE, token rotation, etc.)
Implemented Security Features
1. PKCE (Proof Key for Code Exchange)
RFC 7636 - Mandatory for all OAuth flowsProtection Against
- Authorization code interception attacks
- Code injection attacks
- Man-in-the-middle attacks
Implementation
- S256 challenge method (SHA-256)
- 256-bit code verifier entropy
- Automatic verification on callback
2. State Parameter Integrity Binding
OAuth 2.1 Best Practice - Prevents PKCE state tamperingAttack Prevented: Attackers cannot modify stored PKCE state parameters (server UUID, user ID, code verifier) to steal tokens or hijack flows.
lib/oauth/integrity.ts- HMAC generation and verificationapp/actions/trigger-mcp-oauth.ts- Hash creationapp/api/oauth/callback/route.ts- Hash verification
3. Reduced PKCE Expiration (5 Minutes)
OAuth 2.1 Recommendation - Reduced attack windowWhy 5 minutes instead of 10?
Why 5 minutes instead of 10?
OAuth 2.1 recommends shorter PKCE state expiration to minimize the window for:
- Replay attacks
- Code interception attempts
- State prediction attacks
db/schema.ts- Schema documentationapp/actions/trigger-mcp-oauth.ts:447- State creationapp/api/oauth/callback/route.ts:166- Expiration check
4. Refresh Token Rotation
OAuth 2.1 Best Practice - Prevents token reuse attacksSingle-Use Tokens
Each refresh token can only be used once. After use, it’s immediately invalidated.
Reuse Detection
If a refresh token is reused, all tokens are revoked as a security measure.
db/schema.ts:1940- Schema definitionlib/oauth/token-refresh-service.ts:97-104- Reuse detectionlib/oauth/token-refresh-service.ts:128-139- Mark as usedlib/oauth/token-refresh-service.ts:179-190- Store new tokens
5. HTTP Basic Authentication for Client Credentials
RFC 6749 Section 2.3.1 - Prevents credential loggingSecurity Issue: Sending
client_secret in URL-encoded body causes it to be logged in:- Proxy access logs
- WAF logs
- Server access logs
- Load balancer logs
lib/oauth/token-refresh-service.ts:134-140- Token refreshapp/api/oauth/callback/route.ts- Token exchange
Security Enhancements Summary
| Feature | Standard | Plugged.in Implementation | Security Benefit |
|---|---|---|---|
| PKCE | RFC 7636 | ✅ S256 method, 256-bit entropy | Prevents code interception |
| State Integrity | OAuth 2.1 BP | ✅ HMAC-SHA256 binding | Prevents state tampering |
| PKCE Expiration | OAuth 2.1 BP | ✅ 5 minutes (vs 10) | Reduced attack window |
| Token Rotation | OAuth 2.1 BP | ✅ Single-use + reuse detection | Prevents token replay |
| Client Auth | RFC 6749 §2.3.1 | ✅ HTTP Basic Auth | Prevents credential logging |
| User Binding | OWASP | ✅ PKCE state → user_id FK | Prevents flow hijacking |
| Server Ownership | Custom | ✅ Multi-level validation | Prevents token substitution |
| Rate Limiting | OWASP | ✅ 10 req/15min on callback | Prevents brute force |
Attack Scenarios Prevented
Before OAuth 2.1 Implementation
❌ Authorization Code Injection → Attacker could hijack victim’s OAuth flow ❌ Token Reuse Attacks → Stolen refresh tokens could be used indefinitely ❌ State Parameter Tampering → Attacker could modify PKCE state to steal tokens ❌ Credential Logging → Client secrets exposed in access logs ❌ Extended Attack Window → 10-minute PKCE expiration too longAfter OAuth 2.1 Implementation
✅ All OAuth flows bound to authenticated user ✅ Refresh tokens are single-use only ✅ HMAC integrity verification prevents tampering ✅ Client secrets never logged (HTTP Basic Auth) ✅ 5-minute PKCE expiration reduces risk ✅ Automatic token revocation on reuse ✅ Server ownership validation ✅ Rate limiting on OAuth endpointsMigration Notes
Database Changes
Two migrations were applied to support OAuth 2.1: Migration 0071: State Integrity HashBackward Compatibility
✅ Fully Backward Compatible- Existing OAuth flows continue to work
- New security features apply to all new flows
- No breaking changes to API
- Automatic migration on application upgrade
Environment Variables
Required
.env
Recommended
.env
Monitoring & Observability
Structured Logging with Loki
Plugged.in uses structured JSON logging with Loki for comprehensive OAuth security monitoring. All security events are automatically logged with full context for analysis.See Observability Documentation for complete setup guide
Security Events Logged
All OAuth operations emit structured JSON logs to Loki:LogQL Security Queries
Critical Security Events (Last Hour):Prometheus Metrics
17 OAuth-specific metrics for real-time monitoring:Flow Success Rate
oauth_flows_total{status="success"} / oauth_flows_totalSLO: > 95%Token Reuse Detection
oauth_token_refresh_total{status="reuse_detected"}Alert: > 0 (Critical)Code Injection Attempts
oauth_code_injection_attempts_totalAlert: > 0 (Critical)Integrity Violations
oauth_integrity_violations_totalAlert: > 0 (High)Grafana Dashboards
Pre-built dashboards available in/observability/dashboards:
OAuth Overview
- Success rates
- Operations/min
- Active tokens
- Error trends
Security Dashboard
- Security events timeline
- Attack heatmap
- Top attackers
- Violation breakdown
Performance Dashboard
- Latency percentiles (p50, p95, p99)
- Throughput by provider
- Slow operations
- Discovery performance
Critical Alerts Configuration
Configure these alerts in Grafana:Metrics to Monitor
SLO: > 95%Metric:
oauth_flows_total{status="success"} / oauth_flows_totalAlert if: < 95% for 5 minutesSLO: > 99%Metric:
oauth_token_refresh_total{status="success"} / oauth_token_refresh_totalAlert if: < 99% for 5 minutesExpected: 0Metric:
oauth_token_refresh_total{status="reuse_detected"}Alert if: > 0 (IMMEDIATE - Critical)Expected: 0Metric:
oauth_code_injection_attempts_totalAlert if: > 0 (IMMEDIATE - Critical)Expected: ~0Metric:
oauth_integrity_violations_totalAlert if: > 5 per 15 minutes (High)SLO: < 2 secondsMetric:
histogram_quantile(0.95, oauth_token_refresh_duration_seconds_bucket)Alert if: > 2s for 5 minutesIncident Response Playbooks
Token Reuse Detected (P0)
Token Reuse Detected (P0)
Severity: Critical - Immediate action requiredIndicators:
oauth_refresh_token_reuse_detectedevent in logsoauth_token_refresh_total{status="reuse_detected"}> 0
- ✅ All tokens for server immediately revoked
- ✅ User forced to re-authenticate
- ✅ Security event logged with full context
- Check logs for
serverUuidanduserId - Review user’s recent OAuth activity
- Check for concurrent requests (race condition vs. attack)
- If attack: Block user IP, audit account
- If race condition: Review application logs, check for retry logic issues
Code Injection Attempt (P0)
Code Injection Attempt (P0)
Severity: Critical - Immediate action requiredIndicators:
oauth_code_injection_attemptevent in logsoauth_code_injection_attempts_total> 0
- ✅ Authorization code rejected
- ✅ Security event logged with attacker/victim details
- Identify attacker from logs:
attackerUserId - Identify victim:
victimUserId - Block attacker account immediately
- Notify victim user of attempted account compromise
- Audit all OAuth flows for both users in last 24h
- Check for pattern of attacks (same IP, same target servers)
Integrity Violations (P1)
Integrity Violations (P1)
Severity: High - Investigate within 1 hourIndicators:
oauth_integrity_violationevents in logsoauth_integrity_violations_totalincreasing
- State tampering attempt
- Database corruption
- Application bug (HMAC calculation mismatch)
- Check
violationType: hash_mismatch, state_reuse, user_mismatch - Review affected
serverUuidanduserId - If single occurrence: Likely user error or network issue
- If multiple from same user: Possible attack or client issue
- If widespread: Check for application deployment issues
Low Success Rate (P1)
Low Success Rate (P1)
Severity: High - Investigate within 1 hourIndicators:
- OAuth success rate < 95%
- Increased error rates in dashboards
- OAuth server downtime
- Network issues
- Configuration changes
- High user error rate (expired states, etc.)
- Check recent deployments
- Review error distribution by type
- Check OAuth server status
- Review network connectivity
- Check for expired PKCE states (>5 minutes)
Sensitive Data Redaction
All sensitive OAuth data is automatically redacted in logs:Redacted Fields (never logged in plaintext):
access_tokenrefresh_tokencode_verifierclient_secretauthorization_code
Testing OAuth 2.1 Compliance
Test State Integrity
Test Refresh Token Reuse
Test PKCE Expiration
References
RFC 7636
PKCE - Proof Key for Code Exchange
RFC 6749
OAuth 2.0 Authorization Framework
OAuth 2.1 Draft
OAuth 2.1 Specification (Draft)
Security BCP
OAuth 2.0 Security Best Practices

