session.getAttribute() 的键为空,在 spring 框架 3.2.4 应用程序上使用 OWASP_CSRFTOKEN

Posted

技术标签:

【中文标题】session.getAttribute() 的键为空,在 spring 框架 3.2.4 应用程序上使用 OWASP_CSRFTOKEN【英文标题】:Key for session.getAttribute() is null using OWASP_CSRFTOKEN on a spring framework 3.2.4 app 【发布时间】:2016-01-07 08:12:12 【问题描述】:

我将 OWASP.CsrfGuard.jar 添加到我的 spring 3.2.4 应用程序以防止 CSRF 攻击(CSRF 是一种攻击,它迫使最终用户在他/她当前已通过身份验证的 Web 应用程序上执行不需要的操作。最常用的例子是“有人欺骗您点击链接以获取您登录的银行会话,然后在未经您同意/知情的情况下从您的银行帐户中提取资金)

这里是我的 Owasp.CsrfGuard.properties:

# The OWASP CSRFGuard Project, BSD License
# Eric Sheridan (eric@infraredsecurity.com), Copyright (c) 2011
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of OWASP nor the names of its contributors may be used
#    to endorse or promote products derived from this software without specific
#    prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

org.owasp.csrfguard.Logger=fr.balucom.devices.helpers.csrf.CsrfLogger

org.owasp.csrfguard.configuration.provider.factory = org.owasp.csrfguard.config.overlay.ConfigurationAutodetectProviderFactory


# If csrfguard filter is enabled
org.owasp.csrfguard.Enabled = true

org.owasp.csrfguard.ValidateWhenNoSessionExists = false

org.owasp.csrfguard.TokenPerPage=false
org.owasp.csrfguard.TokenPerPagePrecreate=false

org.owasp.csrfguard.Ajax=true

# The default behavior of CSRFGuard is to protect all pages. Pages marked as unprotected will not be protected.
# If the Protect property is enabled, this behavior is reversed. Pages must be marked as protected to be protected.
# All other pages will not be protected. This is useful when the CsrfGuardFilter is aggressively mapped (ex: /*),
# but you only want to protect a few pages.
#
# org.owasp.csrfguard.Protect=true
org.owasp.csrfguard.ProtectedMethods=POST

# unprotected pages

org.owasp.csrfguard.action.Log=org.owasp.csrfguard.action.Log
org.owasp.csrfguard.action.Log.Message=potential cross-site request forgery (CSRF) attack thwarted (user:%user%, ip:%remote_ip%, method:%request_method%, uri:%request_uri%, error:%exception_message%)
org.owasp.csrfguard.action.Redirect=org.owasp.csrfguard.action.Redirect
org.owasp.csrfguard.action.Redirect.Page=/devices/error.do

# Token Name
#
# The token name property (org.owasp.csrfguard.TokenName) defines the name of the HTTP parameter
# to contain the value of the OWASP CSRFGuard token for each request. The following configuration
# snippet sets the CSRFGuard token parameter name to the value OWASP_CSRFTOKEN:
#
org.owasp.csrfguard.TokenName=OWASP_CSRFTOKEN_REQUEST

# Session Key
#
# The session key property (org.owasp.csrfguard.SessionKey) defines the string literal used to save
# and lookup the CSRFGuard token from the session. This value is used by the filter and the tag
# libraries to retrieve and set the token value in the session. Developers can use this key to
# programmatically lookup the token within their own code. The following configuration snippet sets
# the session key to the value OWASP_CSRFTOKEN:
#
org.owasp.csrfguard.SessionKey=OWASP_CSRFTOKEN

# Token Length
#
# The token length property (org.owasp.csrfguard.TokenLength) defines the number of characters that
# should be found within the CSRFGuard token. Note that characters are delimited by dashes (-) in groups
# of four. For cosmetic reasons, users are encourage to ensure the token length is divisible by four.
# The following configuration snippet sets the token length property to 32 characters:
#
# org.owasp.csrfguard.TokenLength=32
org.owasp.csrfguard.TokenLength=32

# Pseudo-random Number Generator
#
# The pseudo-random number generator property (org.owasp.csrfguard.PRNG) defines what PRNG should be used
# to generate the OWASP CSRFGuard token. Always ensure this value references a cryptographically strong
# pseudo-random number generator algorithm. The following configuration snippet sets the pseudo-random number
# generator to SHA1PRNG:
#
# org.owasp.csrfguard.PRNG=SHA1PRNG
org.owasp.csrfguard.PRNG=SHA1PRNG

# Pseudo-random Number Generator Provider

# The pseudo-random number generator provider property (org.owasp.csrfguard.PRNG.Provider) defines which
# provider's implementation of org.owasp.csrfguard.PRNG we should utilize. The following configuration
# snippet instructs the JVM to leverage SUN's implementation of the algorithm denoted by the
# org.owasp.csrfguard.PRNG property:

# org.owasp.csrfguard.PRNG.Provider=SUN
org.owasp.csrfguard.PRNG.Provider=SUN

# If not specifying the print config option in the web.xml, you can specify it here, to print the config
# on startup
org.owasp.csrfguard.Config.Print=true



# seconds between checking to see if the config files are updated
org.owasp.csrfguard.configOverlay.secondsBetweenUpdateChecks = 60


###########################

然后我在我的 JSP 中包含这个标签:

<input type="hidden" name="<csrf:tokenname />" value="<csrf:tokenvalue />" />

但结果如下:

]] Root cause of ServletException.
java.lang.IllegalArgumentException: Key for session.getAttribute() is null
        at weblogic.servlet.internal.session.SessionData.check(SessionData.java:457)
        at weblogic.servlet.internal.session.SessionData.getAttribute(SessionData.java:410)
        at org.owasp.csrfguard.CsrfGuard.getTokenValue(CsrfGuard.java:295)
        at org.owasp.csrfguard.tag.TokenValueTag.doStartTag(TokenValueTag.java:49)
        at jsp_servlet._web_45_inf._jsp._accounts.__dataaccount._jsp__tag1(__dataaccount.java:1613)
        at jsp_servlet._web_45_inf._jsp._accounts.__dataaccount._jspService(__dataaccount.java:235)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
        at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:478)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:367)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
        at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:573)
        at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispatcherImpl.java:480)
        at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:162)
        at jsp_servlet._web_45_inf._jsp._accounts.__registeraccount._jspService(__registeraccount.java:155)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
        at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:478)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:367)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
        at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:573)
        at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispatcherImpl.java:480)
        at org.apache.taglibs.standard.tag.common.core.ImportSupport.acquireString(ImportSupport.java:347)
        at org.apache.taglibs.standard.tag.common.core.ImportSupport.doEndTag(ImportSupport.java:204)
        at jsp_servlet._web_45_inf._jsp._template.__template._jsp__tag2(__template.java:366)
        at jsp_servlet._web_45_inf._jsp._template.__template._jspService(__template.java:248)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
        at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:478)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:367)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
        at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:573)
        at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:272)
        at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:2
38)
        at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
        at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)

这里是我的 web.xml

<!-- CSRF Guard -->
        <context-param>
            <param-name>Owasp.CsrfGuard.Config</param-name>
            <param-value>/WEB-INF/Owasp.CsrfGuard.properties</param-value>
        </context-param>

        <context-param>
            <param-name>Owasp.CsrfGuard.Config.Print</param-name>
            <param-value>true</param-value>
        </context-param>

        <filter>
            <filter-name>CSRFGuard</filter-name>
            <filter-class>org.owasp.csrfguard.CsrfGuardFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>CSRFGuard</filter-name> 
             <url-pattern>/*</url-pattern>
        </filter-mapping>

         <listener>
            <listener-class>org.owasp.csrfguard.CsrfGuardServletContextListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.owasp.csrfguard.CsrfGuardHttpSessionListener</listener-class>
        </listener>
        <!-- CSRF Guard -->

【问题讨论】:

我找到的唯一解决方案是通过从 web.xml 中删除条目来禁用 CSRF Guard,但这似乎对您不起作用,所以我不会将其发布为回答。 【参考方案1】:

WebLogic 似乎不喜欢 Sun 的 SHA1PRNG 实现。在我们的项目中,我们发现为了让 CSRF Guard 在 WebLogic 上工作(即避免您遇到的确切错误),我们需要替换

org.owasp.csrfguard.PRNG=SHA1PRNG
org.owasp.csrfguard.PRNG.Provider=SUN

org.owasp.csrfguard.PRNG=IBMSecureRandom
org.owasp.csrfguard.PRNG.Provider=IBMJCE

我不确定这是否意味着您需要使用 IBM JDK 才能将 WebLogic 与 CSRF Guard 一起使用,或者您是否可以使用其他一些 PRNG 来使其工作。

请注意,这似乎是特定于 WebLogic 的,因此使用另一个 Java Web 应用程序服务器可能会更好。

【讨论】:

以上是关于session.getAttribute() 的键为空,在 spring 框架 3.2.4 应用程序上使用 OWASP_CSRFTOKEN的主要内容,如果未能解决你的问题,请参考以下文章

session.setAttribute和session.getAttribute

session.getAttribute()返回值是啥啊

JSP手记--jsp里面session.getAttribute("×××")在java中的表示

(Integer)session.getAttribute("userType")).equals(new Integer(1))啥意思~

jsp session获取问题

怎么在 <c:forEach 标签中取到 变量id放入 session.getAttribute(id); (servlet中键为变量,值为常量