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

Ang*_*ons 54 xss jsf sql-injection csrf owasp

我有一个基于JSF的Web应用程序,MySQL作为DB.我已经实现了代码来防止我的应用程序中出现CSRF.

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

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

是否还需要处理其他任何事情以防止这3种常见攻击?我已经通过了OWASP网站和他们的备忘单.

我是否需要处理任何其他潜在的攻击媒介?

Bal*_*usC 108

XSS

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

<h:outputText value="#{user.name}" />
<h:outputText value="#{user.name}" escape="true" />
<h:inputText value="#{user.name}" />
etc...
Run Code Online (Sandbox Code Playgroud)

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

<p>Welcome, #{user.name}</p>
Run Code Online (Sandbox Code Playgroud)

这也将隐含地被转义.你不一定需要<h:outputText>这里.

只有当您明确地使用以下方式取消用户控制的输入时escape="false":

<h:outputText value="#{user.name}" escape="false" />
Run Code Online (Sandbox Code Playgroud)

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

如果你想重新显示用户控制输入为HTML,其中你想只允许像HTML标签的特定子集<b>,<i>,<u>,等等,那么你需要通过一个白名单来净化输入.HTML解析器Jsoup在这方面非常有帮助.

itemLabelEscaped Mojarra中的错误<2.2.6

旧版钻嘴鱼科版本之前 2.2.6了其中错误<f:selectItems itemLabel>时提供一个错误使该标签未转义List<T>通过<f:selectItems var>代替List<SelectItem>SelectItem[]作为值(发行3143).换句话说,如果您通过a将用户控制的数据重新显示为项目标签List<T>,那么您就有了潜在的XSS漏洞.如果升级到至少Mojarra 2.2.6不是一个选项,那么您需要显式设置itemLabelEscaped属性true以防止这种情况.

<f:selectItems value="#{bean.entities}" var="entity" itemValue="#{entity}"
    itemLabel="#{entity.someUserControlledProperty}" itemLabelEscaped="true" />
Run Code Online (Sandbox Code Playgroud)

CSRF

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

在JSF 2.2中,如果启用了客户端端状态保存,则甚至可以通过使其成为JSF规范的必需部分以及用于加密客户端状态的可配置AES密钥来进一步改进.另请参阅JSF规范问题869在其他会话中重用ViewState值(CSRF).JSF 2.2中的新功能是对GET请求的CSRF保护<protected-views>.

只有在您使用无状态视图时<f:view transient="true">,或者应用程序中存在某个XSS攻击漏洞时,您才会遇到潜在的CSRF攻击漏洞.


SQL注入

这不是JSF的责任.如何防止这种情况取决于您正在使用的持久性API(原始JDBC,现代JPA或良好的'Hibernate),但所有归结为您永远不应该将用户控制的输入连接到SQL字符串,如此

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 + "')";
Run Code Online (Sandbox Code Playgroud)

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

x'; DROP TABLE user; --
Run Code Online (Sandbox Code Playgroud)

您应始终在适用的地方使用参数化查询.

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)";
Run Code Online (Sandbox Code Playgroud)

在简单的JDBC中,您需要使用PreparedStatement填充参数值,在JPA(和Hibernate)中,该Query对象也为此提供了setter.

  • 我补充说,与流行的相信相反,使用存储过程不会**自动保存您免受SQL注入攻击:我已经看到存储过程通过串联创建SQL语句而******同样容易受到攻击*SQL注入!这与使用PreparedStatements不会自动保存您的SQL注入攻击的方式相同,如果您使用它们错了! (5认同)
  • 至于XSS,只需删除`escape ="false"`.或者,如果您想允许某些HTML,请使用Jsoup.你只需要做`String safe = Jsoup.clean(unsafe,Whitelist.basic());`.另见[本指南](http://jsoup.org/cookbook/cleaning-html/whitelist-sanitizer).您可以在将输入保存到DB之前直接执行此操作.对于JSF 1.x中的CSRF预防,您应该在表单中维护基于会话的反CSRF令牌(基本上,具有长/自动生成/不可预测值的隐藏输入字段).Seam框架有类似的组件`<s:token>`:http://seamframework.org/Documentation/CrossSiteRequestForgery (3认同)

Mik*_*uel 8

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

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

任何时候你做的事情

response.write("<b>" + x + "</b>")
Run Code Online (Sandbox Code Playgroud)

攻击者可以导致x包含JavaScript的HTML,那么您很容易受到XSS的攻击.

解决方案通常不是编写大量代码.通常,解决方案是编码$x以及攻击者控制的任何其他值,然后将其包含在您生成的HTML中.

response.write("<b>" + escapePlainTextToHtml(x) + "</b>")
Run Code Online (Sandbox Code Playgroud)

过滤或消毒输入可以帮助提供额外的保护层.

<shameless-plug>

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

Closure Template是Java的一个这样的选项.

上下文自动转换的工作原理是通过扩充Closure模板,根据每个动态值出现的上下文对每个动态值进行正确编码,从而防御攻击者控制的值中的XSS漏洞.

编辑

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

转义输出文本

<h:outputText/>并且<h:outputLabel/>在默认情况下有escape属性设置为True.通过使用此标记显示输出,您可以缓解大部分XSS漏洞.

SeamT​​extParser和 <s:formattedText/>

如果您希望允许用户使用一些基本的html标签来自定义他们的输入,JBoss Seam提供了一个<s:formattedText/>标签,允许用户指定一些基本的html标签和样式.

  • 与旧式的JSP/Servlet不同,JSF并没有真正的`response.write(foo)`的概念.对于不熟悉JSF 2.x的用户来说,这个答案有点令人困惑. (2认同)