身份认证中的JWT

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种简洁的、自包含的方法用于通信双方之间以 JSON 对象的形式安全地传输信息。这种信息可以被验证和信任,因为它是数字签名的。JWT通常用于互联网应用程序中,用于身份验证和授权。
JWT编码解码

空加密

JWT支持使用空加密算法,可以在header中指定alg为None。这样的话,只要把signature设置为空(即不添加signature字段),提交到服务器,任何token都可以通过服务器的验证。

爆破签名密钥

前提条件:

  • 知悉JWT使用的加密算法
  • 一段有效的、已签名的token
  • 签名用的密钥不复杂(弱密钥)

KID攻击

kid是JWT header中的一个可选参数,用于指定加密算法的密钥,因为该参数可以由用户输入,所以可能造成一些安全问题。

任意文件读取

kid参数用于读取密钥文件,但系统并不会知道用户想要读取的到底是不是密钥文件,所以,如果在没有对参数进行过滤的前提下,攻击者是可以读取到系统的任意文件的。

1
2
3
4
5
{ 
"alg" : "HS256",
"typ" : "jwt",
"kid" : "/etc/passwd"
}

SQL注入

kid也可以从数据库中提取数据,这时候就有可能造成SQL注入攻击,通过构造SQL语句来获取数据或者是绕过signature的验证。

1
2
3
4
5
{
"alg" : "HS256",
"typ" : "jwt",
"kid" : "key11111111' || union select 'secretkey' -- "
}

命令注入

对kid参数过滤不严也可能会出现命令注入问题,但是利用条件比较苛刻。如果服务器后端使用的是Ruby,在读取密钥文件时使用了open函数,通过构造参数就可能造成命令注入。
"/path/to/key_file|whoami"

Java项目中的JAR包

JAR包使用 IDEA 进行反编译。

Java项目中的组件

第一步:看项目中有哪些第三方组件(判断有没有安全风险)。
第二步:看代码中哪些地方用到了这些组件组件(判断在哪里利用)。

水平越权

修改数据包查看其他用户的信息。