关于 XSS 防范的一些思考
- - keakon的涂鸦馆最近在看一些 web 安全相关的文章,大部分都有系统和完善的解决方案,然而 XSS(Cross-site scripting)攻击相关的资料却很杂乱,甚至连 HTML 实体转义能解决哪些地方的 XSS 攻击都说不清. 于是在翻了一堆资料后,觉得还是把自己对它的一些思考记录下来吧. 先要说明的是,不同的地方,有不同的方式避免 XSS:.
<div>{user_input}</div>
如果 user_data 里包含了 HTML 标签,那么展示的外观(可以加个 img 标签)和逻辑(可以加个 script 标签)都可能被篡改。所以这里至少要把 <
字符转义成 <
,也就不会开启和关闭任何标签了。 >
字符并不会关闭标签,所以它可以不处理。但是输出成 XML(如 RSS)或 XHTML 格式时,单独的 >
会造成页面解析失败,所以这种情况下需要转义。 &
的时候,是希望它显示成 &
的,而结果却显示成了 &
,这也是不符合预期的。所以 &
字符也应该被转义成 &
。 white-space: pre-wrap
的样式来处理,也可以替换成
和 <br>
,或者直接不管。 <
和 &
字符: def escape_html_text(string):
return string.replace('&', '&').replace('<', '<')
function escape_html_text(string) {
return string.replace('&', '&').replace('<', '<');
}
<input value="{user_input}">
这里自然也不能允许用户输入 <
和 &
字符。 >
的话,就可以轻松地关闭 input 标签了,所以 >
需要被转义成 >
。 "
和 '
需要被转义成 "
和 '
( '
是 XML 里的 entity,在 HTML 里没有定义,所以更推荐用前者)。 `
字符作为属性的分割符: <input value=`{user_input}`>
所以有需要的话,也可以转义 ` 字符。但如果你能保证你的的代码里只使用 "
和 '
作为属性分割符,那就可以不处理。 <input value={user_input}>
如果非要这么做的话, OWASP 建议将属性值中所有的 ASCII 字符都编码成 &#xHH;
的形式。 import re
escape_pattern = re.compile(r'[&<>"\']')
escape_map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}
def replacer(match):
return escape_map[match.group(0)]
def escape_html_attr(string):
return escape_pattern.sub(replacer, string)
var escape_map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
function replacer(char) {
return escape_map[char];
}
function escape_html_attr(string) {
return string.replace(/[&<>"']/g, replacer);
}
其实,Python 也可以直接用 cgi.escape 函数,至少我懒得写这些代码。 <img src="{user_input}">
<a href="{user_input}">{user_input}</a>
<button onclick="{user_input}">
<link ref="{user_input}" href="{user_input}">
<script src="{user_input}">
它们的处理规则其实并不一样: javascript:alert(0)
之类的代码。 <a href="/path?key={user_input}">...</a>
需要对参数进行百分号编码( percent-encoding),JavaScript 有内置的 encodeURIComponent
函数(会忽略字母、数字和 - _ . ! ~ * ' ( )
这些字符),Python 可以用 urllib.quote(url, '-_.!~*()')
(我觉得 '
字符还是比较危险的,不应该忽略)。 <script>
var value = {user_input};
var value = "{user_input}";
</script>
第一种情况应该不允许用户输入。 \xHH
的形式。 <style>
{user_input}
body {background-url: "{user_input}"}
</style>
都不应该允许用户输入。某些允许用户自定义样式的网站,如果会对别人有效,应该提供模板和可选的值,因为这里面能 XSS 攻击的地方太多了。 document.createElement
方法,然后手动设置各个属性和子元素,自然会安全很多;但拼成字符串,然后直接传给 jQuery()
或 innerHTML
无疑会方便很多,可是风险也就随之突显出来了。 帮我写一个能提取pentesterlab xss漏洞分析
- - JavaScript - Web前端 - ITeye博客pentesterlab简介. pentesterlab官方定义自己是一个简单又十分有效学习渗透测试的演练平台. pentesterlab环境搭建. 官方提供了一个基于debian6的镜像,官网下载镜像,使用vmware建立一个虚拟机,启动即可. ps:官方文档建议做一个host绑定,方便后面使用.