安全编码规范基于OWASP Top 10(2010) ------The Ten Most Critical Web Application Security Risks 整理,它们列出如下:
A1.注入(Injection)
A2.跨站脚本(Cross-Site Scripting(XSS))
A3.失效的身份认证和会话管理(Broken Authentication and Session Management)
A4.不安全的直接对象引用(Insecure Direct Object References)
A5.跨站请求伪造(Cross-Site Request Forgery(CSRF))
A6.安全配置错误 (Security Misconfiguration)
A7.不安全的加密存储(Insecure Cryptographic Storage)
A8.URL访问限制缺失(Failure to Restrict URL Access)
A9.没有足够的传输层防护(Insufficient Transport Layer Protection)
A10.未验证的重定向和转发(Unvalidated Redirects and Forwards)
下面分别针对Top 10各专题进行讨论:
注入攻击
注入攻击主要是SQL注入,这个我们已经了解的比较多了,暂不整理。
XSS攻击
是指恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
有以下开发规范:
- 不要从不可信任的源接收javascript脚本,或执行不可信数据。
- 对不可信数据进行JavaScript Encode后再传给应用或与可信数据拼接。
- 使用document.createElement("..."), element.setAttribute("...","value"), element.appendChild(...)来操作DOM,避免使用HTML渲染方法,如:
element.innerHTML = "...";
element.outerHTML = "...";
document.write(...);
document.writeln(...); - 不要使用eval()方法把JSON串转换为Javascript原生对象,而是使用:JSON.toJSON()和JSON.parse()。
- 对用户的输入进行转义处理(需要转义的字符列表待提供)。
- 在Java程序中,如果Runtime.exec执行的命令依赖用户输入参数,则要进行严格的检查。尽量采用别的方式实现此需求。
- 避免使用外部输入去生成反射字符串,尽量使用其它方式实现需求功能,如果采用了,则做好输入的验证。
- 日志信息依赖用户输入时,在记录日志时,要检查字符串中是否包含一些特殊字符,如:'\n'。
- 不可靠来源的数据输出到以下位置时,要做转义处理。
1) 页面元素内容;
如:
<div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
2) HTML通用属性的值;
3) HTML内javascript数值;
4) HTML样式属性值;
5) URL参数;
例如对一些特殊字符做如下转义:
& 转义为 &
< 转换为 <
> 转换为 > >
" 转换为 > "
' 转换为 ' 不建议转为'
/ 转换为 /
可以使用ESAPI进行转义处理:
String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) ); - 尽量使用开源社区现成的检验工具对输入参数进行校验,而不是自己重新写一个。如Apache Commons Validator或OWASP ESAPI Validators
XSS相关资料:
http://elegantcode.com/2009/05/28/cross-site-scripting-xss/
http://amix.dk/blog/post/19432
http://stackoverflow.com/questions/6025418/dom-based-xss-attack-and-innerhtml
这里是XSS攻击的示例:http://ha.ckers.org/xss.html
失效的身份认证和会话管理
- Session信息要设置超时时间,原则上不要超过一小时;
- 防止放入Session的值覆盖已存在的变量;
- 不允许在Session中存放大对象,否则容易造成系统堆空间溢出;
- 除了登录注销,不允许在代码中修改Session中的用户识别信息,如user_id、user_email等,以及用户操作相关的的内容(可防止用户原始ID被覆盖,避免造成用户信息混乱)。
- 对COOKIE 使用Secure标签
相关资料:
http://shiflett.org/articles/the-truth-about-sessions
http://shiflett.org/articles/session-hijacking
http://shiflett.org/articles/session-fixation
相关的:
Session管理:https://216.48.3.18/index.php/Session_Management
Httponly:http://216.48.3.18/index.php/HTTPOnly
和:http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html
不安全的直接对象引用
尽量防止用户输入信息对对象的直接引用;
例如,一个下拉列表包含6个授权给当前用户的资源,它可以使用数字1‐6来指示哪个是用户选择的值,而不是使用资源的数据库关键字来表示。在服务器端,应用程序需要将每个用户的间接引用映射到实际的数据库关键字。
跨站请求伪造
要防止跨站请求伪造,需要在每个HTTP请求的body或URL中添加一个随机的令牌。这种令牌至少应该对每个用户会话来说是唯一的,或者也可以对每个请求是唯一的。最好的方法是将独有的令牌包含在一个隐藏字段中,通过HTTPs用POST方式发送,避免其被包含在URL中从而被暴露出来。