深入剖析default-src在CSP中的应用与常见坑点解析

欧阳文娟 安全 阅读 2,730
赞 48 收藏
二维码
手机扫码查看
反馈

先看效果,再看代码

说到 default-src,这玩意儿在内容安全策略 (CSP) 里是个挺重要的东西。它决定了你的页面默认能加载哪些资源,比如脚本、图片、样式表等。我今天就来聊聊这个东西怎么用,以及我在实际项目中的一些经验。

深入剖析default-src在CSP中的应用与常见坑点解析

核心代码就这几行

首先,我们来看一下最基本的 CSP 配置。假设你有一个简单的 HTML 页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSP Example</title>
</head>
<body>
    <h1>Hello, CSP!</h1>
    <script src="https://jztheme.com/script.js"></script>
</body>
</html>

为了让这个页面启用 CSP,并且设置 default-src,你需要在 HTTP 头里加上相应的配置。如果你是用 Node.js 的 Express 框架,可以这样写:

const express = require('express');
const app = express();

app.use((req, res, next) => {
    res.setHeader("Content-Security-Policy", "default-src 'self' https://jztheme.com");
    next();
});

app.get('/', (req, res) => {
    res.send(
        &lt;!DOCTYPE html&gt;
        &lt;html lang=&quot;en&quot;&gt;
        &lt;head&gt;
            &lt;meta charset=&quot;UTF-8&quot;&gt;
            &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
            &lt;title&gt;CSP Example&lt;/title&gt;
        &lt;/head&gt;
        &lt;body&gt;
            &lt;h1&gt;Hello, CSP!&lt;/h1&gt;
            &lt;script src=&quot;https://jztheme.com/script.js&quot;&gt;&lt;/script&gt;
        &lt;/body&gt;
        &lt;/html&gt;
    );
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

这个场景最好用

在实际项目中,default-src 通常用于控制外部资源的加载。比如,你可能想限制所有的外部脚本和图片只能从自己服务器或可信的第三方加载。这样的配置可以有效防止恶意注入,提升安全性。

举个例子,假设你有一个博客网站,你想确保所有脚本都来自你自己服务器或者可信的 CDN。你可以这样设置:

res.setHeader("Content-Security-Policy", "default-src 'self' https://cdn.example.com");

这样一来,任何试图从其他地方加载的资源都会被浏览器拦截。亲测有效!

踩坑提醒:这三点一定注意

在使用 default-src 时,有几点需要注意:

  • 不要过度限制:有时候你可能会不小心把一些必要的资源也给限制了,比如 Google Analytics 或者 Facebook Pixel。这种情况下,可以单独为这些资源添加例外,例如:
res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' https://www.google-analytics.com https://connect.facebook.net");
  • 测试很重要:在正式上线前,一定要在开发环境中充分测试 CSP 配置。可以使用 Report-Only 模式 先观察一段时间,看看有没有什么问题。折腾了半天发现,有些资源在某些特定条件下会出问题。
  • 动态配置:如果你的网站有不同的页面需要不同的 CSP 配置,建议在后端动态生成 CSP 头。这样可以避免一刀切带来的问题。

进阶技巧:更灵活的配置

除了基本的 default-src 配置,还有一些高级技巧可以让你的 CSP 更加灵活。比如,你可以使用 nonce 来允许特定的内联脚本:

const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader("Content-Security-Policy", default-src &#039;self&#039;; script-src &#039;self&#039; &#039;nonce-${nonce}&#039;);

res.send(
    &lt;!DOCTYPE html&gt;
    &lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
        &lt;title&gt;CSP Example&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;Hello, CSP!&lt;/h1&gt;
        &lt;script nonce=&quot;${nonce}&quot;&gt;console.log(&#039;This inline script is allowed&#039;);&lt;/script&gt;
    &lt;/body&gt;
    &lt;/html&gt;
);

这种方式可以确保只有带有正确 nonce 的内联脚本才能执行。特别适合那些需要动态生成 JavaScript 的场景。

最后的话

以上是我个人对 default-src 的完整讲解,希望对你有帮助。这个技术的拓展用法还有很多,后续我会继续分享这类博客。如果有更优的实现方式,欢迎评论区交流。

祝大家编码愉快!

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论