从0到1完全掌握Broken Authentication
Drunkbaby Lv6

从0到1完全掌握Broken-Authentication

从0到1完全掌握 身份认证漏洞 Broken-Authentication

0x01 前言

  • 整理一下关于身份认证所有的漏洞合集,说实话,实在是太多太杂了,很多业务逻辑漏洞也算是身份验证的漏洞,太多太杂了。
  • 写这一篇文章为了大家更好的学习,少踩坑,还请师傅们多多指点

0x03 2FA 的身份验证方式

0x04 JWT Tokens的身份验证

  • JWT: 全称 Json Web Tokens

传统的 Cookie 验证,也就是 Session Cookie 的验证。

1、用户向服务器发送用户名和密码。
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入用户的 Cookie。
4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

2. JWT 验证作用

  • 一句话阐明 JWT 的验证作用

实现同一家公司的关联服务,也就是用户在 A 网站登录,而当用户访问同公司旗下的 B 网站能够自动登录

3. 浅谈 JWT 原理

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

1
2
3
4
5
{
"姓名": "张三",
"角色": "管理员",
"到期时间": "2018年7月1日0点0分"
}

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(详见后文)。

服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

JWT 由三部分组成,Header,Payload,Signature

Header 部分

Header 部分同样也是一个 json 文件,它由两部分组成

  • typ 部分声明 token 类型,在 JWT 中默认为 JWT
  • alg 部分声明表示签字的算法,默认是 HMAC SHA256(写成 HS256)
    1
    2
    3
    4
    {
    'typ': 'JWT',
    'alg': 'HS256'
    }

接着对这一个 json 对象进行 base64 编码

1
{"typ":"JWT","alg":"HS256"}

得到的编码就构成了 Header 部分

Payload 部分

  • Payload 用来存放有效信息,这个名字像是特指飞机上承载的货品。
  • JWT 官方规定了 7 个原始字段
  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

1
2
3
4
5
6

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

同样,进行 base64 编码,得到第二段 payload

Signature 部分

Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

1
2
3
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将上述三部分组合起来,就是一个完整的 JWT

例如这一段,中间用 “.” 来分割三个模块

1
eyJhbGciOiJIUzI1NiJ9.ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1VTRVIiIF0sDQogICJjbGllbnRfaWQiIDogIm15LWNsaWVudC13aXRoLXNlY3JldCIsDQogICJleHAiIDogMTYwNzA5OTYwOCwNCiAgImp0aSIgOiAiOWJjOTJhNDQtMGIxYS00YzVlLWJlNzAtZGE1MjA3NWI5YTg0IiwNCiAgInNjb3BlIiA6IFsgInJlYWQiLCAid3JpdGUiIF0sDQogICJ1c2VyX25hbWUiIDogInVzZXIiDQp9.9lYaULTuoIDJ86-zKDSntJQyHPpJ2mZAbnWRfel99iI

JWT Secret

  • JWT 的生成:
    1
    2
    3
    4
    5
    HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
    )

因为有这个密钥的存在,所以即便调用方偷偷的修改了前两部分的内容,在验证环节就会出现签名不一致的情况,所以保证了安全性。

4. JWT 的应用

一般是在请求头里加入Authorization,并加上Bearer标注:

1
2
3
4
5
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})

JWT 获取 token 的原理如图所示

 评论