【问题标题】:Can JSF standard validation prevent code injection?JSF 标准验证可以防止代码注入吗?
【发布时间】:2010-08-26 09:22:21
【问题描述】:

在我的项目中,我在表示层和持久层进行了重复验证,希望提高安全性。所以我的问题是:标准的 JSF 验证可以防止代码注入吗?

<h:inputText id="name" value="#{bean.customer.name}" required="true" requiredMessage="Validation Error: Value is required." title="Name" >
      <f:validateLength maximum="40"/>
</h:inputText>

这里我验证字段是否为空,并验证字段长度。我知道验证字段长度会使代码注入变得更加困难,但有时您需要较长的字段长度,例如textArea。如果这是脆弱的,我将如何解决它?非常感谢您。

【问题讨论】:

  • 这与您的原始问题无关,但我注意到您在表示层中重复验证,我认为值得一提的是,可以使用 Ajax 重用相同的验证逻辑在表示层的持久性(或业务)层中可用。只需使用适合您需要的机制(例如 JSP)将这些逻辑公开为 Ajax 服务,并在需要执行验证时使用 Ajax 调用在客户端调用它们。

标签: java security jsf sql-injection code-injection


【解决方案1】:

默认情况下,JSF 已经通过在 UIInputUIOutput 组件中转义用户控制的输入来阻止 XSS attacks。这可以通过设置escape="false" 属性在h:outputText 中进行控制。你不必担心这个。

另一方面,防止SQL injection attacks 不是JSF 的责任。您需要在持久层中处理这个问题。例如 JPA 和/或 Hibernate,如果使用得当(即不在 SQL/命名查询字符串中连接用户控制的输入),默认情况下也已经阻止它。在普通的 JDBC 中,您需要确保使用 PreparedStatement 而不是 Statement 在 SQL 字符串中包含用户控制的输入。用得好的话,在 JSF 端也不用担心这个了。

相关问题:

【讨论】:

  • 这让我感觉好多了。 :D 谢谢+1
  • 哦,太好了,我正在输入我的答案,你的答案就来了。我的日子注定要结束了!
  • 这被认为是concatenate user-controlled input in SQL/named query strings:@NamedQuery(name="Customer.delete", query="delete from Customer c where c.id = :id"),然后我会将字符串customerId作为参数传递给会话bean中的方法,然后执行此query.setParameter("id", new Long(customerId));
  • 不,这些是命名/参数化查询。那绝对没问题。他们将被逃脱。连接我的意思更像是:"delete from Customer c where c.id = " + customerId.
  • @Harry,命名查询将在内部转换为使用参数化查询的预准备语句。这是 JPA 提供者的责任。在移交给提供者之前,您需要担心构建的本机 SQL 查询。基本上传递给 EntityManager.createQuery() 和 EntityManager.createNativeQuery() 的字符串不应该有串联的用户输入。
【解决方案2】:

注入攻击有一个共同的主题:由于应用程序中的各种缺陷,输入数据在某个时间点被转换并解释为代码。最常见的缺陷是未正确编码或转义的未清理数据。单独存在或不存在编码并不能保护应用程序免受攻击 - 必须对允许将代码转换为数据的字符进行编码,以便它们不会被区分为代码。

现在,从 JSF 的角度来看,设计者已经深思熟虑地加入了针对某些类型攻击的保护。由于它是一个表示层框架,因此存在针对 XSS 攻击(和 CSRF 攻击,尽管它与注入无关)的保护。在Cross Site ScriptingCross Site Request Forgery 的Seam 框架页面中详细讨论了保护机制及其安全使用。 Seam 使用 JSF,因此在保护 JSF 应用程序和 Seam 应用程序免受 XSS 和 CSRF 影响方面没有太大区别;这些页面中的大部分建议在 JSF 应用程序中都适用。

但是,如果您需要保护自己免受其他突出的注入攻击,尤其是 SQL 注入,则需要查看持久性框架提供的功能(假设您将使用其中之一)。如果您手动编写 SQL 查询并直接在代码中执行它们,请使用 PreparedStatement 对象来保护自己免受最常见的 SQL 注入类型的影响。如果您使用的是 JPA、JDO 等,则需要考虑安全地使用此类框架 - 它们中的大多数默认情况下会创建 PreparedStatement 对象,当向它们提供查询时,通常无需担心。

防止 JPA 中的 SQL 注入攻击

命名查询和本机查询将在内部转换为使用参数化查询的预准备语句。这是 JPA 提供者的责任。人们需要担心在移交给提供者之前构建的 SQL 查询。基本上传递给 EntityManager.createQuery() 和 EntityManager.createNativeQuery() 的字符串不应该有串联的用户输入。

PS:CSRF 保护功能出现在 JSF 2 中,而不是在 JSF 1.x 中。它也仅存在于 Seam 的某些版本(2.1.2 及更高版本)中。

【讨论】:

  • 很棒的帖子。我正在使用 JPA 2.0 顺便说一句。我的大部分查询都涉及"@NamedQuery(name="...", query="... :id",然后在会话bean 中我会执行query.setParameter("id", new Long(Id));,其中Id 是我从托管bean 传递下来的字符串。应该没问题吧?抱歉,我只能投票给你,因为 BalusC 肯定会先发帖。我希望这篇文章能吸引更多的流量,这样你的帖子就能得到更多的支持。
  • 我在上面看到了你的评论。谢谢:D
  • @Harry,我今天有点呆滞。 BalusC 的答案值得被标记为正确。很高兴能帮上忙:-)
猜你喜欢
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 2020-08-09
  • 2015-11-08
  • 2012-10-21
  • 2022-08-05
  • 1970-01-01
相关资源
最近更新 更多