ZKOSS - 会话令牌固定 -

问题描述 投票:0回答:1

希望有人有想法。我需要的:

在尝试进行身份验证时,检查是否设置了某个会话属性:

Sessions.getCurrent().getAttribute(...);

通过这样做,创建了一个新会话。如果未设置该属性,则会检查身份验证,并需要将其保存到新会话中。它必须是一个新会话来检索新的会话ID,否则该应用程序将会破坏会话令牌固定攻击。

现在我无法使会话无效,获取新会话然后设置身份验证,因为

Sessions.getCurrent().invalidate();
Sessions.getCurrent(true).setAttribute(...);

在最后一个请求完成之前不会销毁会话,因此这里的getCurrent()会给我“旧”会话,此时此时仍然有效。

我的想法是事后向前发送一个URL中的必要属性,将它们保存在会话的另一个方法中,我可以访问新会话。但是,我收到了IllegalStateException:

java.lang.IllegalStateException:在处理用户请求时使用sendRedirect

有关如何解决这种情况的任何想法?

提前致谢! MJ。

zk
1个回答
0
投票

我不是安全专家,因此请自行检查(以及您的安全团队)以下代码是否符合您的特定要求。它只是试图演示如何使用本机会话和请求对象来有条件地使会话无效,设置/检查属性并在需要时转发请求。

对于这种情况,我建议使用较低级别的抽象,并直接使用本机HttpSession和HttpServletRequest对象,例如在servlet过滤器中。

这会在请求处理的早期阶段捕获潜在的操作尝试(并使您独立于所使用的框架工作)。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class CheckCertainAttributeFilter implements Filter {

    public static final String CERTAIN_SESSION_ATTRIBUTE = "certain-session-attribute";
    public static final String MY_EXPECTED_VALUE = "my-expected-value";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        final HttpSession session = httpServletRequest.getSession();

        //session present, check for certain session attribute value
        if (session != null) { 
            final String certainSessionAttributeValue = 
                    (String) session.getAttribute(CERTAIN_SESSION_ATTRIBUTE);
            if (!MY_EXPECTED_VALUE.equals(certainSessionAttributeValue)) {
                session.invalidate();
                HttpSession newSession = ((HttpServletRequest) request).getSession(true);
                newSession.setAttribute(CERTAIN_SESSION_ATTRIBUTE, MY_EXPECTED_VALUE);
                request.getRequestDispatcher("/login.zul").forward(request, response);
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }
}

然后在web.xml中配置过滤器

<filter>
    <filter-name>checkCertainAttribute</filter-name>
    <filter-class>CheckCertainAttributeFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>checkCertainAttribute</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

之后,除非会话属性中存在预期值,否则每个请求都将转发到login.zul页面。

© www.soinside.com 2019 - 2024. All rights reserved.