关于 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绑定,方便后面使用.