JWT攻擊的九種手法:
空加密算法
JWT支持使用空加密算法,可以在header中指定alg為None,這樣的話,只要把signature設置為空(即不添加signature字段),提交到服務器,任何token都可以通過服務器的驗證。空加密算法的設計初衷是用于調試的,但是如果某天開發人員腦闊瓦特了,在生產環境中開啟了空加密算法,缺少簽名算法,jwt保證信息不被篡改的功能就失效了。攻擊者只需要把alg字段設置為None,就可以在payload中構造身份信息,偽造用戶身份。
None
修改RSA加密算法為HMAC
JWT中最常用的兩種算法為HMAC和RSA。HMAC是密鑰相關的哈希運算消息認證碼(Hash-based Message Authentication Code)的縮寫,它是一種對稱加密算法,使用相同的密鑰對傳輸信息進行加解密。RSA則是一種非對稱加密算法,使用私鑰加密明文,公鑰解密密文。在HMAC和RSA算法中,都是使用私鑰對signature字段進行簽名,只有拿到了加密時使用的私鑰,才有可能偽造token。
HMAC
RSA
signature
爆破密鑰
JWT的密鑰爆破需要在一定的前提下進行:
知悉JWT使用的加密算法
一段有效的、已簽名的token
簽名用的密鑰不復雜(弱密鑰)
所以其實JWT密鑰爆破的局限性很大。簡單的字母數字組合都是可以爆破的,但是密鑰位數稍微長一點或者更復雜一點的話,爆破時間就會需要很久。
修改KID參數
kid是jwt header中的一個可選參數,全稱是key ID,它用于指定加密算法的密鑰。因為該參數可以由用戶輸入,所以也可能造成一些安全問題。
kid
key ID
任意文件讀取
kid參數用于讀取密鑰文件,但系統并不會知道用戶想要讀取的到底是不是密鑰文件,所以,如果在沒有對參數進行過濾的前提下,攻擊者是可以讀取到系統的任意文件的。
SQL注入
kid也可以從數據庫中提取數據,這時候就有可能造成SQL注入攻擊,通過構造SQL語句來獲取數據或者是繞過signature的驗證。
命令注入
對kid參數過濾不嚴也可能會出現命令注入問題,但是利用條件比較苛刻。如果服務器后端使用的是Ruby,在讀取密鑰文件時使用了open函數,通過構造參數就可能造成命令注入。對于其他的語言,例如php,如果代碼中使用的是exec或者是system來讀取密鑰文件,那么同樣也可以造成命令注入,當然這個可能性就比較小了。
open
修改JKU/X5U參數
JKU的全稱是”JSON Web Key Set URL”,用于指定一組用于驗證令牌的密鑰的URL。類似于kid,JKU也可以由用戶指定輸入數據,如果沒有經過嚴格過濾,就可以指定一組自定義的密鑰文件,并指定web應用使用該組密鑰來驗證token。X5U則以URI的形式數允許攻擊者指定用于驗證令牌的公鑰證書或證書鏈,與JKU的攻擊利用方式類似。
JKU
X5U
信息泄露
JWT保證的是數據傳輸過程中的完整性而不是機密性。由于payload是使用base64url編碼的,所以相當于明文傳輸,如果在payload中攜帶了敏感信息(如存放密鑰對的文件路徑),單獨對payload部分進行base64url解碼,就可以讀取到payload中攜帶的信息。
base64url
回答所涉及的環境:聯想天逸510S、Windows 10。
JWT攻擊的九種手法:
空加密算法
JWT支持使用空加密算法,可以在header中指定alg為
None,這樣的話,只要把signature設置為空(即不添加signature字段),提交到服務器,任何token都可以通過服務器的驗證。空加密算法的設計初衷是用于調試的,但是如果某天開發人員腦闊瓦特了,在生產環境中開啟了空加密算法,缺少簽名算法,jwt保證信息不被篡改的功能就失效了。攻擊者只需要把alg字段設置為None,就可以在payload中構造身份信息,偽造用戶身份。修改RSA加密算法為HMAC
JWT中最常用的兩種算法為
HMAC和RSA。HMAC是密鑰相關的哈希運算消息認證碼(Hash-based Message Authentication Code)的縮寫,它是一種對稱加密算法,使用相同的密鑰對傳輸信息進行加解密。RSA則是一種非對稱加密算法,使用私鑰加密明文,公鑰解密密文。在HMAC和RSA算法中,都是使用私鑰對signature字段進行簽名,只有拿到了加密時使用的私鑰,才有可能偽造token。爆破密鑰
JWT的密鑰爆破需要在一定的前提下進行:
知悉JWT使用的加密算法
一段有效的、已簽名的token
簽名用的密鑰不復雜(弱密鑰)
所以其實JWT密鑰爆破的局限性很大。簡單的字母數字組合都是可以爆破的,但是密鑰位數稍微長一點或者更復雜一點的話,爆破時間就會需要很久。
修改KID參數
kid是jwt header中的一個可選參數,全稱是key ID,它用于指定加密算法的密鑰。因為該參數可以由用戶輸入,所以也可能造成一些安全問題。任意文件讀取
kid參數用于讀取密鑰文件,但系統并不會知道用戶想要讀取的到底是不是密鑰文件,所以,如果在沒有對參數進行過濾的前提下,攻擊者是可以讀取到系統的任意文件的。
SQL注入
kid也可以從數據庫中提取數據,這時候就有可能造成SQL注入攻擊,通過構造SQL語句來獲取數據或者是繞過signature的驗證。命令注入
對
kid參數過濾不嚴也可能會出現命令注入問題,但是利用條件比較苛刻。如果服務器后端使用的是Ruby,在讀取密鑰文件時使用了open函數,通過構造參數就可能造成命令注入。對于其他的語言,例如php,如果代碼中使用的是exec或者是system來讀取密鑰文件,那么同樣也可以造成命令注入,當然這個可能性就比較小了。修改JKU/X5U參數
JKU的全稱是”JSON Web Key Set URL”,用于指定一組用于驗證令牌的密鑰的URL。類似于kid,JKU也可以由用戶指定輸入數據,如果沒有經過嚴格過濾,就可以指定一組自定義的密鑰文件,并指定web應用使用該組密鑰來驗證token。X5U則以URI的形式數允許攻擊者指定用于驗證令牌的公鑰證書或證書鏈,與JKU的攻擊利用方式類似。信息泄露
JWT保證的是數據傳輸過程中的完整性而不是機密性。由于payload是使用
base64url編碼的,所以相當于明文傳輸,如果在payload中攜帶了敏感信息(如存放密鑰對的文件路徑),單獨對payload部分進行base64url解碼,就可以讀取到payload中攜帶的信息。回答所涉及的環境:聯想天逸510S、Windows 10。