1. 首页
  2. css

CSS内容安全策略:防止混合内容的简单方法

我最近了解了一个浏览器特性,如果您提供了一个特殊的HTTP头,它将自动发布到一个URL,并报告任何非HTTPS内容。在将站点转换为HTTPS时,这将是一件非常好的事情,例如,根除任何混合内容警告。在本文中,我们将通过一个小的WordPress插件来实现这个特性。
什么是混合内容?
\”混合内容\”意味着您\”通过HTTPS页面加载页面,但该页面上的某些资产(图像、视频、CSS、脚本、脚本调用的脚本等)是通过纯HTTP加载的。关于混合内容的浏览器警告。
我假设我们对这个警告非常熟悉,请读者参阅这本优秀的初级读物,了解有关混合内容的更多背景知识。什么是内容安全策略?
内容安全策略(CSP)是一种浏览器功能,它使我们能够指导浏览器如何处理混合内容错误。通过在页面中包含特殊的HTTP头,我们可以告诉浏览器阻止、升级或报告混合内容。本文关注于报告,因为它为我们提供了一个简单而有用的进入CSP的切入点。
CSP是一个奇怪的不透明名称。不要让它吓到你,因为它很容易处理。它似乎对每只狗都有极好的支持。下面是Chrome中传出报告的形成方式:
{\”csp-report\”: {\”document-uri\”:\”http://localhost/wp/2017/03/21/godaddys-micro-dollars/\”,\”referrer\”:\”http://localhost/wp/\”,\”violated-directive\”:\”style-src\”,\”effective-directive\”:\”style-src\”,\”original-policy\”:\”default-src https: \”unsafe-inline\” \”unsafe-eval\”; report-uri>
Here\”s what it looks like in its natural habitat:The outgoing report in the network panel of Chrome\”s inspector.What do I do with this?
What you\”re going to have to do, is tell the browser what URL to send that report to, and then have some logic on your server to listen for it. From there, you can have it write to a log file, a database table, an email, whatever. Just be aware that you will likely generate an overwhelming amount of reports. Be very much on guard against self-DOSing!Can I just see an example?
You may! I made a small WordPress plugin to show you. The plugin has no UI, just activate it and go. You could peel most of this out and use it in a non-WordPress environment rather directly, and this article does not assume any particular WordPress knowledge beyond activating a plugin and navigating the file system a bit. We\”ll spend the rest of this article digging into said plugin.Sending the headers
Our first step will be to include our content security policy as an HTTP header. Check out this file from the plugin. It\”s quite short, and I think you\”ll be delighted to see how simple it is.
The relevant bit is this line:
header( \”Content-Security-Policy-Report-Only: default-src https: \”unsafe-inline\” \”unsafe-eval\”; report-uri $rest_url\” );
我们可以在那里玩很多参数。
– 对于Content-Security-Policy-Report-Only参数,我们说我们想要一个违反我们策略的资产报告,但我们不想实际阻止或以其他方式影响它们。
– 对于default-src参数,我们说我们注意所有类型的资产,而不仅仅是图像、字体或脚本,比如说,
– 对于https参数,我们的策略是只批准通过https加载的资产。
– 对于unsafe-inline和unsafe-eval参数,我们关心像普通图像标记这样的内联资源,以及用于从字符串中编造代码,比如JavaScriptseval()函数。
– 最后,最有趣的是,使用report-uri $rest_url参数,我们为浏览器提供了一个URL,它应该将报告发送到该URL。
如果您想了解有关参数的更多详细信息,可以使用一个优秀的文档Mozilla.org网站. 同样值得注意的是,我们可以将CSP作为meta标记发送,尽管我发现语法很难理解,Google指出这不是他们首选的方法。
本文将只使用HTTP头技术,您会注意到,在我的头中,我正在做一些工作来构建报表URL。它恰好是一个wpapi URL。我们接下来将深入研究这个问题。注册端点
您可能熟悉WP API。在我们使用wpapi之前的那些日子里,当我需要一些任意的URL来监听表单提交时,我通常会制作一个页面,或者一个自定义post类型的post。这是恼人的和脆弱的,因为它太容易删除在wp管理页面没有意识到它是为了什么。使用wpapi,我们有了一种更稳定的方法来注册侦听器,我在这个类中这样做。这个类有三个有趣的地方。
在第一个函数中,在检查日志是否过大后,我调用了register_rest_route(),这是一个用于注册侦听器的WordPress核心函数:
function rest_api_init() => array( $this, \”cb\” ),));}
该函数还允许我注册回调函数,它处理已发布的CSP报告:
function cb( WP_REST_Request $request ) = json_decode( $body, TRUE = new Record( $args>
In that function, I massage the report in it\”s raw format, into a PHP array that my logging class will handle.Creating a log file
In this class, I create a directory in the wp-content folder where my log file will live. I\”m not a big fan of checking for stuff like this on every single page load, so notice that this function first checks to see if this is the first page load since a plugin update, before bothering to make the directory.
function make_directory() = new Update;if( ! $update -> get_is_update() ) { return FALSE; = file_exists( $log_dir_path );if( $file_exists ) { return FALSE;>
That update logic is in a different class and is wildly useful for lots of things, but not of special interest for this article.Logging mixed content
Now that we have CSP reports getting posted, and we have a directory to log them to, let\”s look at how to actually convert a report into a log entry,
In this class I have a function for adding new records to our log file. It\”s interesting that much of the heavy lifting is simply a matter of providing the aarg to thefopen()函数:
function add_row( $array ) {// Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create = fopen( $path, $mode );// Add the row to the spreadsheet.fputcsv( $handle, $array );// Close the file.fclose( $handle );return TRUE;}
这里没有什么特别的WordPress,只是一个用普通PHP方式向csv添加行的家伙。再说一次,如果你不想拥有一个日志文件,你可以让它发送一封电子邮件或写入数据库,或者任何看起来最好的方法。注意事项
在这一点上,我们已经涵盖了我的插件中所有有趣的亮点,我建议您提供一些需要注意的陷阱。
首先,请注意,与任何浏览器功能一样,CSP报告也会受到跨浏览器差异的影响。请看这篇关于这些差异的令人震惊、煞费苦心的详细报告。
其次,请注意,如果您的服务器配置阻止请求混合内容,那么浏览器将永远没有机会报告这些内容。在这种情况下,CSP报告作为准备迁移到https的方法比监视https遵从性的方法更有用。这种配置的一个例子是Cloudflare\”s\”Always Use HTTPS.
最后,self-DOS问题需要重复。假设一个受欢迎的网站每月会收集数百万份报告是完全合理的。因此,与其跟踪您自己的服务器或数据库上的报告,不如考虑将其外包给诸如httpschecker.net下一步

CSS内容安全策略:防止混合内容的简单方法 为WP2原创文章,链接:https://www.wp2.cn/css/css%e5%86%85%e5%ae%b9%e5%ae%89%e5%85%a8%e7%ad%96%e7%95%a5%ef%bc%9a%e9%98%b2%e6%ad%a2%e6%b7%b7%e5%90%88%e5%86%85%e5%ae%b9%e7%9a%84%e7%ae%80%e5%8d%95%e6%96%b9%e6%b3%95/