JSF 中的 CSRF、XSS 和 SQL 注入攻击预防

发布于 2024-12-08 22:23:08 字数 463 浏览 1 评论 0 原文

我有一个基于 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我恋#小黄人 2024-12-15 22:23:08

XSS

JSF 旨在具有内置的 XSS 预防功能。您可以使用以下命令安全地重新显示所有用户控制的输入(请求标头(包括 cookie!)、请求参数(以及保存在数据库中的参数!)和请求正文(上传的文本文件等))任何 JSF 组件。

<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>

这也将被隐式转义。这里不一定需要

当您使用 escape="false" 显式取消转义用户控制的输入时:

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

那么您就有潜在的 XSS 攻击漏洞!

如果您希望将用户控制的输入重新显示为 HTML,其中您希望仅允许 HTML 标记的特定子集,例如 等,那么您需要通过白名单来清理输入。 HTML 解析器 Jsoup 非常对此有帮助

Mojarra 中的 itemLabelEscaped 错误 itemLabelEscaped 2.2.6

2.2.6 之前的旧版 Mojarra 存在以下错误:当提供 List 时, 会错误地呈现未转义的标签。 通过 而不是 ListSelectItem[] 作为值(问题 3143)。换句话说,如果您通过 List 将用户控制的数据重新显示为项目标签,则存在潜在的 XSS 漏洞。如果无法升级到至少 Mojarra 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 规范的必需部分,并在启用客户端状态保存的情况下使用可配置的 AES 密钥来加密客户端状态。另请参阅 JSF 规范问题 869在其他会话 (CSRF) 中重用 ViewState 值。 JSF 2.2 中的新功能是对 <受保护的视图>

仅当您使用无状态视图(如 中的情况),或者应用程序中存在 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 + "')";

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

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)中,查询 对象也为此提供了设置器。

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.

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

Note that when you're using JSF 2.0 on Facelets, then you can use EL in template text like so:

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

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":

<h:outputText value="#{user.name}" 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.6

Older Mojarra versions before 2.2.6 had the bug wherein <f:selectItems itemLabel> incorrectly renders the label unescaped when provided a List<T> via <f:selectItems var> instead of List<SelectItem> or SelectItem[] as value (issue 3143). In other words, if you're redisplaying user-controlled data as item labels via a List<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 set itemLabelEscaped attribute to true to prevent that.

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

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

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 + "')";

Imagine what would happen if the enduser chooses the following name:

x'; DROP TABLE user; --

You should always use parameterized queries where applicable.

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)";

In plain JDBC you need to use PreparedStatement to fill the parameter values and in JPA (and Hibernate), the Query object offers setters for this as well.

眸中客 2024-12-15 22:23:08

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

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

每当您执行诸如

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

攻击者可能导致 x 包含包含 JavaScript 的 HTML 之类的操作时,您就很容易受到 XSS 的攻击。

解决方案通常是不要编写大量代码。通常,解决方案是先对 $x 和攻击者控制的任何其他值进行编码,然后再将它们包含在您生成的 HTML 中。

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

过滤或清理输入有助于提供额外的保护层。

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

闭包模板就是 Java 的此类选项之一。

上下文自动转义通过增强闭包模板来根据每个动态值出现的上下文对其进行正确编码,从而防御攻击者控制的值中的 XSS 漏洞。

编辑

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

转义输出文本

默认情况下将 escape 属性设置为 True。通过使用此标签显示输出,您可以缓解大部分 XSS 漏洞。

SeamT​​extParser 和

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

I am not using any JavaScript in any of the view pages. Even if I use do I really need to implement code to bypass XSS Attack.

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

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

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.

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

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.

Contextual autoescaping works by augmenting Closure Templates to properly encode each dynamic value based on the context in which it appears, thus defending against XSS vulnerabilities in values that are controlled by an attacker.

EDIT

Since you are using JSF you should read up on XSS mitigation in JSF:

Escape output text

<h:outputText/> and <h:outputLabel/> by default has the escape attribute set to True. By using this tag to display outputs, you are able to mitigate majority of the XSS vulnerability.

SeamTextParser and <s:formattedText/>

If you would like to allow users to utilise some of the basic html tags to customise their inputs, JBoss Seam provides a <s:formattedText/> tag that allows some basic html tags and styles specified by users.

给妤﹃绝世温柔 2024-12-15 22:23:08

当将 与未转义值(例如来自 html 文本编辑器)一起使用时,您很容易遭受令人讨厌的 XSS 攻击。在这种情况下,我使用 JSF 转换器,它使用 Jsoup 从文本中删除 javascript,而保持 HTML 完好无损。转换器也可用于清理用户输入。您可以像这样使用它:

以及转换器本身:

/**
 * Prevents from XSS attack if output text is not escaped.
 */
@FacesConverter("htmlSanitizingConverter")
public class HtmlSanitizingConverter implements Converter {

    private static final Whitelist JSOUP_WHITELIST = Whitelist.relaxed()
            .preserveRelativeLinks(true)
            .addAttributes(":all","style");
            /*
             Optionally - add support for hyperlinks and base64 encoded images.
            .addTags("img")
            .addAttributes("img", "height", "src", "width")
            .addAttributes("a", "href")
            .addProtocols("img", "src", "http", "https", "data");
            */

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        return (submittedValue != null) ? Jsoup.clean(submittedValue, JSOUP_WHITELIST) : null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (value != null) ? Jsoup.clean(value.toString(), JSOUP_WHITELIST) : "";
    }

}

注意:
当您将 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:

/**
 * Prevents from XSS attack if output text is not escaped.
 */
@FacesConverter("htmlSanitizingConverter")
public class HtmlSanitizingConverter implements Converter {

    private static final Whitelist JSOUP_WHITELIST = Whitelist.relaxed()
            .preserveRelativeLinks(true)
            .addAttributes(":all","style");
            /*
             Optionally - add support for hyperlinks and base64 encoded images.
            .addTags("img")
            .addAttributes("img", "height", "src", "width")
            .addAttributes("a", "href")
            .addProtocols("img", "src", "http", "https", "data");
            */

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        return (submittedValue != null) ? Jsoup.clean(submittedValue, JSOUP_WHITELIST) : null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (value != null) ? Jsoup.clean(value.toString(), JSOUP_WHITELIST) : "";
    }

}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文