简体   繁体   English

如何防止 JSF 2.2 接受来自不同 session 的 ViewState?

[英]How can I prevent JSF 2.2 from accepting a ViewState from a different session?

I am using JSF 2.2 (Glassfish 4.1).我正在使用 JSF 2.2(Glassfish 4.1)。 Our webapp has Primefaces 6.0 and Omnifaces 2.6.9 as dependencies.我们的 webapp 有 Primefaces 6.0 和 Omnifaces 2.6.9 作为依赖项。 JSF state is stored on server. JSF state 存储在服务器上。 As an example say I have this form where userModel is a javax.faces.view.ViewScoped bean.例如说我有这个表单,其中userModel是一个javax.faces.view.ViewScoped bean。

<h:form id="user">
    <p:inputText id="name" value="#{userModel.name}"/>
    <p:inputText id="pass" value="#{userModel.pass}"/>
    <p:commandButton id="create" value="#{msgs.lbl_add}" action="#{userModel.addUser()}"/>
</h:form>

A company scanned our web app for security issues and claims it has a CSRF vulnerability.一家公司扫描了我们的 web 应用程序是否存在安全问题,并声称它存在 CSRF 漏洞。 An attacker can provide a made up form to one of our app users like this to perform unwanted actions.攻击者可以像这样向我们的一个应用用户提供一个虚构的表单来执行不需要的操作。

<!DOCTYPE html>
<html>
    <body>
        <form action="http://appserver:8080/myapp/users.jsf" method="POST">
            <input type="hidden" name="javax.faces.source" value="user:create"/>
            <input type="hidden" name="user:create" value="user:create"/>
            <input type="hidden" name="user" value="user"/>
            <div>
                <input type="text" name="user:name" value="FAKEUSER"/>
                <input type="text" name="user:pass" value="FAKEPASSWORD"/>
                <input type="text" name="javax.faces.ViewState" value="1185295409278172717:-3206872038807094332"/>
            </div>
            <input type="submit" name="submit" value="Create User"/>
        </form>
    </body>
</html>

I read on SO that ViewState is JSF way of preventing CSRF.我在 SO 上读到 ViewState 是 JSF 防止 CSRF 的方式。 But following scenario are possible in our web app (with HTTP protocol if it matters).但是在我们的 web 应用程序中可能会出现以下情况(如果重要,请使用 HTTP 协议)。

  1. Attacker visits our app login page to find a valid ViewState in his page source.攻击者访问我们的应用登录页面以在他的页面源中找到有效的 ViewState。
  2. Attacker prepares HTML file mentioned above with his ViewState and sends to victim.攻击者使用他的 ViewState 准备上述 HTML 文件并发送给受害者。
  3. Victim opens HTML file in browser and submits (from local file system eg file:///C:/... or hosted by local webserver)受害者在浏览器中打开 HTML 文件并提交(来自本地文件系统,例如file:///C:/...或由本地网络服务器托管)
  4. User is created.用户已创建。

The conclusion is that our webapp/JSF in this scenario does not check if the received ViewState belongs to the session identified by JSESSIONID.结论是我们这个场景下的webapp/JSF没有检查接收到的ViewState是否属于JSESSIONID标识的session。

Isn't this a vulnerability?这不是漏洞吗? How can I avoid this?我怎样才能避免这种情况?

In our case it was a bug in our application.在我们的例子中,这是我们应用程序中的一个错误。 We also use Deltaspike library and registered a 'Handle-All-Exceptions' class in our app.我们还使用 Deltaspike 库并在我们的应用程序中注册了一个“Handle-All-Exceptions”class。

import org.apache.deltaspike.core.api.exception.control.ExceptionHandler;
import org.apache.deltaspike.core.api.exception.control.Handles;
import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent;

@ExceptionHandler
public class ExceptionDispatcher {

    public void processException(@Handles ExceptionEvent<Throwable> evt) {
        // Handle exception by just logging
    }
}

This also "handled" javax.faces.application.ViewExpiredException which occur if JSF finds a invalid ViewState.如果 JSF 发现无效的 ViewState,这也会“处理” javax.faces.application.ViewExpiredException As a result the request was normally processed.结果,请求被正常处理。

A better implementation will redirect to an error page and invalidate session.更好的实现将重定向到错误页面并使 session 无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM