exploiting-oauth-misconfiguration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Exploiting OAuth Misconfiguration

利用OAuth配置错误

When to Use

适用场景

  • During authorized penetration tests when the application uses OAuth 2.0 or OpenID Connect for authentication
  • When assessing "Sign in with Google/Facebook/GitHub" social login implementations
  • For testing single sign-on (SSO) flows between applications
  • When evaluating API authorization using OAuth bearer tokens
  • During security assessments of applications acting as OAuth providers or consumers
  • 在授权渗透测试期间,当应用使用OAuth 2.0或OpenID Connect进行身份验证时
  • 评估“使用Google/Facebook/GitHub登录”等社交登录实现时
  • 测试应用间的单点登录(SSO)流程时
  • 使用OAuth承载令牌评估API授权时
  • 对作为OAuth提供者或消费者的应用进行安全评估时

Prerequisites

前置条件

  • Authorization: Written penetration testing agreement covering OAuth/SSO flows
  • Burp Suite Professional: For intercepting OAuth redirect flows
  • Browser with DevTools: For monitoring redirect chains and token leakage
  • Multiple test accounts: On both the OAuth provider and the target application
  • curl: For manual OAuth flow testing
  • Attacker-controlled server: For receiving redirected tokens/codes
  • 授权许可: 涵盖OAuth/SSO流程的书面渗透测试协议
  • Burp Suite Professional: 用于拦截OAuth重定向流程
  • 带DevTools的浏览器: 用于监控重定向链和令牌泄露
  • 多个测试账户: 同时拥有OAuth提供者和目标应用的测试账户
  • curl: 用于手动测试OAuth流程
  • 攻击者可控服务器: 用于接收重定向的令牌/授权码

Workflow

操作流程

Step 1: Map the OAuth Flow and Configuration

步骤1:梳理OAuth流程与配置

Identify the OAuth grant type, endpoints, and configuration.
bash
undefined
识别OAuth授权类型、端点和配置信息。
bash
undefined

Discover OAuth/OIDC configuration endpoints

发现OAuth/OIDC配置端点

Key endpoints to identify:

需要识别的关键端点:

- Authorization endpoint: /oauth/authorize

- 授权端点: /oauth/authorize

- Token endpoint: /oauth/token

- 令牌端点: /oauth/token

- UserInfo endpoint: /oauth/userinfo

- 用户信息端点: /oauth/userinfo

- JWKS endpoint: /oauth/certs

- JWKS端点: /oauth/certs

Capture the authorization request in Burp

在Burp中捕获授权请求

Typical authorization code flow:

典型的授权码流程:

GET /oauth/authorize?

GET /oauth/authorize?

response_type=code&

response_type=code&

client_id=CLIENT_ID&

client_id=CLIENT_ID&

scope=openid profile email&

scope=openid profile email&

state=RANDOM_STATE

state=RANDOM_STATE

Identify the grant type:

识别授权类型:

- Authorization Code: response_type=code

- 授权码模式: response_type=code

- Implicit: response_type=token

- 隐式模式: response_type=token

- Hybrid: response_type=code+token

- 混合模式: response_type=code+token

Check for PKCE parameters:

检查PKCE参数:

- code_challenge=...

- code_challenge=...

- code_challenge_method=S256

- code_challenge_method=S256

undefined
undefined

Step 2: Test Redirect URI Manipulation

步骤2:测试重定向URI操纵

Attempt to redirect the authorization code or token to an attacker-controlled domain.
bash
undefined
尝试将授权码或令牌重定向到攻击者可控的域名。
bash
undefined

Test open redirect via redirect_uri

通过redirect_uri测试开放重定向

Original: redirect_uri=https://app.example.com/callback

原始地址: redirect_uri=https://app.example.com/callback

Attempt various bypasses:

尝试各种绕过方式:

If redirect_uri validation is path-based, try path traversal

如果redirect_uri验证是基于路径的,尝试路径遍历

If subdomain matching, try subdomain takeover + redirect

如果是子域名匹配,尝试子域名接管+重定向

undefined
undefined

Step 3: Test for Authorization Code and Token Theft

步骤3:测试授权码与令牌窃取

Exploit leakage vectors for stealing OAuth tokens and codes.
bash
undefined
利用泄露向量窃取OAuth令牌和授权码。
bash
undefined

Test token leakage via Referer header

通过Referer头测试令牌泄露

If implicit flow returns token in URL fragment:

如果隐式模式在URL片段中返回令牌:

And the callback page loads external resources,

且回调页面加载外部资源时,Referer头可能会泄露包含令牌的URL

the Referer header may leak the URL with the token

通过Referer测试授权码泄露

Test for authorization code leakage via Referer

在回调地址收到授权码后,检查:

After receiving code at callback, check if:

1. 页面是否加载外部图片/脚本

1. Page loads external images/scripts

2. 页面是否包含指向外部站点的链接

2. Page has links to external sites

Burp: 在代理历史中检查包含"code="的Referer头

Burp: Check Proxy History for Referer headers containing "code="

测试授权码重用

Test authorization code reuse

CODE="captured_auth_code"
CODE="captured_auth_code"

First use

第一次使用

curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"
curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"

Second use (should fail but may not)

第二次使用(理论上应该失败,但可能不会)

curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"
curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"

Test state parameter absence/predictability

测试state参数缺失/可预测性

Remove state parameter entirely

完全移除state参数

If no error, CSRF on OAuth flow is possible

如果没有报错,则OAuth流程可能存在CSRF风险

undefined
undefined

Step 4: Test Scope Escalation and Privilege Manipulation

步骤4:测试范围提升与权限操纵

Attempt to gain more permissions than intended.
bash
undefined
尝试获取超出预期的权限。
bash
undefined

Request additional scopes beyond what's needed

请求超出所需范围的额外权限

Test with elevated scope on token exchange

在令牌交换时测试提升范围

Test token with manipulated claims

测试篡改声明的令牌

If JWT access token, try modifying claims (see JWT testing skill)

如果是JWT访问令牌,尝试修改声明(请参考JWT测试技能)

Test refresh token scope escalation

测试刷新令牌范围提升

curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN&client_id=APP_ID&scope=admin+write"
curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN&client_id=APP_ID&scope=admin+write"

Test client credential flow with elevated permissions

测试客户端凭证流的提升权限

curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=client_credentials&client_id=APP_ID&client_secret=APP_SECRET&scope=admin"
undefined
curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=client_credentials&client_id=APP_ID&client_secret=APP_SECRET&scope=admin"
undefined

Step 5: Test for Account Takeover via OAuth

步骤5:测试通过OAuth接管账户

Exploit OAuth flows to take over victim accounts.
bash
undefined
利用OAuth流程接管受害者账户。
bash
undefined

Test missing email verification on OAuth provider

测试OAuth提供者缺少邮箱验证

1. Create an account on the OAuth provider with victim's email

1. 在OAuth提供者处使用受害者邮箱创建账户

2. OAuth login to the target app

2. 通过OAuth登录目标应用

3. If the app trusts the unverified email, account linking occurs

3. 如果应用信任未验证的邮箱,则会发生账户关联

Test pre-authentication account linking

测试预认证账户关联

1. Register on target app with victim's email (no OAuth)

1. 在目标应用使用受害者邮箱注册(不使用OAuth)

2. Attacker links their OAuth account to victim's email

2. 攻击者将自己的OAuth账户关联到受害者邮箱

3. Attacker can now login via OAuth to victim's account

3. 攻击者现在可以通过OAuth登录受害者账户

CSRF on account linking

账户关联的CSRF攻击

If /oauth/link endpoint lacks CSRF protection:

如果/oauth/link端点缺少CSRF保护:

1. Attacker initiates OAuth flow, captures the auth code

1. 攻击者启动OAuth流程,捕获授权码

2. Craft a page that submits the code to victim's session

2. 构造一个页面,将代码提交到受害者的会话中

3. Victim's account gets linked to attacker's OAuth account

3. 受害者的账户会被关联到攻击者的OAuth账户

Test token substitution

测试令牌替换

Use authorization code/token from one client_id with another

将来自一个client_id的授权码/令牌用于另一个client_id

curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE_FROM_APP_A&redirect_uri=https://app-b.example.com/callback&client_id=APP_B_ID&client_secret=APP_B_SECRET"
undefined
curl -s -X POST "https://auth.target.example.com/oauth/token"
-d "grant_type=authorization_code&code=$CODE_FROM_APP_A&redirect_uri=https://app-b.example.com/callback&client_id=APP_B_ID&client_secret=APP_B_SECRET"
undefined

Step 6: Test Client Secret and Token Security

步骤6:测试客户端密钥与令牌安全性

Assess the security of OAuth credentials and tokens.
bash
undefined
评估OAuth凭证和令牌的安全性。
bash
undefined

Check for exposed client secrets

检查是否存在暴露的客户端密钥

Search JavaScript source code

搜索JavaScript源代码

curl -s "https://target.example.com/static/app.js" | grep -i "client_secret|clientSecret|client_id"
curl -s "https://target.example.com/static/app.js" | grep -i "client_secret|clientSecret|client_id"

Check mobile app decompilation for hardcoded secrets

检查移动应用反编译后的硬编码密钥

Test token revocation

测试令牌吊销

ACCESS_TOKEN="captured_access_token"
ACCESS_TOKEN="captured_access_token"

Use the token

使用令牌

curl -s -H "Authorization: Bearer $ACCESS_TOKEN"
"https://api.target.example.com/me"
curl -s -H "Authorization: Bearer $ACCESS_TOKEN"
"https://api.target.example.com/me"

Revoke the token

吊销令牌

curl -s -X POST "https://auth.target.example.com/oauth/revoke"
-d "token=$ACCESS_TOKEN&token_type_hint=access_token"
curl -s -X POST "https://auth.target.example.com/oauth/revoke"
-d "token=$ACCESS_TOKEN&token_type_hint=access_token"

Test if revoked token still works

测试已吊销的令牌是否仍能使用

curl -s -H "Authorization: Bearer $ACCESS_TOKEN"
"https://api.target.example.com/me"
curl -s -H "Authorization: Bearer $ACCESS_TOKEN"
"https://api.target.example.com/me"

Test token lifetime

测试令牌生命周期

Decode JWT access token and check exp claim

解码JWT访问令牌并检查exp声明

echo "$ACCESS_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq .exp
echo "$ACCESS_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq .exp

Long-lived tokens (hours/days) increase attack window

长期令牌(数小时/数天)会增加攻击窗口

Check PKCE implementation

检查PKCE实现

If public client without PKCE, authorization code interception is possible

如果是未使用PKCE的公共客户端,授权码可能被拦截

undefined
undefined

Key Concepts

核心概念

ConceptDescription
Authorization Code FlowMost secure OAuth flow; exchanges short-lived code for tokens server-side
Implicit FlowDeprecated flow returning tokens directly in URL fragment; vulnerable to leakage
PKCEProof Key for Code Exchange; prevents authorization code interception attacks
Redirect URI ValidationServer-side validation that the redirect_uri matches registered values
State ParameterRandom value binding the OAuth request to the user's session, preventing CSRF
Scope EscalationRequesting or obtaining more permissions than authorized
Token LeakageExposure of OAuth tokens via Referer headers, logs, or browser history
Open RedirectUsing OAuth redirect_uri as an open redirect to steal tokens
概念描述
Authorization Code Flow最安全的OAuth流程;在服务器端用短期授权码交换令牌
Implicit Flow已弃用的流程,直接在URL片段中返回令牌;易受泄露攻击
PKCE授权码交换证明密钥;防止授权码拦截攻击
Redirect URI Validation服务器端验证redirect_uri是否与注册值匹配
State Parameter将OAuth请求与用户会话绑定的随机值,防止CSRF
Scope Escalation请求或获取超出授权范围的权限
Token LeakageOAuth令牌通过Referer头、日志或浏览器历史暴露
Open Redirect利用OAuth的redirect_uri作为开放重定向来窃取令牌

Tools & Systems

工具与系统

ToolPurpose
Burp Suite ProfessionalIntercepting OAuth redirect chains and modifying parameters
OWASP ZAPAutomated OAuth flow scanning
PostmanManual OAuth flow testing with environment variables
oauth-tools.comOnline OAuth flow debugging and testing
jwt.ioJWT token analysis for OAuth access tokens
Browser DevToolsMonitoring network requests and redirect chains
工具用途
Burp Suite Professional拦截OAuth重定向链并修改参数
OWASP ZAP自动化OAuth流程扫描
Postman使用环境变量手动测试OAuth流程
oauth-tools.com在线OAuth流程调试与测试
jwt.io分析OAuth访问令牌的JWT内容
Browser DevTools监控网络请求和重定向链

Common Scenarios

常见场景

Scenario 1: Redirect URI Subdomain Bypass

场景1:重定向URI子域名绕过

The OAuth provider validates
redirect_uri
against
*.example.com
. An attacker finds a subdomain vulnerable to takeover (
old.example.com
), takes it over, and steals authorization codes redirected to it.
OAuth提供者验证
redirect_uri
是否匹配
*.example.com
。攻击者找到一个易被接管的子域名(
old.example.com
),接管后窃取重定向到该子域名的授权码。

Scenario 2: Missing State Parameter CSRF

场景2:缺失State参数导致CSRF

The OAuth login flow does not include or validate a
state
parameter. An attacker crafts a link that logs the victim into the attacker's account, enabling account confusion attacks.
OAuth登录流程未包含或未验证
state
参数。攻击者构造一个链接,让受害者登录到攻击者的账户,从而实现账户混淆攻击。

Scenario 3: Implicit Flow Token Theft

场景3:隐式流程令牌窃取

The application uses the implicit flow, receiving the access token in the URL fragment. The callback page loads a third-party analytics script, and the token leaks via the Referer header.
应用使用隐式流程,在URL片段中返回访问令牌。回调页面加载第三方分析脚本时,令牌会通过Referer头泄露。

Scenario 4: Authorization Code Reuse

场景4:授权码可重用

The OAuth provider does not invalidate authorization codes after first use. An attacker who intercepts a code via Referer leakage can exchange it for an access token even after the legitimate user has completed the flow.
OAuth提供者在授权码首次使用后未使其失效。攻击者通过Referer泄露拦截到授权码后,即使合法用户已完成流程,仍能交换访问令牌。

Output Format

输出格式

undefined
undefined

OAuth Security Assessment Report

OAuth安全评估报告

Vulnerability: Redirect URI Validation Bypass Severity: High (CVSS 8.1) Location: GET /oauth/authorize - redirect_uri parameter OWASP Category: A07:2021 - Identification and Authentication Failures
漏洞: 重定向URI验证绕过 严重程度: 高(CVSS 8.1) 位置: GET /oauth/authorize - redirect_uri参数 OWASP分类: A07:2021 - 身份识别与认证失败

OAuth Configuration

OAuth配置信息

PropertyValue
Grant TypeAuthorization Code
PKCENot implemented
State ParameterPresent but predictable
Token TypeJWT (RS256)
Token Lifetime1 hour
Refresh Token30 days
属性
授权类型授权码模式
PKCE未实现
State参数存在但可预测
令牌类型JWT(RS256)
令牌生命周期1小时
刷新令牌30天

Findings

发现的问题

FindingSeverity
Redirect URI path traversal bypassHigh
Missing PKCE on public clientHigh
Authorization code reusableMedium
State parameter uses sequential valuesMedium
Client secret exposed in JavaScriptCritical
Token not revoked after password changeMedium
问题严重程度
重定向URI路径遍历绕过
公共客户端未实现PKCE
授权码可重用
State参数使用连续值
客户端密钥在JavaScript中暴露关键
修改密码后令牌未被吊销

Recommendation

建议

  1. Implement strict redirect_uri validation with exact string matching
  2. Require PKCE for all clients (especially public/mobile clients)
  3. Invalidate authorization codes after first use
  4. Use cryptographically random state parameters tied to user sessions
  5. Migrate from implicit flow to authorization code flow with PKCE
  6. Never expose client secrets in client-side code
undefined
  1. 实现严格的redirect_uri验证,采用精确字符串匹配
  2. 要求所有客户端(尤其是公共/移动客户端)使用PKCE
  3. 授权码首次使用后立即失效
  4. 使用与用户会话绑定的加密随机state参数
  5. 从隐式流程迁移到带PKCE的授权码流程
  6. 绝对不要在客户端代码中暴露客户端密钥
undefined