為什麼oauth 2.0規範裡 先後兩次提交併驗證redirect_uri
耗子寫了篇關於 oauth 的文章,其中第二個bug沒有看懂。翻了原文又翻了規範,後來才想通。
原文是 Bug 2. Lack of redirect_uri validation on get-token endpoint 換token(指的是access token)的時候缺少重定向地址的校驗。
(E) The authorization server authenticates the client, validates the
authorization code, and ensures that the redirection URI
received matches the URI used to redirect the client in
step (C).
redirect_uri這個重定向地址是讓第三方接收authorization code(授權碼) 來換access token的。對於第三方而言,誰給它授權碼誰就是合法使用者,後續將與之建立http會話回吐使用者的資訊。所以一旦這個地址被攻擊者改了,code就會被攔截,真正的使用者被重定向到了攻擊者的頁面,正常流程因此中斷;而攻擊者就可以拿著code重新拼裝好redirect_uri往瀏覽器裡一貼,無需密碼他就成了合法使用者,完成了session劫持。
redirect_uri是如此敏感,有個辦法可以在它leak(也就是被改掉)之後補救:第三方在換token的時候是拿著使用者給的code,加上自己受信的redirect_uri一起提交給服務提供方做驗證。如果之前服務提供方在前面返回code的時候,code是基於異常的redirect_uri計算出來的,那麼這一步重新校驗就可以知道兩者不匹配。
Egor在這兒說redirect_uri應該是個常量,看了下各家都嚴格做了限定。國內的qq和豆瓣是固定用第三方註冊時填寫的地址;google是可以註冊時填多個,但必須使用其中一個;github是必須使用註冊時的地址,或該地址的子目錄(因此給了攻擊者機會)。