在 ‌Nginx + Laravel‌ 环境中配置 ‌CSP (Content Security Policy)‌ 安全头

以下是在 Nginx + Laravel 环境中配置 CSP (Content Security Policy) 安全头的完整指南,涵盖动态生成 Nonce、报告模式、以及常见框架兼容性处理:


1. CSP 核心概念

CSP 通过白名单控制允许加载的资源(JS/CSS/图片等),防止 XSS 和数据注入攻击。
关键指令

  • default-src:默认资源类型限制
  • script-src:控制 JavaScript 来源
  • style-src:控制 CSS 来源
  • report-uri:违规报告地址(可选)

2. 基础 Nginx 配置

在 Nginx 的 SSL 配置块(/etc/nginx/sites-available/laravel.conf)中添加:

server {
    listen 443 ssl;
    # ... 其他 SSL 配置 ...

    # 基础 CSP 策略(示例)
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self';";

    # 可选:启用 CSP 报告模式(不强制拦截,仅记录)
    # add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-violation-report-endpoint";
}

3. Laravel 动态生成 Nonce(关键安全实践)

3.1 创建中间件
php artisan make:middleware ApplyCspHeaders

编辑 app/Http/Middleware/ApplyCspHeaders.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Str;

class ApplyCspHeaders
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // 生成随机 Nonce
        $nonce = Str::random(32);
        $request->attributes->set('csp_nonce', $nonce);

        // 设置 CSP 头(动态包含 Nonce)
        $cspPolicy = "default-src 'self';" .
            "script-src 'self' 'nonce-{$nonce}' https://cdn.jsdelivr.net;" .
            "style-src 'self' 'nonce-{$nonce}';" .
            "img-src 'self' data:;";

        $response->header('Content-Security-Policy', $cspPolicy);

        return $response;
    }
}
3.2 注册中间件

app/Http/Kernel.php$middleware 数组中添加:

protected $middleware = [
    \App\Http\Middleware\ApplyCspHeaders::class,
    // ... 其他中间件 ...
];
3.3 在 Blade 模板中使用 Nonce
<script nonce="{{ request()->attributes->get('csp_nonce') }}">
    // 内联 JS 代码(需 Nonce 才能执行)
</script>

<link href="/style.css" rel="stylesheet" nonce="{{ request()->attributes->get('csp_nonce') }}">

4. 针对常见服务的 CSP 规则

4.1 允许 Google Analytics
add_header Content-Security-Policy "... script-src 'self' https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com;";
4.2 允许 YouTube 嵌入
add_header Content-Security-Policy "... frame-src 'self' https://www.youtube.com;";
4.3 允许 WebSocket 连接
add_header Content-Security-Policy "... connect-src 'self' wss://your-websocket.example.com;";

5. 报告模式与违规监控

5.1 Laravel 路由接收违规报告
// routes/api.php
Route::post('/csp-violation-report-endpoint', function (Request $request) {
    Log::channel('security')->warning('CSP Violation:', $request->all());
    return response()->noContent();
});
5.2 Nginx 配置报告地址
add_header Content-Security-Policy "... report-uri https://your-domain.com/csp-violation-report-endpoint;";

6. 严格模式配置(生产环境推荐)

add_header Content-Security-Policy "
    default-src 'none';
    script-src 'self' 'nonce-{NONCE}' 'strict-dynamic';
    style-src 'self' 'nonce-{NONCE}';
    img-src 'self' data:;
    font-src 'self';
    connect-src 'self';
    frame-ancestors 'none';
    base-uri 'self';
    form-action 'self';
    upgrade-insecure-requests;
";

注意

  • 替换 {NONCE} 为 Laravel 动态生成的 Nonce
  • 'strict-dynamic' 允许通过 JS 动态加载的脚本

7. 测试与验证

7.1 使用浏览器控制台
  • 检查是否有 Content-Security-Policy 响应头
  • 观察是否有 CSP 违规警告
7.2 自动化扫描工具
# 使用 Mozilla Observatory 测试
curl -X POST https://http-observatory.security.mozilla.org/api/v1/analyze?host=your-domain.com

8. 常见问题解决

问题 1:内联样式/脚本被阻止
  • 方案:使用 Nonce 或 Hash 白名单
    script-src 'self' 'sha256-abc123...';
    
问题 2:CDN 资源加载失败
  • 方案:明确添加可信 CDN 到白名单
    script-src 'self' https://cdn.jsdelivr.net;
    
问题 3:CSP 头被覆盖
  • 检查:Nginx 中是否有多个 add_header 指令(后者会覆盖前者)

9. 安全增强建议

  1. 逐步启用:先使用 Content-Security-Policy-Report-Only 模式监控
  2. 最小权限:从 default-src 'none' 开始,逐步添加必要规则
  3. 自动化工具

最终配置示例

Nginx + Laravel 动态 Nonce 方案

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{NONCE}' https://cdn.jsdelivivr.net; style-src 'self' 'nonce-{NONCE}'; img-src 'self' data:; report-uri /csp-violation-report-endpoint;";

Blade 模板

<!-- 动态 Nonce 生效示例 -->
<script nonce="{{ request()->attributes->get('csp_nonce') }}">
    console.log('This inline script is allowed!');
</script>

通过以上步骤,你的 Laravel 应用将获得企业级 CSP 防护,平衡安全性与功能性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值