HTTP Content-Security-Policy 标头对于 Struts 中的 script-src 无法正常工作

Seb*_*uiz 6 javascript java security struts2 content-security-policy

我在将我的 struts struts2-core-2.5.30 项目版本更新到 struts2-core-6.1.1 时遇到问题,因此我开始收到一条错误,表明安全策略已被违反,做了一些研究,我发现标头应该添加

[仅限报告] 拒绝加载脚本 '',因为它违反了以下内容安全策略指令:“script-src 'nonce-MOz6w31eaDHGUDfV__K8LEZ1' 'strict-dynamic' http: https:”。请注意,存在“strict-dynamic”,因此基于主机的白名单被禁用。请注意,“script-src-elem”未明确设置,因此“script-src”用作后备。

在这个错误中我有这个描述

[仅限报告] 拒绝加载脚本http://localhost:8080/Portal/html/js/jquery/jquery-1.8.3.min.js,因为它违反了以下内容安全策略指令:“script-src 'nonce-MOz6w31eaDHGUDfV__K8LEZ1' 'strict-dynamic' http: https:”。请注意,存在“strict-dynamic”,因此基于主机的白名单被禁用。请注意,“script-src-elem”未明确设置,因此“script-src”用作后备。

[仅限报告] 拒绝加载脚本http://localhost:8080/Portal/html/js/jquery/jquery-ui.1.10.4.min.js,因为它违反了以下内容安全策略指令:“script-src 'nonce-MOz6w31eaDHGUDfV__K8LEZ1' 'strict-dynamic' http: https:”。请注意,存在“strict-dynamic”,因此基于主机的白名单被禁用。请注意,“script-src-elem”未明确设置,因此“script-src”用作后备。

不过我尝试过这些标题

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">


<meta http-equiv="Content-Security-Policy" content="default-src *;
    style-src * 'unsafe-inline'; script-src * 'unsafe-inline'
    'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src *
    'unsafe-inline'; frame-src *;">

<meta http-equiv="Content-Security-Policy" content="default-src  'nonce-rAnd0m'">
<script src="${pageContext.request.contextPath}/html/js/jquery/jquery-1.8.3.min.js" type="text/javascript" nonce="rAnd0m123"></script> 
Run Code Online (Sandbox Code Playgroud)

对于它们中的每一个,我都会遇到相同的错误,在我以前的 Struts 版本中,它没有要求我提供任何这些信息。

我还尝试制作一个拦截器来添加相应的指令,但它对我来说也不起作用。

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.StrutsStatics;


public class SessionInterceptor extends AbstractInterceptor{

   private static final long serialVersionUID = 1L;


   public String intercept(ActionInvocation invocation) throws Exception {
     
    ActionContext ac = invocation.getInvocationContext();
    HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
    //HttpServletResponse response = ServletActionContext.getResponse();

    response.addHeader("X-Frame-Options", "SAMEORIGIN");
    response.addHeader("Content-Security-Policy-Report-Only", "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'self'; connect-src 'self'; report-uri REDACTED");
    response.addHeader("X-Content-Security-Policy-Report-Only", "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'self'; connect-src 'self'; report-uri REDACTED");
    return invocation.invoke();
}

}
Run Code Online (Sandbox Code Playgroud)

以同样的方式,我按照评论中的建议更新了 jquery-1.8.3 版本,但它对我也不起作用

jcc*_*ero 3

Content-Security-PolicyStruts从6.x 版本开始提供支持。

该功能主要在CspInterceptor.

该拦截器是通过提供CspSettings的便捷默认实现来配置的。

默认情况下,该拦截器包含在Struts 配置中。正如您在链接资源文档中看到的那样,默认情况下仅在报告、非强制模式下配置:

<interceptor-ref name="csp">
  <param name="disabled">false</param>
  <param name="enforcingMode">false</param>
</interceptor-ref>
Run Code Online (Sandbox Code Playgroud)

我查看了该库的当前源代码和配套文档,看来CspInterceptor目前无法提供自定义 CSP 配置。

这意味着为了减轻您的错误,一种可能性是禁用CspInterceptor并提供您自己的错误。Struts 文档提供了有关如何完成此操作的指导。对于你的情况,我认为它应该类似于以下内容:

<action name="myAction" class="myActionClass">
    <interceptor-ref name="defaultStack">
        <param name="csp.disabled">true</param>
    </interceptor-ref>
</action>
Run Code Online (Sandbox Code Playgroud)

此外,在我在答案开头引用的提交中,他们提到了组件和相应的标签s:link,以及s:script考虑到默认 CSP 设置来获取所需 CSS 和 Javascript 资源的可能方法:基本上,它们提供了必要的机制根据所应用的策略的需要,考虑链接资源的适当随机数。请考虑查看Struts 提供的展示中的此页面作为示例,为方便起见,在此处复制:

<%@taglib prefix="s" uri="/struts-tags" %>


<html lang="en">
<head>
    <!-- content removed for brevity -->

    <s:url var="jqueryJs" value='/js/jquery-2.1.4.min.js' encode='false' includeParams='none'/>
    <s:script src="%{jqueryJs}"/>
    <!-- other resources... now handling inline sources --> 
    <s:script type="text/javascript">
        $(function () {
            var alerts = $('ul.alert').wrap('<div />');
            alerts.prepend('<a class="close" data-dismiss="alert" href="#">&times;</a>');
            alerts.alert();
        });
    </s:script>


    <!-- ... -->
</head>
Run Code Online (Sandbox Code Playgroud)