我有一个基于 JSF 构建的 Web 应用程序,并使用 MySQL 作为数据库。我已经在我的应用程序中实现了防止 CSRF 的代码。
现在,由于我的底层框架是 JSF,我想我不必处理 XSS 攻击,因为它已经由 UIComponent
处理了。我没有在任何视图页面中使用任何 JavaScript。即使我使用,我真的需要实现代码来防止 XSS 攻击吗?
对于数据库,我们在所有数据库交互中使用准备好的语句和存储过程。
为了防止这 3 种常见攻击,还需要采取其他措施吗?
我已经浏览过 OWASP 网站及其 备忘单。
我需要注意任何其他潜在的攻击媒介吗?
I have a web application built on JSF with MySQL as DB. I have already implemented the code to prevent CSRF in my application.
Now since my underlying framework is JSF, I guess I don't have to handle XSS attack as it is already handled by UIComponent
. I am not using any JavaScript in any of the view pages. Even if I use do I really need to implement code to prevent XSS attacks?
For DB we are using prepared statements and stored procedures in all DB interactions.
Is there anything else needs to be handled for preventing these 3 common attacks?
I have already been through the OWASP site and their cheat sheets.
Do I need to take care of any other potential attack vectors?
发布评论
评论(3)
XSS
JSF 旨在具有内置的 XSS 预防功能。您可以使用以下命令安全地重新显示所有用户控制的输入(请求标头(包括 cookie!)、请求参数(以及保存在数据库中的参数!)和请求正文(上传的文本文件等))任何 JSF 组件。
请注意,当您在 Facelets 上使用 JSF 2.0 时,您可以在模板文本中使用 EL,如下所示:
这也将被隐式转义。这里不一定需要
。仅当您使用
escape="false"
显式取消转义用户控制的输入时:那么您就有潜在的 XSS 攻击漏洞!
如果您希望将用户控制的输入重新显示为 HTML,其中您希望仅允许 HTML 标记的特定子集,例如
、
、
等,那么您需要通过白名单来清理输入。 HTML 解析器 Jsoup 非常对此有帮助。
Mojarra 中的
itemLabelEscaped
错误itemLabelEscaped
2.2.62.2.6 之前的旧版 Mojarra 存在以下错误:当提供
List 时,
通过
会错误地呈现未转义的标签。
而不是List
或SelectItem[]
作为值(问题 3143)。换句话说,如果您通过List
将用户控制的数据重新显示为项目标签,则存在潜在的 XSS 漏洞。如果无法升级到至少 Mojarra 2.2.6,则您需要将itemLabelEscaped
属性显式设置为true
以防止出现这种情况。CSRF
JSF 2.x 已经在使用服务器端状态保存时以
javax.faces.ViewState
隐藏字段的形式内置了 CSRF 预防功能。在 JSF 1.x 中,这个值非常弱并且太容易预测(实际上它从来没有被设计为 CSRF 预防)。在 JSF 2.0 中,通过使用长而强的自动生成值而不是相当可预测的序列值,这一点得到了改进,从而使其成为强大的 CSRF 预防措施。在 JSF 2.2 中,这一点甚至得到了进一步改进,使其成为 JSF 规范的必需部分,并在启用客户端状态保存的情况下使用可配置的 AES 密钥来加密客户端状态。另请参阅 JSF 规范问题 869 和 在其他会话 (CSRF) 中重用 ViewState 值。 JSF 2.2 中的新功能是对
<受保护的视图>
。仅当您使用无状态视图(如
中的情况),或者应用程序中存在 XSS 攻击漏洞时,才会存在潜在的 CSRF 攻击漏洞。SQL 注入
这不是 JSF 的责任。如何防止这种情况取决于您使用的持久性 API(原始 JDBC、现代 JPA 或优秀的 Hibernate),但归根结底,您不应该将用户控制的输入连接到 SQL 字符串中,例如所以
想象一下如果最终用户选择以下名称会发生什么:
您应该始终在适用的情况下使用参数化查询。
在普通 JDBC 中,您需要使用
PreparedStatement
来填充参数值,在 JPA(和 Hibernate)中,
查询
对象也为此提供了设置器。XSS
JSF is designed to have builtin XSS prevention. You can safely redisplay all user-controlled input (request headers (including cookies!), request parameters (also the ones which are saved in DB!) and request bodies (uploaded text files, etc)) using any JSF component.
Note that when you're using JSF 2.0 on Facelets, then you can use EL in template text like so:
This will also implicitly be escaped. You don't necessarily need
<h:outputText>
here.Only when you're explicitly unescaping user-controlled input using
escape="false"
:then you've a potential XSS attack hole!
If you'd like to redisplay user-controlled input as HTML wherein you would like to allow only a specific subset of HTML tags like
<b>
,<i>
,<u>
, etc, then you need to sanitize the input by a whitelist. The HTML parser Jsoup is very helpful in this.itemLabelEscaped
bug in Mojarra < 2.2.6Older Mojarra versions before 2.2.6 had the bug wherein
<f:selectItems itemLabel>
incorrectly renders the label unescaped when provided aList<T>
via<f:selectItems var>
instead ofList<SelectItem>
orSelectItem[]
as value (issue 3143). In other words, if you're redisplaying user-controlled data as item labels via aList<T>
, then you've a potential XSS hole. If upgrading to at least Mojarra 2.2.6 is not an option, then you need to explicitly setitemLabelEscaped
attribute totrue
to prevent that.CSRF
JSF 2.x has already builtin CSRF prevention in flavor of
javax.faces.ViewState
hidden field in the form when using server side state saving. In JSF 1.x this value was namely pretty weak and too easy predictable (it was actually never intended as CSRF prevention). In JSF 2.0 this has been improved by using a long and strong autogenerated value instead of a rather predictable sequence value and thus making it a robust CSRF prevention.In JSF 2.2 this is even be further improved by making it a required part of the JSF specification, along with a configurable AES key to encrypt the client side state, in case client side state saving is enabled. See also JSF spec issue 869 and Reusing ViewState value in other session (CSRF). New in JSF 2.2 is CSRF protection on GET requests by
<protected-views>
.Only when you're using stateless views as in
<f:view transient="true">
, or there's somewhere a XSS attack hole in the application, then you've a potential CSRF attack hole.SQL injection
This is not JSF's responsibility. How to prevent this depends on the persistence API you're using (raw JDBC, modern JPA or good ol' Hibernate), but all boils down that you should never concatenate user-controlled input into SQL strings like so
Imagine what would happen if the enduser chooses the following name:
You should always use parameterized queries where applicable.
In plain JDBC you need to use
PreparedStatement
to fill the parameter values and in JPA (and Hibernate), theQuery
object offers setters for this as well.即使您不在页面中使用 JavaScript,您也可能容易受到 XSS 攻击。当您合并由攻击者控制的内容而未对其进行正确编码时,就会发生 XSS。
每当您执行诸如
攻击者可能导致
x
包含包含 JavaScript 的 HTML 之类的操作时,您就很容易受到 XSS 的攻击。解决方案通常是不要编写大量代码。通常,解决方案是先对
$x
和攻击者控制的任何其他值进行编码,然后再将它们包含在您生成的 HTML 中。过滤或清理输入有助于提供额外的保护层。
您还可以使用自动编码输出的模板语言来防止 XSS。
闭包模板就是 Java 的此类选项之一。
编辑
由于您使用的是 JSF,因此您应该阅读 JSF 中的 XSS 缓解 :
You can be vulnerable to XSS even if you don't use JavaScript in your pages. XSS occurs when you incorporate content controlled by an attacker without properly encoding it.
Anytime you do something like
where an attacker can cause
x
to contain HTML that contains JavaScript, then you are vulnerable to XSS.The solution is usually not to write large amounts of code. Typically the solution is to encode
$x
and any other values controlled by an attacker before including them in the HTML you generate.Filtering or sanitizing inputs can help provide an additional layer of protection.
<shameless-plug>
You can also use a template language that encodes output automatically to protect against XSS.
Closure Template is one such option for Java.
EDIT
Since you are using JSF you should read up on XSS mitigation in JSF:
当将
与未转义值(例如来自 html 文本编辑器)一起使用时,您很容易遭受令人讨厌的 XSS 攻击。在这种情况下,我使用 JSF 转换器,它使用 Jsoup 从文本中删除 javascript,而保持 HTML 完好无损。转换器也可用于清理用户输入。您可以像这样使用它:以及转换器本身:
注意:
当您将 JSF 与 PrimeFaces 结合使用时,请注意
- 旧版本(6.2 之前的版本)默认情况下不会清理用户输入。When using
<h:outputText escape="false">
with unescaped values (for example coming from html text editors) you're open for a nasty XSS attacks. In such cases I'm using a JSF converter which uses Jsoup to remove javascript from text leaving HTML intact. Converter can be used to sanitize user inputs as well. You can use it like this:<h:outputText value="{bean.value}" escape="false" converter="htmlSanitizingConverter"/>
And the converter itself:
Note:
When you're using JSF with PrimeFaces, beware of
<p:textEditor>
- older versions (prior to 6.2) by default didn't sanitize user input.