6. XSS防护方法
XSS防护方法主要包括特殊字符转义和HTTPOnly。HTTPOnly上面已经介绍过,这里来介绍一下特殊字符转义。
1)编码内容:HTML内容
l 转义清单
Ø &->&。
Ø <->%lt>。
Ø >->%gt。
Ø "->"。
Ø '->'。
l 例子与说明
Ø <span>需要编码的数据</span>。
Ø <div>需要编码的数据</div>:使用特定的HTML解析器处理库。
2)编码内容:HTML属性
l 转义清单
Ø 不安全属性,比如:name、value。
Ø 对&、< 、 > 、 " 、'->&#HH。
l 例子与说明
Ø <input type="text" name="name" value="需要编码的数据">:仅用于安全属性,不安全属性进行HTML属性编码。
Ø 对于src、href属性,比如<iframesrc="需要编码的数据"/>,需要通过基于白名单验证URL。只能允许HTTP头、HTTPS头,避免JavaScript头。
3)编码内容:JavaScript
l 转义清单
Ø JavaScript代码进行JavaScript编码。
Ø 特殊字符转换为\xHH形式。
Ø 不要使用\形式编码,容易受到双重转移攻击\\。
Ø 将变量放在引号内,不以被执行。比如如下代码。
var x = $var
var y = "$var"
x=1;alert(2); //alert可执行
y="x=1;alert(2);" //alert不可以执行,比较安全
l 例子与说明
Ø <script>var xx="需要编码的数据";</script>:JavaScript编码。
4)编码内容:CSS
l 转义清单
Ø 将不可信任的数据放在安全属性中,进行CSS编码(不安全属性,不如URL、behavior)。
Ø 将不可信任的数据放在JavaScript表达式属性中。
Ø URL不以javasvript开头。
Ø 其他属性不以expression开头。
l 例子与说明
Ø <div style="width:需要编码的数据">Selection</div>。仅用于安全属性;不安全属性需要CSS样式编码。
5)编码内容:URL参数
l 转义清单
Ø <a href= "http://www.somesite.com?test=URL编码数据"></a>。
Ø URL编码:数字、字母、特殊字符编码成%HH格式。
l 例子与说明
Ø <a href="/site/sraech?value=需要编码的数据">URL编码。
6)编码内容:自定义HTML标签
l 转义清单
Ø .NET:HTMLSanitizer
Ø JAVA库:OWSAP Java HTMLSanitizer; Ø Ruby库:Ruby onRails SanitizeHelper
Ø PHP库:PHP HTMLPurifier
Ø JavaScript库:JavaScript/Node.js Bleach
Ø Python库:PythonBleach
12为安全的HTML属性。
12 安全的HTML属性
ESAPI (OWASP企业安全应用程序接口)是一个免费、开源的、网页应用程序安全控件库,它使程序员能够更容易写出更低风险的程序。ESAPI接口库被设计来使程序员能够更容易的在现有的程序中引入安全因素。ESAPI库也可以成为作为新程序开发的基础。ESAPI主要支持JAVA语言。其使用方法可以参照网上介绍。
4展示的是ESAPI中哪些特殊符号在何种情况下需要转义;5表示ESAPI中特殊符号转义成什么字符。
4 OWASP ESAPI中哪些特殊符号在何种情况下需要转义
编码类型 | & | < | > | " | ' | / | \ | = | ` | ( | ) | \t | \n | \f | \r | \b | 空格 | 下一行 | 行隔 | 段隔 | \u00000~\u001f |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
文本内容及属性 | b | b | b | b | b | ||||||||||||||||
文本内容 | b | b | b | ||||||||||||||||||
文本属性 | b | b | b | b | |||||||||||||||||
未加引号的属性 | b | b | b | b | b | b | b | b | b | b | b | b | b | b | b | ||||||
CSS字符串 | b | b | b | b | b | b | b | ||||||||||||||
CSS URL | b | b | |||||||||||||||||||
URL一个组件 | b | b | b | b | b | b | b | b | b | ||||||||||||
JavaScript字符串 | b | b | b | b | b | b | b | b | b | b | b | b |
5 OWASP ESAPI中特殊符号转义成什么字符
符号 | 转换 | 符号 | 转换 |
---|---|---|---|
& | & \26(用于CSS、JavaScript或URL) | ) | \29(用于CSS或URL) |
< | < \3c(用于CSS或URL) | 下一行:\u0085 | … |
> | > \3e(用于CSS或URL) | 行分隔符:\u2028 | 
 |
" | " \22(用于CSS、JavaScript或URL) | 换行符:\u000A | 
 \n(用于JavaScript) |
' | ' \27(用于CSS、JavaScript或URL) | 换页符: \u000C |  \f(用于JavaScript) |
/ | / \2f(用于CSS或URL)\/(用于CSS、JavaScript) | 回车符:\u000D | 
 \r(用于JavaScript) |
\ | \5c(用于CSS或URL)\\(用于JavaScript) | 退格符:\u000A | \b(用于JavaScript) |
= | = | 空格符:\u0020 |   |
` | ` | 段落分隔符:\u2029 | 
 |
( | \28(用于CSS或URL) | \u00000~\u001f | \X##(用于JavaScript) |
下面对常用的OWASP ESAPI进行一一讲解。(注OWASP ESAPI除了JAVA版本,还有ASP.NET、PHP、Python、JavaScript等多个版本,这里介绍的是JAVA版本)。
函数:String forHtml(String input)。
说明:对文本内容及文本属性编码。
例子:
<div><%=Encode.forHtml(UserData)%></div>
函数:String forHtmlContent(Stringinput)。
说明:对文本内容编码。
例子:
<div><%=Encode.forHtmlContent(UserData)%></div>
函数:String forHtmlAttribute(Stringinput)。
说明:对文本属性编码。
例子:
<input type="text"name="name" value="Encode.forHtmlAttribute(UserData)">
函数:StringforHtmlUnquoteAttribute(String input)。
说明:未加引号的属性进行编码。
例子:
<input type="text"name="name" value="Encode.forHtmlUnquoteAttribute(UserData)">
函数:String forCssString(String input)。
说明:编码CSS字符串,字符串必选在引号内。
例子:
<div style="width:Encode.forCssString(UserData)">Selection</div>
函数:String forCssUrl(String input)。
说明:编码CSS URL,必须在url()内。
例子:
<divstyle="background:url(<%=Encode.forCssUrl(…)%>)">
<styletype="text/css">
background:url(<%=Encode.forCssUrl(…)%>)
</style>
函数:String forUrlComponent(Stringinput)。
说明:对URL一个组件进行编码。
例子:
<ahref="http://www.mydoman.com/<%=Encode.forUrlComponent(…)%>?query#fragment">
函数:String forJavaScript(Stringinput)。
说明:编码JavaScript字符串。
例子:
<buttononclick="alert('<%=Encode.forJavaScript(data)%>');">
<script>
var data ="<%=Encode.forJavaScript(data)%>";
</script>
函数:StringforJavaScriptAtribute(String input)。
说明:编码JavaScript属性。
例子:
<buttononclick="alert('Encode.forJavaScriptAtribute(data)%>');">
函数:String forJavaScriptBlock(Stringinput)。
说明:编码JavaScript实体属性。
例子:
<script>
var data = "<%=Encode.forJavaScriptBlock(data)%>";
</script>
除了OWASP ESAPI,还有一些企业提供了防止XSS注入的API,它们是。
l OWASP JAVA HTML Sanitizer,包括。
Ø Sanitizer.FORMATTING.sanitize(html)。
Ø Sanitizer.BLOCKS.sanitize(block)。
Ø Sanitizer.STYLES.sanitize(attribute)。
Ø Sanitizer.LINKS.sanitize(link)。
Ø Sanitizer.TABLES.sanitize(html)。
Ø Sanitizer.IMAGES.sanitize(img)。
l AnjularJS SCE:这是Google开发并维护的一套JavaScript框架,包括。
Ø getTrustedHtml(value)。
Ø getTrustedCss(value)。
Ø getTrustedUrl(value)。
Ø getTrustedResourceUrl(value)。
Ø getTrustedJs(vaule)。
Ø trustAsHtml(value)。
Ø trustAsCss(value)。
Ø trustAsUrl(value)。
Ø trustAsResourceUrl(value)。
Ø trustAsJs(value)。
l ESAPI4JS:这是OWASP ESAPI的JavaScript版本,包括。
Ø encodeForHTML()。
Ø encodeForURL()。
Ø encodeForCSS()。
Ø encodeForHTMLAttribute()。
Ø encodeForJavaScript()。
Ø normal():过滤无法识别数据 比如:ぢ。
Ø cananicalize(): 还原 &<->&<。
l JQuery Encode:类似于ESAPI4JS,包括。
Ø encodeForHTML();。
Ø encodeForHTMLAttribute()。
Ø encodeForCSS()。
Ø encodeForJavaScript()。
Ø encodeForURL()。
除了使用特殊字符转义和HTTPOnly以外,还可以考虑在HTTP包里包含以下表头信息。
l 使用安全策略(CSP):CSP是Content-Security-Policy的缩写。
l X-XSS-Protection响应头。X-XSS-Protection响应头包括以下四种模式。
Ø 0:禁用XSS过滤器。
Ø 1:启用XSS过滤器(默认)。
Ø 1; mode = block:如果找到XSS,则不要渲染文档。
Ø 1; report = URL:如果找到XSS,对页面修改并且报告URL。
在这里建议使用X-XSS-Protection:1; mode=block模式
总结一下,防止CSS注入可以采取以下四种方式。
l 输入检查并转义。
l 使用ESAPI等规范。
l 输出检查并转义。
l 使用安全的表头。
一般而言在服务器端进行如下处理。
l 输出编码,工具OWASP Java Encode。
l HTML过滤,工具OWASP Java HTML Sanitizer。
l Cookie设置HTTPOnly。
l 启用CSP策略。
l 添加X-XSS-Protection响应头。
而在客户端采取下面的处理。
l 输出编码,工具ESAPI4J或jQuery Encoder。
l 自动上下文转义,工具AngularJS。
l JavaScript安全编码。
对于存储式XSS注入应该输出检查并转义还是输入检查并转义比较好?作者认为应该是输出检查并转义,这样可以确保存储在数据库、文件或其他容器中的数据可以被不同的前端应用。