Content-Security-Policy: report-uri 指令
已弃用:此特性不再推荐。虽然某些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除,可能正在删除过程中,或者可能仅为兼容性目的而保留。请避免使用它,如果可能,请更新现有代码;请参阅本页底部的兼容性表格以指导您的决策。请注意,此特性可能随时停止工作。
警告: report-to
指令旨在取代 report-uri
,在支持 report-to
的浏览器中,report-uri
指令将被忽略。
然而,在 report-to
获得广泛支持之前,你可以同时指定这两个头,如下所示
Content-Security-Policy: …; report-uri https://endpoint.example.com; report-to endpoint_name
已废弃的 HTTP Content-Security-Policy
(CSP) report-uri
指令指示用户代理报告尝试违反内容安全策略的行为。这些违规报告由通过 HTTP POST
请求发送到指定 URI 的 JSON 文档组成。
该指令本身没有效果,只有与其他指令结合使用时才具有意义。
语法
Content-Security-Policy: report-uri <uri>;
Content-Security-Policy: report-uri <uri> <uri>;
- <uri>
-
指示报告发送位置的 URI。
违规报告语法
报告 JSON 对象通过 HTTP POST
操作发送,Content-Type
为 application/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-directive
是effective-directive
字段的历史名称,包含相同的值。
示例
带有 Content-Security-Policy 的 CSP 违规报告
让我们考虑一个位于 http://example.com/signup.html
的页面。它使用以下策略,除了从 cdn.example.com
加载的样式表外,禁止所有内容。
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
signup.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
请求
{
"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 头将大致相同。
Content-Security-Policy-Report-Only: default-src 'none'; style-src cdn.example.com; report-to /_/csp-reports
报告将相同,除了 disposition "report"
以及当然的 "original-policy"
{
"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
头的响应
Content-Security-Policy: default-src https:; report-uri /csp-violation-report-endpoint/
/csp-violation-report-endpoint/
例如可以运行一个 PHP 脚本,如下所示,该脚本记录详细说明违规的 JSON,如果违规是第一个添加到日志文件的,则向管理员发送一封电子邮件
<?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 |
浏览器兼容性
加载中…