你的Grails应用安全么?

一直以来,应用安全、数据安全总是令人揪心。纵然有许多的软件可以防止木马、病毒、黑客的侵害,但是更重要的是要提高应用程序自身的免疫力。本文借鉴Frank Kim以及Gautam Malhotra的博文,为读者介绍增强应用免疫力的方法。

为了提高Grails应用的安全性,首先就要检查你的web.xml配置,Frank Kim在其博文中,列出了7种常见的导致安全漏洞的错误方法(注,下述web.xml配置基于Servlet 3.0,同样适用于JavaEE应用。):

  1. 不自定义出错页面:通常,Web应用出错后,会将详细的错误信息(包括服务器版本、详细的堆栈跟踪信息,甚至于代码片断)显示在页面上,这些信息对于黑客来说简直就是无价之宝。所以最好自定义出错页面,屏蔽掉这些信息,而是给出更友好的人性化提示,提高用户体验。示例配置如下:
  2. 1<error-page>
    2  <error-code>500</error-code>
    3  <location>/path/to/error.jsp</location>
    4</error-page>

    其中,error-code是错误码,location是出现错误码代表的错误后,重定向页面的路径。如果不知道错误码,也可以用异常类型代替,比如:<exception-type>java.lang.Throwable</exception-type>。error.jsp中,最好不显示详细的错误信息,可以将这些信息输出到日志文件中。对于Grails应用,也可以通过UrlMappings来指定错误发生后的定向位置,例如:

    1class UrlMappings{
    2"404" (controller:"errors",action:"notFound")
    3"500" (controller:"errors",action:"internalError")
    4}
  3. 绕过用户验证和授权:

    <security-constraint>标签中的http-method属性用于指定哪种HTTP方法服从授权约束。通常,会指定为POST、GET方法,比如:

    1<security-constraint>
    2  ......
    3    <http-method>GET</http-method>
    4    <http-method>POST</http-method>
    5  ......
    6</security-constraint>

    上述配置的本意是只允许GET、POST的请求。但却让其他HTTP方法甚至是非法方法都畅通无阻。至于这种情况是如何发生的,具体可参见Arshan Dabirsiaghi的论文。好在解决方法很简单,去掉所有的<http-method>。

  4. 不配置SSL:对于应用中的敏感数据,应当使用SSL来加以保护,配置方式参见这里
  5. 不使用Secure标签;即使使用SSL进行用户验证,也不可高枕无忧。因为,应用中有可能存在非SSL也能访问的内容,要杜绝所有非SSL的访问,就要使用Secure标签,配置示例如下:
  6. 1<session-config>
    2  <cookie-config>
    3    <secure>true</secure>
    4  </cookie-config>
    5</session-config>
  7. 不使用HttpOnly标签:HttpOnly标签的意思是禁止客户端脚本访问Cookie,这样可以避免常见的XSS(Cross-site scripting,跨站点脚本)的攻击。
  8. 使用URL参数进行会话跟踪:<tracking-mode>用来设置JSESSIONID存放的位置,可选值为COOKIE、URL、SSL。如果选择了URL,JSESSIONID可能会保存到浏览器历史记录、代理服务器日志、Web日志中,这就等于将你的身份证号码公告天下。
  9. 不设置会话过期时间:为了图方便,而不设置会话过期时间,黑客就会有充足的时间对你的应用进行,诸如会话劫持以及CSRF(Cross-site request forgery,跨站点请求伪造)这样的攻击。配置会话过期时间并不难:
  10. 1<session-config>
    2  <session-timeout>15</session-timeout>
    3</session-config>

    上述代码设置的过期时间为15分钟,如果session-timeout的值小于或等于0,则表示会话永不过期。强烈不推荐!如果web.xml中没有使用session-timeout属性设置会话过期时间,Web服务器就会使用Web容器的缺省会话过期时间,比如:Tomcat的缺省会话过期时间为30分钟。也可以在HttpSession类中使用setMaxInactiveInterval属性设置这个时间,只是需要注意这里的单位是秒。

好,web.xml为应用建起了第一道防线,下面Grails应用也要穿上防弹衣。Gautam Malhotra告诉大家如何见招拆招

SQL注入攻击

如果你习惯于用如下方式执行查询:

1Post.findAll(" from Post as post WHERE post.user.username='${username}' ")

一旦黑客将username的值设置为" ' or '1' = '1",这个查询就会返回所有的Post对象,多么可怕的性能隐患!如果delete语句也使用上述参数赋值方式,那你的数据就极度危险了,有可能一夜之间所有数据都丢失了!换一种方法,就能去除这些隐患:

1Post.findAll(" from Post as post WHERE post.user.username=? ", [username])

Grails的DomainClass对于防止这类攻击提供了天然屏障。但在直接使用SQL和HQL时,需注意以上的问题。

XSS攻击

这种攻击是将变量的值修改为HTML或者javascript,当页面显示变量时,自动执行变量中的HTML或者js代码,尤其是js,几乎可以让你崩溃!GSP中,${..}返回的内容缺省是不被转义的,其中的任何HTML字符串内容被直接输出到页面。这就增加了被XSS攻击的风险。比如,页面上有如下代码:

1<%
2 def username="<script type=/"text/javascript/">alert(/"alert/")</script>"
3 %>
4 <div>${username}</div>

在每次刷新页面的时候都会看到alert弹出窗口。要降低被攻击的风险,可以这么做:

 

  • 对于GSP中要显示的变量,使用encodeAsHTML()方法进行转码,比如:"${username.encodeAsHTML()}";
  • 这里需要注意,对于诸如textField、textArea这样的Grails标签,value属性已经进行encodeAsHTML处理了,比如:

    1<g:textField name="username" value="${username}">
    2<!--等同于 -->
    3<g:textField name="username" value="${username.encodeAsHTML()}">
  • 使用页指令defaultCodec对页面进行HTML转义,例如:在每个页面上添加<%@ defaultCodec="html" %>,或者简单点,在Config.groovy文件中使用grails.views.default.codec属性指定转义,例如:grails.views.default.codec="html",会对所有GSP生效。

如果URL采用如下方式传参数:“/gTunes/albums?title=${params.title}”,这也是XSS攻击的对象,请使用encodeAsURL()进行URL的转义,比如:“/gTunes/albums?title=${params.title?.encodeAsURL()}”。

是不是有所感悟?原来,许多偷懒做法都会给应用带来安全隐患。快给你的应用进行秋季进补吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值