Evaled JSON 注入

假设每当有人访问 Bob 网站中的个人资料页面时,都会获取以下网址:

https://example.com/api/users/1234/profiledata.json

有这样的回应:

{
    "name": "Bob",
    "description": "Likes pie & security holes."
}

比解析和插入数据:

var data = eval("(" + resp + ")");
document.getElementById("#name").innerText = data.name;
document.getElementById("#description").innerText = data.description;

好像很好吧?错误。

如果某人的描述是 Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. 怎么办?看起来很奇怪,但如果做得不好,响应将是:

{
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
}

这将是 evaled:

({
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
})

如果你认为这不是问题,请将其粘贴到控制台中,看看会发生什么。

Mitagation

  • 使用 JSON.parse 而不是 eval 来获取 JSON。一般情况下,不要使用 eval,并且绝对不要将 eval 与用户可以控制的东西一起使用。Eval 创建了一个新的执行上下文 ,从而创造了性能损失

  • 在将其放入 JSON 之前,正确地转义用户数据中的 "\。如果你只是转义了 ",那么这将会发生:

    Hello! \"});alert(1);({
    

    将转换为:

    "Hello! \\"});alert(1);({"
    

    哎呀。记得要转义\",或者只使用 JSON.parse。