> For the complete documentation index, see [llms.txt](https://xiang753017.gitbook.io/zixiang-blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xiang753017.gitbook.io/zixiang-blog/security/ietf-2025-oauth-2.0-best-current-practice.md).

# IETF 2025 OAuth 2.0 Best Current Practice

#### Open Redirector

這是個轉跳的方式，是 Auth Server 同意 client side 進行 external web 訪問。如果 server side 未嚴格檢查 redirect url 則容易使得 client side 被指引到惡意網站。

```markdown
https://example.com/login?redirect=`open redirctor`
[Example]: https://example.com/login?redirect=https://evil.com/fake-login
```

下面這張圖說明 OAuth 2.0 如何透過第三方登入。最危險的部分在於 Step 3，這邊主要是讓使用者輸入帳號密碼的地方（像是選擇 Google 登入，就會到 Google 頁面讓你輸入帳密）。

```mermaid
sequenceDiagram
    autonumber
    actor User as User / Browser
    participant Client as Client App
    participant Auth as Authorization Server

    User->>Client: Login with OAuth
    Client-->>User: Redirect to /authorize
    User->>Auth: GET /authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://client.com/callback&scope=openid
    Auth-->>User: Render Login & Consent Page
    Note over User,Auth: User approves authorization
    Auth-->>User: 302 Redirect (Location: https://client.com/callback?code=ABC)
    User->>Client: GET /callback?code=ABC
    Client->>Auth: POST /token (grant_type=authorization_code, code=ABC, client_id=CLIENT_ID)
    Auth-->>Client: Return Access Token Response
    Client-->>User: Login complete
```

核心攻擊情境為：Attacker 置換了 Client App (Browser) 的 `redirect_uri`。為防止 User 被轉導至釣魚網站並輸入帳密，Auth Server 必須對 `redirect_uri` 進行精準比對（如 `string.Eql(redirect_uri)`），絕不能使用模糊比對。

```mermaid
sequenceDiagram
    autonumber
    actor User as User / Browser
    participant Client as Client App
    participant Auth as Authorization Server

    User->>Client: Login with OAuth
    Client-->>User: Redirect to /authorize
    User->>Auth: GET /authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://client.com/callback&scope=openid

    Note over Auth: Security Verification:<br/>1. Exact string match for redirect_uri<br/>   (Exception: Dynamic ports allowed for Native Apps on localhost)<br/>2. Prevent credential leakage & Mix-up attacks

    alt redirect_uri match failed (Unregistered or mismatch)
        Auth-->>User: 400 Bad Request (Aborted without redirect)
    else redirect_uri match succeeded
        Auth-->>User: Render Login & Consent Page
        Note over User,Auth: User approves authorization
        Auth-->>User: 302 Redirect (Location: https://client.com/callback?code=ABC)
        User->>Client: GET /callback?code=ABC
        Client->>Auth: POST /token (grant_type=authorization_code, code=ABC, client_id=CLIENT_ID, redirect_uri=https://client.com/callback)
        Note over Auth: Re-verify redirect_uri in Token Request<br/>against the URI bound to the Authorization Code
        Auth-->>Client: Return Access Token Response
        Client-->>User: Login complete
    end
```
