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。