前言
前段时间在网上看到一个网址,好奇之下进去看了看。胜利的条件是你录入一个串,让其调用prompt(1) 。发现里面有好多想不到的东西,今天终于悠闲了来这里说说XSS。
XSS 原理
跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
XSS 常见场景
一些私人的博客,攻击者恶意评论,弹出alert,这种充其量也就是一个玩笑。但是如果是盗窃cookie,异常提交请求,这些就比较难受了。
prompt(1)
chrome 版本 62.0.3202.75(正式版本) (64 位)
function escape(input) { // warm up // script should be executed without user interaction return '<input type="text" value="' + input + '">'; }
第一个
这是一个开胃菜,没有做任何校验,这种不设防的在现在已经很少了。他把值直接拼入字符串,组成一个DOM input标签,那我们只要正确的把标签闭合掉就可以调用了。
"><script>prompt(1)</script>
,拼出来的字符串为<input type="text" value=""><script>prompt(1)</script>">
,这样就等于插入了我们的代码。
function escape(input) { // tags stripping mechanism from ExtJS library // Ext.util.Format.stripTags var stripTagsRE = /<\/?[^>]+>/gi; input = input.replace(stripTagsRE, ''); return '<article>' + input + '</article>'; }
第二个
这个已经提升难度了,/<\/?[^>]+>/gi匹配<>标签内的所有东西,如输入<script>prompt(1)</script>
转换过后会出现prompt(1),内容里面的标签被替换掉了。所以这个我们去尝试不闭合标签,让浏览器自己去容错。
<img src onerror="prompt(1);"
该方法通过img加载src失败会调用onerror的想法。
function escape(input) { // v-- frowny face input = input.replace(/[=(]/g, ''); // ok seriously, disallows equal signs and open parenthesis return input; }
第三个
这个就有点略坑了/[=(]/g把所以的=号和(号都替换掉了,这样我们尝试调用的时候就不能使用这些东西了。使用的方法是通过模板字符串的标签模板,这个ES6的特性。