首页 > 解决方案 > 提供 php 文件时,在 apache conf 中定义的 CSP 不起作用

问题描述

我正在配置站点的 apache csp 锁定,当我打开与 php 脚本相同的文件而不是作为 html 文件打开它时,我遇到了一种奇怪的行为。

html文件是:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="cache-control" content="no-cache" />
    <script TYPE="text/javascript" src="injectblob.js" nonce="NEFFZW1HYjB4SnB0b0lHRlAzTmQ="></script>
  </head>
  <body>
   here
  </body>
</html>

php文件是:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="cache-control" content="no-cache" />
    <script TYPE="text/javascript" src="injectblob.js.php" nonce="HNEFFZW1HYjB4SnB0b0lHRlAzTmQ="></script>
  </head>
  <body>
    her
  </body>
</html>

唯一的区别是 javascript 文件的名称。

作为 .js 和 .js.php 的 javascript 文件是:

"use strict"
var inject1=function(){
  const s = document.createElement('script');
  s.textContent = 'alert("STRING says hello")';
  s.setAttribute("type","text/javascript");
//  s.setAttribute("nonce","NEFFZW1HYjB4SnB0b0lHRlAzTmQ=");
  document.head.appendChild(s);
}

var inject2=function(){
  const s = document.createElement('script');
  const b = new Blob(['alert("BLOB says hello")'], { type: 'text/javascript' });
  const u = URL.createObjectURL(b);
  s.src = u;
  s.setAttribute("type","text/javascript");
//  s.setAttribute("nonce","NEFFZW1HYjB4SnB0b0lHRlAzTmQ=");
  document.head.appendChild(s);
}
window.onload=function(){
  inject1();
  inject2();
}

我在 apache conf 的虚拟主机中设置的 CSP 标头是:

Header add Content-Security-Policy "default-src 'self' blob: 'nonce-NEFFZW1HYjB4SnB0b0lHRlAzTmQ='"
Header add Content-Security-Policy "script-src 'self' 'nonce-NEFFZW1HYjB4SnB0b0lHRlAzTmQ='"

当它作为 html 文件运行时,CSP 正在工作,并且相应的警告在浏览器控制台窗口中显示为“拒绝执行内联脚本,因为它违反了......”。但是当我运行与 php 相同的文件时,注入的脚本会像不存在 CSP 规则一样运行。

在浏览器网络窗口中单击文件,会为 html 文件显示 CSP 规则,但不会为 php 文件显示 CSP 规则。

我知道我可以在 php 中添加适当的标头,但是仅在一个地方定义 CSP 会很方便,并且如果必要时在 php 中否决它们,例如当我想在某些脚本标签中设置 sha 哈希以通过注入时获取收到的加密/解密 javascript。

我的问题是双重的。

  1. 我可以在 apache conf 中设置 CSP,以便规则适用于 php 脚本和 html 文件吗?

  2. 如果对问题 1 的回答是肯定的,那么 php 中设置的 CSP 标头是否会否决 apache conf 中设置的 CSP 标头?

标签: javascriptphphtmlapache

解决方案


在我问这个问题之前,我显然没有深入挖掘。如果包装在指令中,则 apache 虚拟主机 conf 的 csp 标头部分。我没有在 filesMatch 指令中包含 php。

至于用 php header 覆盖 apache conf。这没用。Apache是​​最顶级的CSP!

为了获得问题中提到的功能,我必须在指令中不带 php 的情况下在 apache 中组合 filesMatch,并在 php 中手动包含适当的标头,并注意始终将它们包含在 php 脚本中。如果我想在某些脚本标签中设置一个 sha 哈希以通过获取接收到的加密/解密 javascript 注入,也许不是最安全的方法,而是唯一的方法。我知道该解决方案容易出现人为错误:-(


推荐阅读