大家好,欢迎来到IT知识分享网。
一、HttpOnly属性
为Cookie中的关键值设置httponly属性,众所周知,大部分XSS(跨站脚本攻击)的目的都是通过浏览器的同源策略,来获取用户Cookie,从而冒充用户登陆系统的。
如果为Cookie中用于用户认证的关键值设置httponly属性,浏览器将会禁止js通过同源策略访问cookie中设有httponly属性的信息,因此以劫持用户认证cookie为目的XSS攻击将会失败。
但很明显,只为cookie中的值设置Httponly是不够的,因为XSS攻击并不是只能获取用户COOKIE,它还可以窃取用户浏览器信息,模拟用户身份执行操作等等。(具体内容详见:《白帽子讲Web安全》)
二、对用户输入进行检查——XSS filter
XSS filter是在用户提交数据时获取变量,并进行XSS 过滤的。此时的XSS filter只对用户输入数据进行XSS检查,并没有结合渲染页面的HTML代码。
所以针对XSS filter需要强调两点:
1.XSS filter对语境的理解并不完整(比如:无法针对输出点位置进行合适的XSS过滤。所以有时可能会造成遗漏、破坏原有语义等后果)
2.XSS filter是在服务器进行URL解码之前生效的,所以要考虑URL编码绕过的问题。(比如XSS filter过滤了<script>标签,但如果用户输入的是经过URL编码后的<script>标签:%3C%73%63%72%69%70%74%3E,这样就饶过了原本的XSS filter检测)
三、对用户输出进行检查——安全的编码函数
(1)HtmlEncode
一般来说,在进行XSS防御的时候,至少需要将以下字符做转换处理:
转换前 转换后
& &
< <
> >
” "
‘ '
/ /
(2)JavascriptEncode
javascriptEncode的编码方式和HtmlEncode有所不同,它使用 \ 对特殊字符进行转义。
常用的JavaScript编码函数为:escapeJavascript()
该函数的功能为:将 ‘ ” < > \ & # 这些个危险字符进行转义。
举一个《白帽子讲Web安全》里的例子
var x=1;alert(2);
var y=”1;alert(2)”;
JS环境内,第一行的弹窗代码会被执行,第二行则会是安全的,即使攻击者想要尝试闭合”,输入的”也会被JavaScript编码转义为\”。这样攻击者相要绕过”的封锁也会十分苦难。
不过这里需要注意
1.如果页面使用的是GBK编码,可能会被攻击者利用类似宽字节注入的方式绕过。比如
2.用户的输出如果是在标签内,则要求JavascriptEncode的变量输出点一定要被引号包裹。
如果用户输出点太多,导致开发人员无法针对性的对用户输出进行编码、转义。则可以使用更严格的Javascriptencode函数,使用函数将除了数字、字母之外的所有字符通通都以”\xHH”的方式进行16进制编码。
接下来需要介绍一个很重要的东西,是我当天总结的重中之重!!!!!!
相信很多初学者会和我一样,非常好奇为什么会有Htmlencode和JavaScriptEncode两种编码方式,从功能上来看都可以抵御XSS攻击,但为什么要将两者分开使用。这是因为浏览器有两套不同的自解码机制。
1、HTML的自解码机制
浏览器在解析HTML标签属性值内的代码前,会先对下列两种编码进行解码,然后再对属性中的代码进行解析。
(1)、进制解码:&#xH;(十六进制格式)、&#D;(十进制格式)。编码中最后的分号(;)可以不要。且16进制中用来表示10~15的a~f对大小写不敏感
例子:
<iframe src=’javascript:alert`1`’></iframe>
也可写成
<iframe src=’javascript:alert`1`’></iframe>
(2)、HTML 实体编码
例子:
<input type=”button” value=”test” οnclick=”document.write(‘<img src=@ οnerrοr=alert(123) />’)” />
也可写成
<input type=”button” value=”test” οnclick=”document.write(‘<img src=@ οnerrοr=alert(123) />’)” />
2、JavaScript 自解码机制
(1)、Unicode 形式:\uH(十六进制)。
(2)、普通十六进制:\xH。
(3)、纯转义:\’、\”、\<、\>这样在特殊字符之前加\进行转义。
注:以上三种规则仅在通过JS更改HTML DOM树时才适用( 例如document.write() document.getelementbyid().innerhtml=””),直接在<script>标签内使用上述编码,自解码规则不生效。
例子:
<input type=”button” id=”exec_btn” value=”exec” />
<script>
function $(id){return document.getElementById(id);};
$(‘exec_btn’).onclick = function(){
document.write(‘<img src=@ οnerrοr=alert(123) />’);//改代码可执行、可弹窗
//在JS执行前会先将上面这行代码先解码为:document.write(‘<img src=@ οnerrοr=alert(123)/>’);
};
</script>
但如果直接在<script>标签内使用该编码,则自解码机制不生效。
例如:
<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0032\u0033\u0029</script>
其中上述\u编码内容为alert(123),但该代码并没有更新DOM树,所以不会弹窗。
四、针对不同的输出点使用合适的编码方式
1.输出点在HTML标签之间
如<div>输出点</div>
攻击者如果想要构造XSS语句并执行,需要构造一个能执行脚本的环境。示例如下:
<div><script>alert`1`</script></div>
此处适合使用HtmlEncode,将攻击者输入的<>编码为<>
使得攻击者无法构造JS环境,导致XSS失败。
2.输出点在HTML属性中输出
<div id=’111′ name=”输出点”></div>
普通攻击者尝试的方法为将name属性的双引号闭合,然后再构造xss语句。
<div id=’111′ name=” “><script>alert`1`</script><“”></div>
此处同样推荐使用HtmlEncode
3.输出点在<script>标签中
在<script>标签中输出时,首先应该确保输出的变量在引号中,例如
<script> var x=”输出点”</script>
此处的防御思想是:使攻击者无法闭合标签,导致无论输入什么参数都会被浏览器当作字符串处理。
此处应使用JavascriptEncode。
4.在事件中输出
在事件中输出和在<script>标签中类似
<a href=# οnclick=”funcA(‘输出点’)”>超链接</a>
攻击方法举例:
<a href=# οnclick=”funcA(”);alert`1`;//’)”>超链接</a>
5.在CSS中输出
因为对CSS不太熟悉,所以此部分暂不介绍。
但根据白帽子一书中的介绍,推荐使用 encodeForCSS()函数
6.在地址栏中输出
在地址栏中的输出比较复杂,但总结起来相较于前面有两点需要注意:
(1).输出点在路径或者参数中。
<a href=”http://www.test.com/test=输出点”>test</a>
攻击者可按照如下方式构造payload
<a href=”http://www.test.com/?test=” οnclick=alert(1) “”>test</a>
此处的防御方法为使用URLEncode,是代码变成下面这样
<a href=”http://www.test.com/?test=%22%20%6F%6E%63%6C%69%63%6B%3D%61%6C%65%72%74%28%31%29%20%22″>test</a>
(2).输出点为整个URL
<a href=”输出点”>test</a>
此时就不能单纯的使用URLEncode来抵御XSS攻击了,因为协议和域名部分是不能够进行URL编码的,不然会改变原有的语意。
此处攻击者可能会构造伪协议实施攻击
<a href=”javascript:alert(1);”>test</a>
能被攻击者利用的伪协议有:javascript,vbscript,dataURL
dataURL这个伪协议是Mozila所支持的,能够将一段代码写在URL里
<a href=”data:text/html;base64,PHNjcmlwdD5hbGVydGAxYDwvc2NyaXB0Pg==”>test</a>
这段base64字符串解码后就是<script>alert`1`</script>
所以此处的防御方法应为:
<script> <style> <a>等标签的src和href属性必须以白名单的方式强制为 http://或https://开头,并且不能有10进制和16进制编码的字符串。(此处的做法是防止攻击者使用伪协议进行XSS攻击)
7.DOM型XSS的防御
如果用户的输出点在<script>之间时,须先进行一次JavaScriptEncode,在通过document.write等方式输出到HTML页面时,如果输出点为事件或者脚本,须再进行一次JavaScriptEncode,如果输出点为HTML的内容或者属性,则需要做一次Htmlencode。
五、总结
输出到HTML标签内或者之间,需使用HtmlEncode编码进行防御。
输出到JavaScript标签内或者之间,需要进行JavaScriptencode来进行防御。
抵御DOM型XSS,当使用document.write等方法向HTML页面内输入内容时,如过输出点在JS环境内就要再进行一次JavascriptEncode,如果输出点在HTML标签内,则再进行一次HtmlEncode
以上内容大部分参考《白帽子讲Web安全》一书。
关于XSS进阶教程强烈推荐大家看我的另一篇博客,事我很认真,一点点总结出来的,但访问量很少。。。链接如下:
https://blog.csdn.net/sdb5858874/article/details/87913903
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/12884.html