Content-Security-Policy: report-uri 指令

已弃用:此特性不再推荐。虽然某些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除,可能正在删除过程中,或者可能仅为兼容性目的而保留。请避免使用它,如果可能,请更新现有代码;请参阅本页底部的兼容性表格以指导您的决策。请注意,此特性可能随时停止工作。

警告: report-to 指令旨在取代 report-uri,在支持 report-to 的浏览器中,report-uri 指令将被忽略。

然而,在 report-to 获得广泛支持之前,你可以同时指定这两个头,如下所示

http
Content-Security-Policy: …; report-uri https://endpoint.example.com; report-to endpoint_name

已废弃的 HTTP Content-Security-Policy (CSP) report-uri 指令指示用户代理报告尝试违反内容安全策略的行为。这些违规报告由通过 HTTP POST 请求发送到指定 URI 的 JSON 文档组成。

该指令本身没有效果,只有与其他指令结合使用时才具有意义。

CSP 版本 1
指令类型 报告指令
此指令不支持在 <meta> 元素中使用。

语法

http
Content-Security-Policy: report-uri <uri>;
Content-Security-Policy: report-uri <uri> <uri>;
<uri>

指示报告发送位置的 URI。

违规报告语法

报告 JSON 对象通过 HTTP POST 操作发送,Content-Typeapplication/csp-report

注意: 违规报告应被视为攻击者控制的数据。在存储或渲染之前,应正确清理内容。特别是 script-sample 属性(如果提供)。

报告 JSON 对象只有一个顶级属性,"csp-report",其中包含一个具有以下属性的对象

blocked-uri

被内容安全策略阻止加载的资源的 URI。如果被阻止的 URI 与 document-uri 的来源不同,则被阻止的 URI 将被截断,只包含方案、主机和端口。

disposition

根据使用的是 Content-Security-Policy-Report-Only 头还是 Content-Security-Policy 头,值为 "enforce""report"

document-uri

发生违规的文档的 URI。

effective-directive

导致违规的指令。某些浏览器可能会提供不同的值,例如 Chrome 提供 style-src-elem/style-src-attr,即使执行的指令是 style-src

original-policy

Content-Security-Policy HTTP 头指定的原始策略。

referrer 已废弃 非标准

发生违规的文档的引用者。

script-sample

导致违规的内联脚本、事件处理程序或样式的开头 40 个字符。源自外部文件的违规不包含在报告中。

这仅适用于 script-src*style-src* 违规,当相应的 Content-Security-Policy 指令包含 'report-sample' 关键字时。

status-code

实例化全局对象的资源的 HTTP 状态码。

violated-directive 已废弃

导致违规的指令。violated-directiveeffective-directive 字段的历史名称,包含相同的值。

示例

带有 Content-Security-Policy 的 CSP 违规报告

让我们考虑一个位于 http://example.com/signup.html 的页面。它使用以下策略,除了从 cdn.example.com 加载的样式表外,禁止所有内容。

http
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports

signup.html 的 HTML 如下所示

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>Sign Up</title>
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
    Here be content.
  </body>
</html>

你能发现错误吗?样式表只允许从 cdn.example.com 加载,但网站试图从它自己的来源(http://example.com)加载一个。支持 CSP 的浏览器在访问文档时会向 http://example.com/_/csp-reports 发送以下违规报告作为 POST 请求

json
{
  "csp-report": {
    "blocked-uri": "http://example.com/css/style.css",
    "disposition": "report",
    "document-uri": "http://example.com/signup.html",
    "effective-directive": "style-src-elem",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
    "referrer": "",
    "status-code": 200,
    "violated-directive": "style-src-elem"
  }
}

如你所见,报告在 blocked-uri 中包含了违规资源的完整路径。并非总是如此。例如,如果 signup.html 试图从 http://anothercdn.example.com/stylesheet.css 加载 CSS,浏览器将包含完整路径,而只包含来源(http://anothercdn.example.com),以防止泄露有关跨源敏感信息。CSP 规范对此行为进行了解释

带有 Content-Security-Policy-Report-Only 的 CSP 违规报告

report-uri 指令也可以与 Content-Security-Policy-Report-Only 响应头一起使用。此头允许浏览器在测试时报告但不阻止违规。

HTTP 头将大致相同。

http
Content-Security-Policy-Report-Only: default-src 'none'; style-src cdn.example.com; report-to /_/csp-reports

报告将相同,除了 disposition "report" 以及当然的 "original-policy"

json
{
  "csp-report": {
    "blocked-uri": "http://example.com/css/style.css",
    "disposition": "report",
    "document-uri": "http://example.com/signup.html",
    "effective-directive": "style-src-elem",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
    "referrer": "",
    "status-code": 200,
    "violated-directive": "style-src-elem"
  }
}

CSP 违规日志记录

假设服务器发送带有以下 Content-Security-Policy 头的响应

http
Content-Security-Policy: default-src https:; report-uri /csp-violation-report-endpoint/

/csp-violation-report-endpoint/ 例如可以运行一个 PHP 脚本,如下所示,该脚本记录详细说明违规的 JSON,如果违规是第一个添加到日志文件的,则向管理员发送一封电子邮件

php
<?php

// Start configure
$log_file = dirname(__FILE__) . "/csp-violations.log";
$log_file_size_limit = 1000000; // bytes - once exceeded no further entries are added
$email_address = "admin@example.com";
$email_subject = "Content-Security-Policy violation";
// End configuration

$current_domain = preg_replace("/www\./i", "", $_SERVER["SERVER_NAME"]);
$email_subject = $email_subject . " on " . $current_domain;

http_response_code(204); // HTTP 204 No Content

$json_data = file_get_contents("php://input");

// We pretty print the JSON before adding it to the log file
if (($json_data = json_decode($json_data))) {
  $json_data = json_encode(
    $json_data,
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES,
  );

  if (!file_exists($log_file)) {
    // Send an email
    $message =
      "The following Content-Security-Policy violation occurred on " .
      $current_domain . ":\n\n" .
      $json_data .
      "\n\nFurther CPS violations will be logged to the following log file, but no further email notifications will be sent until this log file is deleted:\n\n" .
      $log_file;
    mail(
      $email_address,
      $email_subject,
      $message,
      "Content-Type: text/plain;charset=utf-8",
    );
  } else if (filesize($log_file) > $log_file_size_limit) {
    exit(0);
  }

  file_put_contents($log_file, $json_data, FILE_APPEND | LOCK_EX);
}

规范

规范
内容安全策略级别 3
# directive-report-uri

浏览器兼容性

另见