JSF中的CSRF,XSS和SQL注入攻击防护

我有一个基于JSF的Web应用程序,以MySQL作为数据库。 我已经在我的应用程序中实现了防止CSRF的代码。

现在,由于我的底层框架是JSF,我想我不必处理XSS攻击,因为它已经由UIComponent处理。 我没有在任何视图页面中使用任何JavaScript。 即使我使用,我真的需要执行代码来防止XSS攻击?

对于数据库,我们在所有的数据库交互中都使用准备好的语句和存储过程

还有什么需要处理,以防止这3种常见的攻击? 我已经通过OWASP网站和他们的作弊表 。

我需要照顾任何其他潜在的攻击媒介吗?

XSS

JSF旨在具有内置的XSS预防function。 您可以安全地使用任何JSF组件重新显示所有用户控制的input(请求头(包括cookies!),请求参数(也保存在DB中的请求参数)和请求主体(上传的文本文件等))。

 <h:outputText value="#{user.name}" /> <h:outputText value="#{user.name}" escape="true" /> <h:inputText value="#{user.name}" /> etc... 

请注意,当您在Facelets上使用JSF 2.0时,您可以在模板文本中使用EL,如下所示:

 <p>Welcome, #{user.name}</p> 

这也将隐含地逃脱。 这里你不一定需要<h:outputText>

只有当你使用escape="false"明确地忽略用户控制input时:

 <h:outputText value="#{user.name}" escape="false" /> 

那么你有一个潜在的XSS攻击漏洞!

如果您希望重新显示用户控制的input为HTML,而您希望仅允许特定的HTML标签子集(如<b><i><u>等),则需要通过白名单。 HTMLparsing器Jsoup在这方面非常有帮助 。

itemLabelEscaped在Mojarra <2.2.6中有bug

2.2.6之前的较旧的Mojarra版本有错误,其中当通过<f:selectItems var>而不是List<SelectItem>SelectItem[]提供List<T>作为值时, <f:selectItems itemLabel>错误地呈现标签未转义3143 )。 换句话说,如果您通过List<T>重新显示用户控制的数据作为项目标签,那么您有一个潜在的XSS漏洞。 如果升级到至lessMojarra 2.2.6不是一个选项,那么你需要明确地设置itemLabelEscaped属性为true以防止这种情况。

 <f:selectItems value="#{bean.entities}" var="entity" itemValue="#{entity}" itemLabel="#{entity.someUserControlledProperty}" itemLabelEscaped="true" /> 

CSRF

在使用服务器端状态保存时,JSF 2.x已经在javax.faces.ViewState隐藏字段的格式中内置了CSRF预防。 在JSF 1.x中,这个值非常弱,而且非常容易预测(实际上它从来没有作为CSRF预防)。 在JSF 2.0中,通过使用一个长而强的自动生成的值而不是一个相当可预测的序列值,从而使其成为一个强大的CSRF预防,已经得到了改进。

在JSF 2.2中,如果启用了客户端状态保存,则通过将其作为JSF规范的必需部分以及可configuration的AES密钥来encryption客户端状态,甚至可以进一步改进。 另请参见JSF规范问题869和在其他会话(CSRF)中重复使用ViewState值 。 JSF 2.2中的新function是通过<protected-views>对GET请求进行CSRF保护。

只有在<f:view transient="true">使用无状态视图,或者应用程序中存在XSS攻击漏洞的情况下,才会有潜在的CSRF攻击漏洞。


SQL注入

这不是JSF的责任。 如何防止这种情况取决于你使用的持久性API(原始JDBC,现代JPA或者良好的Hibernate),但是所有的东西都应该归结为你不应该把用户控制的input连接成像这样的SQLstring

 String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = md5(" + password + ")"; String jpql = "SELECT u FROM User u WHERE u.username = '" + username + "' AND u.password = md5('" + password + "')"; 

想象一下,如果最终用户select以下名称会发生​​什么情况:

 x'; DROP TABLE user; -- 

您应该始终在适用的情况下使用参数化查询。

 String sql = "SELECT * FROM user WHERE username = ? AND password = md5(?)"; String jpql = "SELECT u FROM User u WHERE u.username = ?1 AND u.password = md5(?2)"; 

在普通的JDBC中,您需要使用PreparedStatement来填充参数值,而在JPA(和Hibernate)中, Query对象也为此提供了setter。

我没有在任何视图页面中使用任何JavaScript。 即使我使用,我真的需要实现代码绕过XSS攻击。

即使您不在页面中使用JavaScript,也可能容易受到XSS的攻击。 当您合并由攻击者控制的内容而未正确编码时,会出现XSS。

任何时候你都会这样做

 response.write("<b>" + x + "</b>") 

攻击者可以让x包含包含JavaScript的HTML,那么你很容易受到XSS的攻击。

解决scheme通常不会编写大量的代码。 通常情况下,解决scheme是在将代码包含在您生成的HTML中之前,先编码$x和攻击者控制的任何其他值。

 response.write("<b>" + escapePlainTextToHtml(x) + "</b>") 

过滤或消毒input可以帮助提供额外的保护层。

<shameless-plug>

您也可以使用自动编码输出的模板语言来防止XSS。

closures模板是Java的一个select。

上下文自动转义的工作方式是通过增加Closure Templates来正确地对每个dynamic值进行编码,从而防止攻击者控制的值中的XSS漏洞。

编辑

由于您使用的是JSF,因此您应该阅读JSF中的XSS缓解 :

转义输出文本

默认情况下, <h:outputText/><h:outputLabel/>的escape属性设置为True。 通过使用此标记来显示输出,您可以减轻大部分XSS漏洞。

SeamT​​extParser和<s:formattedText/>

如果你想允许用户使用一些基本的html标签来定制他们的input,JBoss Seam提供了一个<s:formattedText/>标签,允许用户指定一些基本的html标签和样式。

Interesting Posts