Web安全开发指南--数据验证
1、数据验证
4.1、输入数据验证安全规则
1 | 数据验证必须放在服务器端进行。 |
2 | 至少对输入数据的数据类型、数据范围和数据长度进行验证。 |
3 | 所有来自不可信数据源(比如网络、用户命令、数据库和文件系统等)的数据都要进行有效验证(参考11.7 ESAPI方案)。 |
4 | 来自客户端的所有参数的数据都要进行验证,比如HTTP header的键值对。 |
5 | 数据验证不通过时应默认拒绝处理该请求。 |
6 | 应尽可能地使用“白名单”而非“黑名单”的方式对数据进行验证。 |
4.2、输出数据编码安全规则
数据编码必须放在服务器端进行。 |
系统应依据上下文环境对自非信任域的数据进行输出编码后再返回给客户端,html编码就是一个很好的例子,但不适用于所有上下文环境,详情请参考【反射型、存储型XSS安全规则】。 |
4.3、反射型、存储型XSS安全规则
将用户数据输出到html body某处时,必须经过html转义,比如: <body>...【用户数据】...</body> <div>...【用户数据】...</div> 以及其它普通的html标签,比如p, b, td等等。 ESAPI sample: String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) ); |
将用户数据输出到html 标签的属性时,必须经过标签属性的转义。 注意:不包含href, src, style和事件处理函数属性(比如onmouseover)。 <div attr=...【用户数据】...>content</div> //数据不在引号内 <div attr='... 【用户数据】...'>content</div> //数据在单引号内 <div attr="...【用户数据】...">content</div> //数据在双引号内 ESAPI sample: String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) ); |
将用户数据输出到JavaScript数据域时,必须经过JavaScript转义。 注意:用户数据必须在引号内,否则转义后数据仍然是不安全的。 <script>alert('... 【用户数据】...')</script> //数据在带引号的字符串内 <script>x='... 【用户数据】...'</script> //数据在带引号的表达式内 <div onmouseover="x='... 【用户数据】...'"</div> ESAPI sample: String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) ); |
将用户数据输出到URL的参数时,必须经过URL转义。 <a href="http://www.somesite.com/x/y/z?test=...【用户数据】...">link</a > ESAPI sample: String safe = ESAPI.encoder().encodeForURL( request.getParameter( "input" ) ); 注意:所有基于URL的标签属性(比如href,src等),如果其整个或相对的URL被用户数据控制,比如: <a href=” ...【用户数据】...”>link</a> 则应先验证URL的有效性,再进行html标签属性的转义【参考附录11.5 ESAPI方案】。 |
除了以上4条规则定义的安全上下文以外,其它上下文都是无法安全地转义的,应避免出现,比如: <script>...【用户数据】...</script> //直接输出到js标签内 <!--...【用户数据】...--> //直接输出到注释内 <div ... 【用户数据】...=test /> //直接输出到标签属性名 <..【用户数据】... href="/test" /> //作为标签名使用 <style>...【用户数据】...</style> //直接输出到CSS …… |
4.4、DOM型XSS安全规则
简要描述 | 一种基于DOM的跨站,这是客户端脚本自身解析不正确导致的安全问题。 | |
解决方案 | 在输出到DOM前必须确定插入HTML的位置,根据上面的反射型、存储型XSS安全规则进行过滤。 | |
备注 | 纯DOM跨站,可以不用与服务器发生数据交互。 | |
4.5、Flash型XSS安全规则
简要描述 | 通过Flash执行javascript | |
解决方案 | 把Flash的参数”allowScriptAccess”置为”never”; 把Flash的参数”allowNetworking”置为”none”或”internal”; 使用navigateToURL(as3)或getURL(as2)时必须验证link 参数,不得含有伪协议(详见XSS安全规则) 如果Flash中有使用ExternalInterface.call,必须过滤该函数的所有参数(详见XSS安全规则) 如果Flash中有使用ExternalInterface.addCallback,必须过滤该函数的第一个参数(详见XSS安全规则) | |
备注 | 注意设置网站根目录下的crossdomain.xml | |
4.6、SQL注入
简要描述 | 当应用程序使用用户输入数据来构造动态sql语句以访问数据库时,就会发生sql注入攻击。 | |
解决方案 | 1、 使用参数化查询(预编译语句)【参考附录11.1.1】。 2、 安全地使用存储过程【参考附录11.1.2】。 3、 转义用户输入【不建议,参考11.1.3】。 | |
备注 | 请参考附录11.1的SQL注入防范代码样例 |
注:如果IE浏览器显示格式不正确,请使用chrome浏览器