HTML转义概要
位置 | 说明 | 转义概要 |
---|---|---|
元素内容(普通文本) | 能解释Tag和字符实体。结束边界字符为“<” | “<”和“&”使用字符实体转义 |
属性值 | 能解释字符实体。结束边界字符为双引号 | 属性值用双括号括起来,“<”和“&”和“‘”使用字符实体转义 |
属性值(URL) | 同上 | 检验URL格式正确后按照属性值的规则转义 |
事件绑定函数 | 同上 | 转义JavaScript后按照属性值的规则转义 |
script元素中的字符串字面量 | 不能解释Tag和字符实体。结束边界字符为“</” | 转义JavaScript并避免出现“</” |
href属性与src属性的XSS
有些属性的值为URL,比如href,img,frame,iframe元素的src属性。如果属性中URL的值由外界传入,外界就能使用javascript:JavaScript代码形式(javascript)或者VBScript。
类似于xxx.php?url=javascript:alert(document.cookkie)
生成的HTML如下:
<body>
<a href="javascript:alert(alert(document.cookie)">书签</a>
</body>
javascript协议引发的XSS,根源不是没有进行HTML转义,因此防范对策也不相同。
生成URL时的对策
当URL由程序动态生成时,需要对其进行校验,仅允许http和https协议。此外,通过校验的URL还需要作为属性值进行HTML转义。
以http:或https:开头的绝对URL或以/开头的相对URL。
校验链接网址
1.检查链接的目标URL,如果指向外部网站就报错
2当链接目标为外部URL时,显示一个警告页面以提醒用户可能存在风险
JavaScript的动态生成
动态生成JavaScript中的字符串字面量。
例如body的onload事件中调用函数时的参数就是由服务器端动态生成的
<body οnlοad="init('<?php echo htmlspecialchars($_GET['name'],ENT_QUOTES)?>')">
</body>
这里用htmlspecialchars函数进行了转义,但是这段PHP还是存在XSS漏洞,查询文字如下:
name=‘);alert(document.cookie)//
启动后生成如下HTML
<body οnlοad="init('');alert(document.cookie)//')">
由于onload事件绑定函数本质上是HTML中的属性值,能解释字符实体,因此,如下Javascript代码就会被执行。
init(' ');alert(document.cookie)//')
措施
1.首先,将数据作为JavaScript字符串字面量进行转义
2.将得到的结果再次进行HTML转义
字符 | 转义后 |
---|---|
\ | \\ |
' | \' |
" | \" |
换行 | \n |
例如
原字符:<>'"\
JavaScript转义后:<>\'\"\\
HTML转义后:<>\'\"\\
Script元素的XSS
当script元素内JavaScript的一部分是动态生成时的XSS漏洞。script不能解释Tag和字符实体,所以无需进行HTML转义,只要进行JavaScript转义。但是
当输入值包含</script>时,</script>就会被当成JavaScript代码的结束符。
这时,攻击者就可以恶意利用这一特性,并输入以下值实施XSS攻击。
</script><script>alert(document.cookie)//
根据HTML的规格,script元素中的数据不能出现</。而字符实体因不能被解释,也不能使用。所以,必须通过变更生成的JavaScript代码来避免这些问题。
JavaScript字符串字面量动态生成的对策
Unicode转义
将字母和数字以外所有字符都进行转义。这种方法利用了JavaScript能将Unicode代码点U+XXXX字符转义为\uXXXX的功能。
DOM based XSS
含有DOM based XSS漏洞的简单的HTML
<body
你好
<script type="text/javascript">
document.URL.match(/name=([^&*)/); //取出查询字符串中name的值
document,write(unescape(RegExp.$1)); //将取出的值显示在页面上
</script>
</body>
使用xxx?name=<script>alert(document.cookie)</script>
攻击者注入的JavaScript代码不会出现于服务器端生成的HTML中,一次这类XSS被称为DOM BASED XSS。
对策
使用jQuery的JavaScript库来示范字符串的显示。使用span元素确定字符串的显示位置,然后向id指定的DOM中插入文本文字。这时使用text方法自动进行转义操作。
<body>
<script src="jquery-1.4.4.min.js"></script> //加载jQuery
你好<span id="name"></span>
<script type="text/javascript">
if (document.URL.match(/name\=([^&]*/)){
var name = unescape(RegExp.$1);
$('#name').text(name); //显示文本
}
</script>
</body>