0x00 总结一下xss相关的坑
- innerHTML写出的
<script>
tag 不会触发xss, 但是javascript scheme会被触发,下面这个例子里,只有alert(2)被触发了。<div id = "tag1"> </div> <div id = "tag2"> </div> <script> document.getElementById("tag1").innerHTML="<script>alert(1)<\/script>"</script> <script> document.getElementById("tag2").innerHTML="<iframe src='javascript:alert(2)'><\/iframe>"</script>
这个行为在HTML5中已经标准化https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations。
-
但是dom的write则可以触发script tag 的xss。 比如下面这个会被触发。
<script> document.write('<script>alert("xss")</\script>')</script>
- js对value的操作不会反映到浏览器的开发者工具上:
<input id="tag1" value="init value"> <script> document.getElementById("tag1").value="world"</script>
打开以上页面,发现页面上input框中显示的是“world”,但是打开开发者工具,发现input中的value属性仍然是“init value”。
有时你想在开发者工具中搜索你输入的数据却搜不到,则有可能是踩到了上述的坑。
-
form的action设置为"javascript:alert(1)"要在post时才会被触发。
-
location.href设置为"javascript:alert(1)"会被立马触发。
-
因为有CORS同源策略,浏览器不会把使用javascript发送的post,get等请求发送给不同的domain,但是如果你把浏览器连接上burp,你会发现burp仍能捕捉到浏览器发送的请求。仔细察看才发现,转发给burp的请求的method已经被改为了OPTIONS,这可能是浏览器的一个feature。(在firefox上进行的测试。)
-
用js取出attr里的html实体时会自动unescape,但是在innerHTML里的则不会。如果渲染之后再在attr(比如value)里输入html实体,则不会被unescape。
<head> <script src="vue.js"> </script> </head> <a id="app" href="#" value="<>>" @click.prevent="doSomething('>')">click</a> <input id ="app2" type="text" name="tekido" value=">"> <p id="app3">></p> <p id="app4" attr_test=">"></p> <script> new Vue({ el: '#app', methods: { doSomething: function (str) { console.log(str) console.log(document.getElementById('app2').value); console.log(document.getElementById('app3').innerHTML); console.log(document.getElementById('app4').getAttribute("attr_test")); } } }) </script>
上面的代码的输出为:
> > > >
-
iframe去的父frame的url问题:
iframe虽然不能使用window.parent.location的方式取得父frame的url,但是可以用document.referrer取得父frame的url。如果父frame的url里有敏感token不想让iframe取得,则可以使用url fragment (#)来传递参数。