攻击者如何伪造令牌并以其他人身份登录
JSON Web令牌是一种在商业应用程序中广泛使用的访问令牌。它们基于JSON格式,并包含令牌签名以确保令牌的完整性。
今天,我们将讨论使用JSON Web令牌(通常是基于签名的令牌)的安全隐患,以及攻击者如何利用它们绕过访问控制。
JSON Web令牌如何工作?
JSON Web令牌包含三个组件:标头,payload和签名。
标头
JSON Web令牌的标头部分标识用于生成签名的算法。它是JSON Blob的base64编码的字符串,如下所示:
{
"alg" : "HS256",
"typ" : "JWT"
}
base64 encoded string: eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K
最常用的算法是HMAC和RSA算法。
payload
payload部分包含实际用于访问控制的信息。此部分在用于令牌之前也已进行base64编码。
{
"user_name" : "admin",
}
base64 encoded string: eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg
签名
签名是用于验证令牌未被篡改的部分。它是通过将标头与payload串联在一起,然后使用标头中指定的算法进行签名来计算的。
signature = HMAC-SHA256(base64Encode(header) + '.' + base64Encode(payload), secret_key)
// Let's just say the value of secret_key is "key".
-> signature function returns 4Hb/6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M
对于此特定令牌,字符串“ eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg”已用密钥“ key”的HS256算法签名。生成的字符串是4Hb / 6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M。
完整的令牌
通过将每个部分(标头,有效负载和签名)与每个部分之间的“。”串联起来,可以获得完整的令牌。
eyBhbGcgOiBIUzI1NiwgdHlwIDogSldUIH0K.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg.4Hb / 6ibbViPOzq9SJflsNGPWSk6B8F6EqVrkNjpXh7M
绕过JSON Web令牌控件的方法
如果正确实现,JSON Web令牌将提供一种安全的方式来标识用户,因为payload部分中包含的数据无法被篡改。(由于用户无权访问密钥,因此她不能自己对令牌进行签名。)
但是,如果实施不正确,攻击者可以通过多种方式绕过安全机制并伪造任意令牌。
更改算法类型
攻击者可以伪造自己的令牌,其中一种方法是篡改标头的alg字段。如果应用程序不限制JWT中使用的算法类型,则攻击者可以指定要使用的算法,这可能会损害令牌的安全性。
- 无算法
JWT支持“无”算法。如果将alg字段设置为“ None”,则如果其标记部分设置为空,则任何令牌都将被视为有效。例如,以下令牌将被视为有效:
eyAiYWxnIiA6ICJOb25lIiwgInR5cCIgOiAiSldUIiB9Cg.eyB1c2VyX25hbWUgOiBhZG1pbiB9Cg。
它只是这两个Blob的base64编码版本,没有签名。
{
"alg" : "None",
"typ" : "JWT"
}
{
"user" : "admin"
}
此功能最初用于调试目的。但是,如果没有在生产环境中将其关闭,则攻击者可以通过将alg字段设置为“ None” 来伪造他们想要的任何令牌。然后,他们可以使用伪造的令牌模拟网站上的任何人。
2. HMAC算法
用于JWT的两种最常见的算法类型是HMAC和RSA。使用HMAC,将使用密钥对令牌进行签名,然后使用相同的密钥进行验证。对于RSA,将首先使用私钥创建令牌,然后使用相应的公钥进行验证。
HMAC -> signed with a key, verified with the same key
RSA -> signed with a private key, verified with the corresponding public key
至关重要的是,将HMAC令牌的私钥和RSA令牌的私钥保密,因为它们用于签名令牌。
现在,我们假设有一个最初设计为使用RSA令牌的应用程序。令牌用私钥A签名,私钥A对公众保密。然后,使用任何人都可以使用的公钥B验证令牌。只要令牌始终被视为RSA令牌,就可以。
Token signed with key A -> Token verified with key B (RSA scenario)
现在,如果攻击者改变的ALG到HMAC,她可能通过与RSA公钥B.签署伪造的令牌能够创建有效令牌
这是因为最初使用RSA对令牌进行签名时,程序会使用RSA公钥B对其进行验证。当将签名算法切换为HMAC时,仍使用RSA公钥B来验证令牌,但是这次是使用令牌可以使用相同的公钥B签名(因为它使用的是HMAC)。
Token signed with key B -> Token verified with key B (HMAC scenario)
提供无效的签名
令牌的签名在到达应用程序后也可能永远不会被验证。这样,攻击者可以通过提供无效签名来简单地绕过安全机制。
暴力破解密钥
也有可能暴力破解用于签署JWT的密钥。
攻击者从一开始就有很多信息:她知道用于对令牌进行签名的算法,已签名的有效负载以及生成的签名。如果用于对令牌进行签名的密钥不够复杂,则她可能可以轻松地对其进行暴力破解。
泄漏密钥
如果攻击者无法蛮力破解密钥,则可以尝试泄漏秘密密钥。如果存在另一个允许攻击者读取存储密钥值的文件的漏洞(如目录遍历,XXE,SSRF),则攻击者可以窃取密钥并签署任意令牌。
KID操作
KID代表“Key ID”。它是JWT中的可选标头字段,它使开发人员可以指定用于验证令牌的密钥。KID参数的正确用法如下所示:
{
"alg" : "HS256",
"typ" : "JWT",
"kid" : "1" // use key number 1 to verify the token
}
由于此字段是由用户控制的,因此攻击者可能会操纵它并导致危险的后果。
- 目录遍历
由于KID通常用于从文件系统中检索密钥文件,因此,如果在使用前未对其进行清理,则可能导致目录遍历攻击。在这种情况下,攻击者将能够在文件系统中指定任何文件作为用于验证令牌的密钥。
“kid”: “../../public/css/main.css”
// use the publicly available file main.css to verify the token
例如,攻击者可以迫使应用程序使用公开可用的文件作为密钥,并使用该文件对HMAC令牌进行签名。
2. SQL注入
KID还可以用于从数据库检索密钥。在这种情况下,可能可以利用SQL注入来绕过JWT签名。
如果可以在KID参数上进行SQL注入,则攻击者可以使用该注入返回她想要的任何值。
“kid”: "aaaaaaa' UNION SELECT 'key';--"
// use the string "key" to verify the token
例如,上面的注入将使应用程序返回字符串“ key”(因为数据库中不存在名为“ aaaaaaa”的键)。然后将使用字符串“ key”作为密钥来验证令牌。
标头参数处理
除密钥ID外,JSON Web令牌标准还使开发人员能够通过URL指定密钥。
- JKU标头参数
JKU代表“ JWK设置URL”。它是一个可选的标头字段,用于指定指向一组用于验证令牌的密钥的URL。如果允许该字段,并且没有适当地限制该字段,则攻击者可以托管自己的密钥文件,并指定应用程序使用它来验证令牌。
jku URL -> file containing JWK set -> JWK used to verify the token
2. JWK标头参数
可选的JWK(JSON Web密钥)标头参数允许攻击者将用于验证令牌的密钥直接嵌入令牌中。
3. X5U,X5C URL操作
类似于jku和jwk标头,x5u和x5c标头参数允许攻击者指定用于验证令牌的公钥证书或证书链。x5u以URI形式指定信息,而x5c允许将证书值嵌入令牌中。
其他JWT安全问题
如果未正确实施,还会产生其他JWT问题。这些不是很常见,但是绝对值得关注:
信息泄漏
由于JSON Web令牌用于访问控制,因此它们通常包含有关用户的信息。
如果令牌未加密,则任何人都可以通过base64解码令牌并读取令牌的有效负载。因此,如果令牌包含敏感信息,则它可能成为信息泄漏的来源。JSON Web令牌的正确实现的签名部分可提供数据完整性,而不是机密性。
命令注入
有时,当KID参数直接传递到不安全的文件读取操作中时,可能会将命令注入代码流中。
可能允许这种类型的攻击的函数之一是Ruby open()函数。此功能使攻击者只需在KID文件名之后将命令添加到输入即可,即可执行系统命令:
“key_file” | whoami;
这只是一个例子。从理论上讲,每当应用程序将未经消毒的任何头文件参数传递给任何类似于system(),exec()等的函数时,就会发生此类漏洞。
最终,JSON Web令牌只是用户输入的另一种形式。他们应始终持怀疑态度并严格审查。
免责声明:这篇文章旨在引起人们对JSON Web令牌漏洞的关注,并帮助开发人员识别常见的陷阱。请不要使用此信息来攻击网站或冒充他人。
在没有测试权限的系统上尝试此操作是非法的。如果您发现了漏洞,请以负责任的方式向供应商披露。帮助使我们的互联网更安全。
翻译自:https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a