想象你搬进一个安保严格的小区,物业给你发来一份《访客须知》:从今天起,所有想进小区的快递员、外卖员、装修工,都必须出示身份和来源证明;顺丰和京东可以进,来源不明的车辆一律拦在门外;所有访客必须从有保安的正门进入,后门永远锁死;你家的户型图不允许被贴到别人家的展厅里展示。 这些看起来“多此一举”的规定,正是 Web 应用世界里安全响应头在做的事。浏览器就像一个小区物业,HTTP 响应头就是它发给每家每户的门禁规则:CSP 管理“哪些外部资源能进页面”,HSTS 强制“只走 HTTPS 正门”,X-Frame-Options 防止“你家被嵌套到别人家”,X-Content-Type-Options 确保“快递按标签配送”,Referrer-Policy 控制“访客登记簿上写多少信息”。 本篇文章就用这套“小区门禁”的比喻,带你从零认识这些安全响应头:它们分别防什么、怎么配、配错了会怎样,以及如何按 OWASP 的标准把它们落到开发全流程中。
安全响应头是浏览器层面的纵深防御基础,掌握 CSP 与 HSTS 等头的配置原理,是 Web 安全工程师、后端与前端开发者的必备技能,也是安全审计与合规检测的第一步。
可视化演示
展示CSP内容安全策略白名单防XSS、HSTS强制HTTPS与预加载、X-Frame-Options防点击劫持及安全头综合配置评分。
本节配有交互动效(进入视口后自动加载,约 3KB)。
CSP内容安全策略:白名单防XSS 默认拒绝所有资源,仅白名单来源(script-src/style-src/img-src)允许加载 非白名单来源(如eval/内联脚本)被浏览器拦截阻断 CSP: default-src \'self\'; script-src \'self\' cdn.trusted.com CSP白名单机制从浏览器层面防御XSS注入攻击
CSP基础概念
新搬进小区,物业递来一封《访客须知》:“从今天起,任何人想进小区,必须登记身份和来源。快递只认顺丰和京东,外卖只认美团和饿了么,来源不明的车辆一律拦在门外。”你看着这封规定,心想物业是不是有点小题大做——但恰恰是这类“白名单思维”,构成了 CSP 的核心逻辑。
Web 应用每天都面临同样的困扰:一个页面要正常运转,需要加载脚本、图片、样式、字体等大量外部资源,如同小区每天进出形形色色的访客。攻击者精心构造的 XSS 恶意脚本,就像一个冒充快递员混进小区的坏人。CSP(Content Security Policy,内容安全策略)就是浏览器这栋“小区”的物业门卫:服务器通过响应头下发一份“访客白名单”,浏览器在加载每个资源前先问“你从哪儿来?在不在名单上?”
CSP 的实现不复杂。当服务器返回 Content-Security-Policy 响应头时,浏览器立刻进入“白名单模式”:凡是无法匹配来源的资源请求,直接拒绝执行或加载。这意味着即使 XSS 漏洞存在——攻击者成功向页面注入了 <script src="http://evil.com/x.js">——因为 evil.com 不在白名单上,脚本永远无法被执行。
物业这条规定的价值不在于拦住所有坏人,而在于让“混进来”这件事几乎不可能:就算攻击者成功注入了代码,门卫也不认识它。CSP 正是这样的“强制白名单”机制,它把 Web 安全从“攻击者代码能不能运行”变成了“除了白名单,谁都别想运行”。
- Content-Security-PolicyCSP 响应头的名称,是整条规则的“文件头”,浏览器一看到它,就启动白名单模式。
- directive(指令)表示要管哪一类资源,比如
script-src管脚本、img-src管图片、style-src管样式,相当于门卫手册里的“快递员名录”“外卖平台名录”。 - source-list(来源列表)一行白名单,可以写多个来源,用空格分隔,支持域名、URL 前缀、
'self'(本网站自己)等。
CSP指令配置
物业的访客名单不是一本总账,而是分类台账:快递员单独一本、外卖员单独一本、装修队单独一本、维修工单独一本。给快递员只发单元门禁卡,给装修队只发电梯卡——权限最小化,才不会互相添乱。
CSP 的指令体系就是按资源类型分类的台账。最核心的是 default-src,它是“兜底名单”:其他指令没写时,所有资源默认参照这份名单。真正的精细管控靠专项指令:script-src 管脚本加载、img-src 管图片资源、style-src 管样式表、font-src 管字体、connect-src 管 fetch/XHR 等网络连接。如果攻击者想把数据回传到外部服务器,connect-src 会像门卫一样拦住流量。
除了限制资源来源,CSP 还有“通风报信”的指令:report-uri 或 report-to 会让浏览器把每次违规拦截行为上报到指定地址。这相当于门卫发现可疑访客后,不只赶走,还拍照发到物业群里,“让管理员知道有人试图混进来”。
分类台账的好处是“权限最小化”:即使某个资源域被攻破,攻击者也无法借它去执行脚本——因为门卫手里的脚本名录管得死死的。配置 CSP 时,优先精细到每一类资源,而不是只靠 default-src 一把大锁。
- 大并集符号表示整份 CSP 策略等于所有指令条目的组合,缺一条就少一重保护。
- directive\_i第 i 条指令的名字,指定资源的类别,例如
script-src。 - source-list\_i第 i 条指令对应的白名单来源列表,多个来源用空格分隔。
CSP部署实践
物业下发通知有两种渠道:一种是直接投递到每一户的信箱(对应 HTTP 响应头),另一种是贴在每栋楼的大厅公告栏上(对应 HTML 的 meta 标签)。两种方式都能让住户看到规则,但力度完全不同。
生产环境中,服务器在 HTTP 响应中携带 Content-Security-Policy 头是最正规的方式:所有浏览器都支持、可以在服务端统一配置、能配合 CDN 和网关做集中管理。而通过 <meta http-equiv="Content-Security-Policy" content="..."> 写在 HTML 里,适合快速验证或静态页面的场景,但能力有阉割——frame-ancestors、report-uri 等指令在 meta 方式下不生效,且 meta 必须放在 <head> 的靠前位置才有效。
实际部署还要考虑兼容性。老浏览器不认识 CSP 头时会直接忽略,此时可以配合 Content-Security-Policy-Report-Only 头做“只上报不拦截”的灰度验证:先让违规行为暴露出来,确认无误后再切换成强制模式。典型的配置示例是 default-src 'self'; script-src 'self' https://cdn.example.com; img-src 'self' data:,既放行了自己的脚本,也允许从可信 CDN 加载。
类比物业,“公告栏通知”成本低但容易被撕、有盲区;“信箱投递”更规范可靠。把 CSP 放进服务端响应头,就像把门禁规则刻进门禁系统的底层逻辑——每个响应都带上它,不给漏发和篡改的机会。
- HTTP 响应头由服务端通过响应头下发,覆盖全页面所有资源,是生产环境的标准做法。
- HTML meta 标签写在页面源码里,配置简单但指令受限,适合原型验证与静态托管。
HSTS基本机制
物业最严格的一条规矩是:所有访客必须从有保安的正门进入,后门常年锁死。就算有人试图绕到后门递东西,保安也会直接把他带走,并要求他从正门重新进来。这条规矩在 Web 世界里就是 HSTS。
HTTP 是明文传输,数据在网络上裸奔;HTTPS 则像正门,有加密通道。可是很多用户习惯输入 http://example.com,请求一跳就是明文——如果中间有人做“降级攻击”(把 HTTPS 请求改写成 HTTP),用户密码就暴露了。HSTS(HTTP Strict Transport Security,严格传输安全)就是浏览器收到的一份强制规定:“未来一段时间内,访问这个域名只许走 HTTPS 正门,任何 HTTP 请求都在内部直接改写成 HTTPS。”
HSTS 通过 Strict-Transport-Security 响应头实现,核心参数是 max-age。浏览器记录下该域名和有效期,在过期之前,用户就算手动输入 http://,浏览器也会默默换成 https://,根本不会发出明文请求。
有了 HSTS,“后门”(HTTP)就在浏览器内部被堵死了。哪怕用户手滑输入 http://,浏览器也会先替他把地址重写成 https:// 再发送,从源头减少了中间人攻击的可用面。
- Strict-Transport-SecurityHSTS 响应头名称,浏览器识别后开启“严格传输”模式。
- max-age有效期,单位是秒,像门禁卡的“授权时长”。
- T时长数值,通常配置为 31536000(一年)。
HSTS高级特性
正门保安手上还有一份“VIP 住户名单”,上面登记了所有子楼层住户的车牌号——凡是名单上的人,保安都会主动引导他们走正门,连第一次来的客人也不例外。HSTS 的 includeSubDomains 和 preload 就是这类“主动覆盖”的机制。
includeSubDomains 把强制 HTTPS 的范围从主域名扩展到所有子域名。比如 example.com 配了它,blog.example.com、api.example.com 也会被强制走 HTTPS。但这里有个坑:如果某个子域名还没来得及部署 HTTPS,加上这个参数反而会让该子域名无法访问。preload 更进一步:站长可以把域名提交到浏览器的 HSTS 预加载列表(如 Chrome 的 hstspreload.org),浏览器发布时就内置了这份名单,用户第一次访问也直接强制 HTTPS,连“先收一次 HSTS 头”都不需要。
清除 HSTS 不是小事:因为策略存在浏览器本地,服务端单方面取消 max-age 并不能立即生效,用户必须等有效期自然过期,或者手动清理浏览器站点数据。所以配置 HSTS 前的 HTTPS 过渡计划非常重要——先把所有子域名的 HTTPS 部署好,再逐步放开 includeSubDomains 和 preload。
预加载名单相当于把门禁规则“刻进保安的入职培训手册”,比临时通知更可靠。它解决了 HSTS 最大的软肋——第一次访问时的空窗期,让“首次请求就被降级”的攻击难度大幅上升。
- includeSubDomains把强制 HTTPS 覆盖到所有子域名,扩大门禁范围。
- preload允许域名被提交到浏览器内置的 HSTS 预加载列表,首访即生效。
- 分号连接多个 HSTS 属性必须用分号分隔,且
max-age不能缺席,否则整条头无效。
其他安全头
除了大管家 CSP 和 HSTS,物业还有几条“小贴士”式的规定:第一,你家的户型图不允许挂到别人家的展厅里;第二,快递必须按面单分类配送,不能把工业酒精当成饮用水。这两条对应 X-Frame-Options 和 X-Content-Type-Options。
X-Frame-Options 负责防止“点击劫持”:攻击者把一个透明 iframe 覆盖在恶意网站上,诱导用户点击,实际点到了 iframe 里的受害页面按钮上。这就像把你家的户型图挂进别人家的展厅,参观者以为在看地形,其实是在替你按下“转账确认”。X-Frame-Options: DENY 表示任何站点都别想用 frame 嵌入你;SAMEORIGIN 则允许同源页面嵌入,常用于自己后台的嵌套管理界面。
X-Content-Type-Options 则只有 nosniff 一个取值,作用是禁止浏览器“嗅探”(猜)资源类型。正常来说,服务器声明 Content-Type: text/plain,浏览器就该按文本处理;但一些老浏览器会自作主张把内容当 HTML 执行,给攻击者留下上传含恶意脚本的“伪文本文件”的机会。nosniff 相当于强制“按面单配送”,声明什么类型就按什么类型处理。
这两条“小贴士”看似不起眼,却堵住了两类常见攻击:点击劫持和 MIME 型恶意上传。它们配置成本极低,是纵深防御里性价比最高的两个响应头。
- X-Frame-Options限制页面被放入
<iframe>/<frame>的响应头,DIR 防类型。 - DENY 与 SAMEORIGIN
DENY禁止一切嵌套,SAMEORIGIN只允许同源页面嵌套。 - nosniff禁止 MIME 嗅探,强制浏览器按声明的
Content-Type处理响应体。
Referrer-Policy策略
从 A 小区去 B 小区,B 小区门卫会问:“你是从哪儿来的?”有些访客老老实实写下场区、楼栋、单元、门牌号;有些只想写“来自某某小区”。Referrer-Policy 就是管理这张“访客登记簿”的规则。
当页面跳转或加载外部资源时,浏览器会在请求头中携带 Referer 字段,告诉目标站点“我从哪个页面来”。完整 URL 里常常带着敏感信息:https://account.example.com/reset?token=abc123——如果这个链接被带出到第三方站点,token 就泄露了,攻击者可借此完成密码重置。Referrer-Policy 的作用,就是精细控制“登记簿上到底写多少来源信息”。
常用取值里,no-referrer 彻底不写来源,隐私最安全;same-origin 只在同源请求时附带完整来源;strict-origin-when-cross-origin 是同源时带完整 URL,跨源时只带源(协议+域名),降级到 HTTPS 时还能更进一步地不发送来源——这是当前浏览器默认值,平衡了隐私与可用性。origin 则无论何时都只发送源。实践中,strict-origin-when-cross-origin 是最推荐的“默认姿态”。
登记簿写得太详细,访客(用户)的隐私路线图就全暴露了;写得太少,目标站点又无法做来源统计。Referrer-Policy 的哲学是“按需填写”:大多数场景下,只让对方知道大方向,不暴露门牌号,更不暴露口袋里掉出的钥匙(token)。
- 集合运算符表示策略只能取集合中的某个值,不能自定义语法。
- no-referrer登记簿一片空白,任何情况都不发送来源信息。
- strict-origin-when-cross-origin同源发完整 URL,跨源只发源,HTTPS 降级时停发。
OWASP安全实践
成熟的物业公司不会只靠经验,而是有一本《保安手册》,把门禁规则、巡查标准、应急预案全部写成制度。在 Web 安全领域,这本“保安手册”就是 OWASP(开放 Web 应用程序安全项目)发布的各类标准与指南。
OWASP 对安全响应头的建议可以总结为“五件套”清单:CSP 拦恶意资源、HSTS 强制 HTTPS、X-Frame-Options 防点击劫持、X-Content-Type-Options 防 MIME 嗅探、Referrer-Policy 控来源泄露。除了响应头,OWASP 还强调“纵深防御”——安全头只是浏览器层面的第一道墙,必须与输入校验、输出编码、CSRF 防护等手段叠加使用。
把安全头融入开发全流程,是 OWASP 的核心理念。设计阶段就把安全头清单列入接口文档;开发阶段由框架中间件统一注入响应头,避免每个接口手工配置;测试阶段用 curl -I 或 securityheaders.com 等工具批量检查线上站点;上线后持续监控违规上报,关注 CSP 的 report-uri 日志及时调整策略。安全头不再是“发布前补丁”,而是 DevOps 流水线的一环。
《保安手册》真正的价值不是厚,而是“被遵守”。OWASP 给的不是死板的模板,而是一套结合业务取舍的决策框架:配置 CSP 时要平衡功能与安全,部署 HSTS 前要确认 HTTPS 全覆盖。把五件套放进开发流水线,安全响应头才能从“纸面合规”变成“常年值守”。
- H\_secure一组“合格”的安全响应头集合,代表达到安全基线。
- 集合枚举五个成员分别是 CSP、HSTS、X-Frame-Options、X-Content-Type-Options、Referrer-Policy。
- 成员标识每个 h 对应一种响应头,互相独立又协同生效。
AI 应用场景
安全响应头自动化合规审计
阶段:安全评估与合规检查
解决的问题:传统安全审计靠人工逐个请求页面、用浏览器开发者工具翻看响应头,效率低且容易漏检。AI 与自动化脚本结合后,可以批量抓取全站 URL,同步检测 CSP、HSTS、X-Frame-Options 等头的存在性与配置强度,自动生成差距报告。
具体案例:一家金融科技公司在上线新 App 前,用 Python 脚本遍历了 2000 个线上 URL,自动比对 OWASP 清单,发现 30% 的接口缺失 HSTS、15% 的页面 CSP 配置过松。报告直接推送给研发群,一周内全部补齐。
网关层统一注入 HSTS
阶段:架构与部署
解决的问题:多业务线各自维护服务端代码时,很难保证每个应用都正确配置安全响应头。在 Nginx 或 API 网关上做一次统一注入,所有经过网关的响应自动带上 HSTS 头,避免了业务代码的重复修改和遗漏。
具体案例:某电商平台的网关团队在 Nginx 配置中统一添加 Strict-Transport-Security 和 X-Content-Type-Options,使全站 HTTPS 强制率在两周内从 62% 提升到 99.9%,且无需后端应用改动一行代码。
用 CSP 减少 XSS 告警噪音
阶段:安全监测与响应
解决的问题:WAF 每天产生大量 XSS 告警,但很多只是扫描器噪音。通过 CSP 的 report-uri 收集真实浏览器端的违规拦截记录,安全团队可以从中筛选出真正的攻击尝试,并快速定位页面中存在隐患的注入点。
具体案例:某站点接入 CSP Report-Only 模式后,两周内收集到 1200 条违规上报,分析发现 80% 来自第三方插件动态生成的脚本。团队据此为插件单独配置白名单,并将 Report-Only 切换为强制模式,XSS 利用成功率降为零。
Python 演示
import re OWASP_HEADERS = { "Content-Security-Policy": "防止XSS的内容安全策略", "Strict-Transport-Security": "强制HTTPS的严格传输安全", "X-Frame-Options": "防止点击劫持", "X-Content-Type-Options": "防止MIME嗅探", "Referrer-Policy": "控制来源信息泄露",} def parse_headers(raw_headers): """把原始响应头文本解析成字典""" headers = {} for line in raw_headers.strip().splitlines(): if ":" in line: key, value = line.split(":", 1) headers[key.strip().lower()] = value.strip() return headers def audit_security_headers(raw_headers): """按OWASP清单审计安全响应头""" parsed = parse_headers(raw_headers) results = [] for name, desc in OWASP_HEADERS.items(): if name.lower() in parsed: results.append((name, "PASS", "已配置")) else: results.append((name, "FAIL", desc)) return results def build_csp_header(trusted_domains): """生成CSP响应头, 只信任自身和给定域名""" sources = ["'self'"] + trusted_domains return "Content-Security-Policy: default-src " + " ".join(sources) def build_hsts_header(max_age=31536000, include_subdomains=True): """生成HSTS响应头, 默认覆盖子域名""" value = "max-age=" + str(max_age) if include_subdomains: value += "; includeSubDomains" return "Strict-Transport-Security: " + value if __name__ == "__main__": sample = """HTTP/1.1 200 OKContent-Type: text/htmlContent-Security-Policy: default-src 'self' https://cdn.example.comStrict-Transport-Security: max-age=31536000; includeSubDomainsX-Content-Type-Options: nosniff""" print("=== OWASP 安全头审计报告 ===") for name, status, note in audit_security_headers(sample): print("[%s] %s - %s" % (status, name, note)) print() print("=== 按配置生成安全头 ===") print(build_csp_header(["https://cdn.example.com", "https://api.example.com"])) print(build_hsts_header())
headers[key.strip().lower()] = value.strip()响应头不区分大小写,统一转小写存储,方便后续比对。if name.lower() in parsed:OWASP 清单中的标准头名转小写后与解析结果匹配,判断是否已配置。results.append((name, "PASS", "已配置"))审计结果以“头名-状态-说明”三元组收集,方便打印或写入表格。"Content-Security-Policy: default-src " + " ".join(sources)把信任域名拼成 CSP 的来源列表,域名之间用空格分隔。if include_subdomains:按开关决定是否追加includeSubDomains,避免在子域名未准备好 HTTPS 时误伤。
常见误区
误区“我们给全站都加了 CSP,以后 XSS 漏洞都不用管了,前端随便写代码都安全。”
正解CSP 是浏览器层面的“白名单大门”,它能拦截外联脚本、eval 执行、data: 协议等大量注入向量,但并不能替代输出编码。反射型 XSS 如果借助内联事件处理器(如 <img onerror=...>)注入,且策略没有用 nonce 或 hash 精细管控内联脚本时,依然可能被利用。CSP 的本质是“兜底闸门”,不是“免写安全代码”的许可证。
为何常见:人们容易把“风险大大降低”误解为“风险完全消失”,尤其当安全团队演示 CSP 拦下了几个典型 payload 后,很容易产生“一劳永逸”的错觉。
误区“只要我配好了 `Strict-Transport-Security` 头,所有用户从第一次访问开始就强制 HTTPS。”
正解HSTS 是“浏览器收到响应头之后”才开始生效的策略。如果用户第一次访问时就被中间人劫持并降级成 HTTP,服务器根本发不出带 HSTS 头的 HTTPS 响应,策略也就无从建立。解决这个空窗期的办法是把域名提交到浏览器的 HSTS 预加载列表(preload),让浏览器在首次访问前就知道“这个域名必须走 HTTPS”。
为何常见:很多人把配置生效理解为“服务端一返回,客户端立刻执行”,忽略了“客户端得先安全地收到这条指令”这一前提。
误区“把 CSP、HSTS、X-Frame-Options、各种安全头全加上,配置越满越安全。”
正解安全头存在明显的“副作用权衡”。例如 CSP 配置过严会把第三方分析和合法 CDN 脚本全部拦掉,导致线上功能挂掉;includeSubDomains 加在未完成 HTTPS 覆盖的域名上,会让子域名直接无法访问;X-Frame-Options 的 SAMEORIGIN 也会影响合法的跨域嵌入场景。安全头的正确打开方式是“按业务场景裁剪 + 灰度验证”,而不是无脑堆叠。
为何常见:合规清单驱动的部署方式让人倾向于“全选”,忽略了每条策略背后的可用性成本和迭代成本。
误区“我在 HTTP 和 HTTPS 响应里都加上 HSTS 头,用户走 HTTP 也能收到强制 HTTPS 的指令。”
正解这是一个半对半错的经典误区。HSTS 头确实可以在 HTTP 响应中传输,但浏览器规范明确要求浏览器只接受通过安全连接(HTTPS)收到的 HSTS 头。如果攻击者能劫持 HTTP 连接,他同样可以剥掉 HSTS 头或注入一个 max-age=0 的 HSTS 头来清除策略。因此,HSTS 的部署前提是站点自身必须稳定提供 HTTPS。
为何常见:人们常把“服务器发出什么”与“浏览器接受什么”混为一谈,忽略了浏览器对安全和加密连接的信任边界。
误区“Referrer-Policy 就是个控制流量统计来源的分析工具,改不改不影响安全。”
正解来源信息泄露是真实攻击面。如果一个带 token 的重置密码链接被作为 Referer 发送给第三方 CDN 或广告联盟,token 就可能泄露,导致账号被接管。strict-origin-when-cross-origin 这类策略正是为了在跨源场景下只暴露源、不暴露完整路径,尤其是防止从 HTTPS 页面降级到 HTTP 时把敏感 URL 带出去。
为何常见:Referrer-Policy 经常被归类为“SEO/分析优化项”,多数教程也只讲它“告诉别人你来自哪里”,很少强调它携带的完整 URL 可能包含敏感参数。
面试题
Q1. CSP(内容安全策略)最主要用于防御以下哪类攻击?
- A.SQL 注入
- B.XSS 跨站脚本← 正确答案
- C.CSRF 跨站请求伪造
- D.DDoS 分布式拒绝服务
答案:B。CSP 通过白名单机制控制浏览器只加载可信来源的脚本与资源,直接阻断恶意脚本的注入与执行,核心目标是防御 XSS。SQL 注入发生在服务端数据库层,CSRF 靠 token 与 SameSite 应对,DDoS 属于流量层攻击,都与 CSP 的防护范围不同,类比门卫只负责检查访客名单,不负责抓小偷。
Q2. 下列哪个 CSP 指令用于限制 JavaScript 脚本的来源?
- A.img-src
- B.style-src
- C.script-src← 正确答案
- D.font-src
答案:C。script-src 专门管脚本资源的来源,是 CSP 中防 XSS 最关键的指令。img-src 管图片、style-src 管样式表、font-src 管字体,它们各有分工,如同物业台账里快递员、外卖员、装修队各记一本。
Q3. X-Frame-Options: DENY 的作用是什么?
- A.允许同源页面用 iframe 嵌入
- B.禁止任何页面用 frame 嵌入当前页面← 正确答案
- C.仅允许 HTTPS 页面嵌入
- D.允许所有域名嵌入但提示警告
答案:B。DENY 表示无论同源还是跨源,全都不允许用 <frame> 或 <iframe> 嵌入当前页面,用于彻底防止点击劫持。SAMEORIGIN 才允许同源嵌入,而“仅允许 HTTPS”不是该头的取值。
Q4. HSTS 响应头 Strict-Transport-Security: max-age=31536000 中,max-age 的作用是什么?
- A.HTTPS 证书的有效期
- B.浏览器强制使用 HTTPS 的时长← 正确答案
- C.DNS 缓存的刷新周期
- D.Cookie 的过期时间
答案:B。max-age 以秒为单位指定 HSTS 策略的有效期,浏览器在这段时间内将域名的 HTTP 请求自动改写成 HTTPS。它不是证书有效期也不是 Cookie 时间,而是“门禁卡在浏览器手里的授权时长”。
Q5. 以下哪些方式可以部署 CSP 策略?
- A.HTTP 响应头
Content-Security-Policy← 正确答案 - B.HTML 中的
<meta http-equiv="Content-Security-Policy">← 正确答案 - C.DNS 的 TXT 记录
- D.服务器端 session 配置
答案:AB。CSP 只支持 HTTP 响应头和 HTML meta 标签两种部署渠道。meta 方式存在指令限制(如 frame-ancestors 无效),但依然可用;DNS TXT 记录和 session 配置与 CSP 完全无关,浏览器根本不读取这些位置。
Q6. HSTS 头通过什么协议传输给浏览器才会被信任?
- A.HTTP
- B.HTTPS← 正确答案
- C.FTP
- D.WebSocket
答案:B。浏览器规范要求只接受通过安全连接收到的 HSTS 头。如果通过明文 HTTP 传输,中间人可以把 HSTS 头剥离或改写成 max-age=0 来禁用策略,因此 HSTS 的部署前提是站点必须稳定提供 HTTPS。
Q7. 下列哪些值属于 Referrer-Policy 的合法取值?
- A.no-referrer← 正确答案
- B.same-origin← 正确答案
- C.strict-origin-when-cross-origin← 正确答案
- D.default-src
答案:ABC。no-referrer、same-origin、strict-origin-when-cross-origin 都是 Referrer-Policy 的标准取值,分别对应“不发送来源”“仅同源发送”“同源发完整 URL、跨源只发源”等策略。default-src 是 CSP 的指令名,两者分属不同机制,如同“门卫登记规则”和“访客分类台账”不是一回事。
Q8. 以下哪个响应头专门用于防止浏览器 MIME 嗅探?
- A.X-Frame-Options: SAMEORIGIN
- B.X-Content-Type-Options: nosniff← 正确答案
- C.Strict-Transport-Security: max-age=31536000
- D.Referrer-Policy: no-referrer
答案:B。X-Content-Type-Options: nosniff 强制浏览器按服务器声明的 Content-Type 处理响应体,禁止猜测内容类型,从而防止攻击者上传“伪装成文本的 HTML”。这就像快递按面单分类配送,不能把工业酒精当饮用水。
Q9. 某域名已提交 HSTS 预加载列表,以下说法正确的是?
- A.用户首次访问也必须走 HTTPS,即使从未收到过 HSTS 头← 正确答案
- B.预加载可以替代 HTTPS 证书的部署
- C.预加载后 HSTS 头不再需要设置 max-age
- D.预加载列表只能由企业申请,个人域名不可提交
答案:A。预加载会把域名写进浏览器内置列表,用户在第一次访问前就知道该域名必须走 HTTPS,解决了 HSTS 的“首访空窗期”。但它不能替代证书部署,服务器仍要正常返回 HSTS 头和有效证书;预加载要求站点满足完整的 HSTS 配置条件才会被接受。
Q10. 关于 Content-Security-Policy: script-src 'self' 的配置,以下说法正确的是?
- A.页面可以加载并执行本站域名下的脚本← 正确答案
- B.页面内联的
<script>代码默认也会被阻止← 正确答案 - C.所有 CDN 脚本都会被阻止← 正确答案
- D.
eval()函数的执行不受影响
答案:ABC。'self' 只放行同源脚本,内联 <script> 与 CDN 脚本都不在白名单中,eval() 也会被 CSP 默认阻止。这个配置非常严格,能阻挡大多数 XSS 注入,但如果有合法的内联脚本或 CDN 依赖,需要额外用 nonce、hash 或补充白名单来放行。