前端面试-CSP内容安全策略 面试笔记

7 阅读5分钟

前端面试必看:CSP内容安全策略

本文专为前端面试梳理,白话讲解+CSP实操+高频真题,复盘、发文两用,看完吃透CSP核心考点。

一、基础认知:一句话吃透CSP

CSP(Content-Security-Policy)即内容安全策略,是浏览器提供的白名单安全机制,通过制定资源加载规则,限制页面可执行/加载的脚本、样式、图片等资源,从源头抵御XSS攻击、数据注入等安全风险,是前端必备安全知识点。

核心本质:不信任任何外部未知资源,只放行明确授权的内容,堵死恶意代码执行路径

二、核心作用:解决什么问题?

  • 主要防御目标:XSS攻击(存储型、反射型),杜绝恶意注入的JS脚本执行
  • 限制非法资源加载:禁止未经授权的第三方脚本、字体、iframe、插件等
  • 防范数据窃取、页面篡改、点击劫持等衍生安全问题
  • 补充说明:CSP是安全增强层,无法100%杜绝所有XSS(如DOM型XSS、CSP绕过漏洞),但能大幅降低风险

三、两种配置方式(面试必答)

1. HTTP响应头配置(生产推荐)

通过服务器(Nginx、Node、Apache)设置响应头,功能最全、优先级最高,支持所有CSP指令。

# Nginx 配置 CSP 响应头(生产环境推荐)
# always:确保所有响应(如404/500)都携带CSP头
add_header Content-Security-Policy " 
default-src 'self';# 默认仅允许同域资源 
script-src 'self';# JS脚本仅允许加载同域 
object-src 'none' # 禁止所有插件(Flash/Java等) 
" always;
// Node/Express中间件配置
const express = require('express');
const app = express();

// 全局CSP响应头
app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self'; object-src 'none'"
  );
  next();
});

app.listen(3000, () => console.log('服务启动成功'));

2. Meta标签配置(纯前端)

直接写入HTML头部,无需修改服务器,适合静态页面;局限性:不支持frame-ancestors、report-uri等指令。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>CSP配置示例</title>
  <!-- 纯前端CSP配置 -->
  <meta http-equiv="Content-Security-Policy" content="
    default-src 'self';
    script-src 'self';
    style-src 'self' 'unsafe-inline';
    img-src 'self' data:
  ">
</head>
<body>
  <h1>CSP页面演示</h1>
</body>
</html>

四、高频指令&关键字(必背表格)

1. 核心指令(控制不同资源)

指令作用
default-src默认规则,所有未单独配置的资源均遵循此指令
script-src控制JS脚本、内联script、eval执行
style-src控制CSS样式、内联样式
img-src控制图片、图标资源加载
connect-src控制fetch/ajax/websocket等网络请求
frame-src控制iframe嵌套页面
object-src控制Flash、插件等,推荐设为none
frame-ancestors控制页面是否允许被嵌套,防点击劫持

2. 关键配置值(高频考点)

  • 'self' :仅允许同域名、同协议、同端口的资源,最常用
  • 'none' :禁止所有相关资源,安全性最高
  • 'unsafe-inline' :允许内联脚本/样式(不推荐,XSS主要利用点)
  • 'unsafe-eval' :允许eval、new Function等动态执行代码(高危
  • 具体域名:如cdn.baidu.com,放行指定第三方资源
  • data::允许base64格式资源(如图片、字体)

五、安全进阶:nonce与hash(替代unsafe-inline)

业务必须使用内联脚本时,摒弃unsafe-inline,采用更安全的方式,掘金代码块演示如下:

1. nonce(随机数)

服务端每次生成唯一随机字符串,CSP白名单绑定该nonce,仅携带对应nonce的内联脚本可执行。

# 响应头配置nonce
add_header Content-Security-Policy "script-src 'nonce-2025csp-random-key';";
<!-- 合法内联脚本,必须携带对应nonce -->
<script nonce="2025csp-random-key">
  console.log('CSP允许的内联脚本执行')
</script>

2. hash(哈希值)

计算内联脚本内容的SHA哈希,将哈希值加入白名单,仅匹配哈希的脚本可执行。

# 配置哈希值放行内联脚本
Content-Security-Policy "script-src 'sha256-abcdefghijklmn1234567890';"

六、调试技巧:Report-Only模式

上线前必用,只上报违规、不拦截资源,避免配置错误导致页面崩溃,控制台可查看所有违规资源。

# 调试模式:仅上报不拦截
add_header Content-Security-Policy-Report-Only "default-src 'self';";
<!-- meta标签调试写法 -->
<meta http-equiv="Content-Security-Policy-Report-Only" content="default-src 'self'">

七、面试高频问答(直接背诵)

1. CSP为什么能防XSS?

XSS核心是注入恶意内联/外部脚本,CSP默认禁止内联脚本、限制脚本来源,攻击者注入的代码不在白名单内,浏览器会直接拦截不执行,从根源阻断攻击。

2. meta标签和HTTP响应头的区别?

HTTP响应头功能完整、优先级更高,支持所有指令,适合生产环境;meta标签纯前端配置、便捷但有指令限制,适合静态页面调试。

3. 为什么不推荐用unsafe-inline?

开启后允许任意内联脚本执行,XSS攻击者可直接注入恶意内联代码,完全失去CSP的防护意义,业务需内联脚本时优先用nonce/hash替代。

4. 项目配置CSP后页面异常,怎么排查?

第一步打开浏览器控制台,查看CSP违规报错;第二步切换Report-Only模式定位问题资源;第三步将可信资源加入对应白名单;第四步验证无误后正式启用CSP。

5. CSP和X-XSS-Protection的区别?

X-XSS-Protection是浏览器基础XSS防护,规则简单、易被绕过;CSP是白名单机制,防护更全面、更灵活,是现代主流安全方案。

八、生产标准配置(直接复制复用)

Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-{{随机值}}';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self' https://api.xxx.com;
object-src 'none';
frame-ancestors 'self';
frame-src 'none';

面试收尾金句:CSP通过白名单机制严控资源加载,是前端防御XSS的核心手段,生产环境优先用响应头配置,结合nonce提升安全性,上线前用Report-Only调试。