web安全基础
Web 安全的核心是围绕 “如何保护用户数据与服务端资源” 构建的防御体系,而同源策略、CORS、XSS、CSRF 及 Cookie 安全设置是其中最基础且关键的模块。以下将按 “基础安全策略→跨域机制→攻击手段→防御配置” 的逻辑,从概念定义、核心作用、关联场景三个层级,拆解各模块的核心信息,并明确漏洞职责与执行环境。
第一部分:基础安全基石 —— 同源策略(Same-Origin Policy, SOP)
同源策略是浏览器的默认安全 “防火墙”,是所有 Web 安全机制的基础,其核心目的是 “隔离不同站点的资源,防止恶意站点非法访问合法站点的数据”。
1. 概念与定义
- 同源的判定标准:两个 URL 需同时满足以下 3 个条件,才被视为 “同源”:
- 协议相同(如均为
http或均为https); - 域名相同(如均为
www.example.com,blog.example.com与www.example.com不同源); - 端口相同(如均为 80 端口或均为 443 端口,默认端口可省略)。
- 协议相同(如均为
- 核心规则:浏览器仅允许 “同源” 的页面 / 脚本,读取或操作另一个同源页面的资源(如 Cookie、LocalStorage、DOM 元素、AJAX 响应数据);非同源资源默认被 “隔离”,无法直接访问。
2. 核心作用与场景
- 保护目标:用户的敏感数据(如登录状态、个人信息)和服务端资源。
- 典型场景:
- 你在
www.baidu.com打开的页面,无法通过脚本读取www.taobao.com的 Cookie(否则会直接窃取淘宝登录状态); - 本地
file://协议打开的 HTML 文件,无法通过 AJAX 请求http://localhost的服务端数据(协议不同源)。
- 你在
3. 职责与执行环境
- 执行环境:仅在浏览器端生效(服务端无同源策略限制,需自行做跨域权限控制)。
- 漏洞关联:同源策略本身是 “防御机制”,无 “漏洞” 属性;但后续的 CSRF 攻击,本质是利用了 “浏览器自动携带同源 Cookie” 这一同源策略的 “特性”(非漏洞),间接绕过身份验证。
第二部分:跨域解决方案 ——CORS(Cross-Origin Resource Sharing)
同源策略虽安全,但无法满足 “合法跨域需求”(如前端项目部署在frontend.example.com,需请求api.example.com的接口)。CORS 是服务端授权、浏览器执行的跨域资源共享机制,用于 “在安全前提下开放跨域权限”。
1. 概念与定义
核心逻辑:当浏览器发起 “非同源” 请求时,会先检查服务端返回的
Access-Control-*响应头,若头信息允许当前源的跨域请求,则浏览器放行响应数据;否则拦截数据,抛出跨域错误。关键响应头(服务端配置):
响应头 作用说明 Access-Control-Allow-Origin允许跨域的源(如 https://frontend.example.com,*表示允许所有源,不推荐)Access-Control-Allow-Methods允许跨域的 HTTP 方法(如 GET, POST, PUT)Access-Control-Allow-Credentials是否允许跨域请求携带 Cookie(需设为 true,且Allow-Origin不能为*)Access-Control-Allow-Headers允许跨域请求携带的自定义请求头(如 Content-Type, Token)
2. 跨域请求执行流程
浏览器发起请求:若为 “简单请求”(如
GET/POST,请求头无自定义字段),直接发送请求;若为 “复杂请求”(如PUT/DELETE、带自定义头),先发送预检请求(OPTIONS),询问服务端是否允许跨域。服务端响应:返回业务数据的同时,附带
Access-Control-*头。浏览器过滤:根据 “同源策略 + 服务端 CORS 头” 判断:
若 CORS 头允许当前源,则放行数据,前端可正常使用;
若 CORS 头不允许或未配置,则拦截数据,前端控制台报错 “Access to XMLHttpRequest at … from origin … has been blocked by CORS policy”。
3. 职责与执行环境
- 执行环境:服务端配置 + 浏览器执行(服务端负责 “授权”,浏览器负责 “校验与放行 / 拦截”)。
- 漏洞职责:若服务端错误配置 CORS(如
Allow-Origin设为*且开启Allow-Credentials),可能导致 “恶意站点跨域获取敏感数据”,属于服务端配置漏洞。
第三部分:前端注入攻击 ——XSS(Cross-Site Scripting)
XSS 是最常见的 Web 攻击之一,本质是 “攻击者将恶意 JavaScript 脚本注入到目标站点的页面中,由浏览器执行脚本,窃取用户数据或控制页面”。其核心是 “用户输入未被过滤,直接被页面渲染执行”。
1. 概念与定义
- 核心逻辑:目标站点(前端 / 后端)未对用户输入的内容(如评论、URL 参数、表单数据)做 “转义处理”,导致攻击者输入的
<script>等恶意代码,被页面 “原封不动” 地渲染并执行。 - 攻击目标:用户的浏览器环境(脚本在用户本地执行,而非服务端),最终目的是窃取用户敏感数据(如 Cookie、SessionID、账号密码)或执行恶意操作(如伪造用户点击、跳转钓鱼网站)。
2. 三大类型:按漏洞位置与存储方式划分
不同类型的 XSS,其漏洞职责(前端 / 后端)、执行场景完全不同,具体对比如下:
| 类型 | 概念定义 | 漏洞职责 | 执行环境 | 典型场景 |
|---|---|---|---|---|
| DOM 型 XSS | 漏洞仅存在于前端代码,因前端直接使用document.write、innerHTML等 API,将未过滤的用户输入(如 URL 参数、LocalStorage 数据)插入 DOM,导致脚本执行。 |
前端 | 用户浏览器 | 前端页面通过location.hash获取 URL 中的#后面的参数,直接用innerHTML插入页面,攻击者构造http://example.com/#<script>窃取Cookie</script>,用户点击后脚本执行。 |
| 反射型 XSS | 漏洞存在于后端代码,后端将未过滤的用户输入(如 URL 参数、表单提交内容)直接 “反射” 到 HTML 响应中,浏览器渲染时执行脚本。 | 后端 | 用户浏览器 | 搜索功能:后端接收?keyword=xxx,直接在页面中输出 “搜索结果:xxx”,攻击者构造?keyword=<script>窃取Cookie</script>,用户点击该链接后,后端返回的页面包含恶意脚本,浏览器执行。 |
| 存储型 XSS | 漏洞存在于后端代码,后端将未过滤的用户输入(如评论、留言、头像 URL)存储到数据库,其他用户访问该页面时,后端从数据库读取并输出恶意脚本,浏览器执行。 | 后端 | 所有访问该页面的用户浏览器 | 论坛评论:攻击者发布包含<script>窃取Cookie</script>的评论,后端存储到数据库,其他用户打开该评论页面时,后端将恶意脚本返回,所有用户的浏览器都会执行脚本,批量窃取 Cookie。 |
3. 核心危害:Cookie 劫持
XSS 的主要危害是 “Cookie 劫持”,流程如下:
- 攻击者通过 XSS 注入恶意脚本(如
<script>var cookie=document.cookie; 发送到攻击者服务器</script>); - 用户访问被注入的页面,脚本在用户浏览器执行,读取当前站点的 Cookie(包含登录状态);
- 脚本通过 AJAX 或图片请求,将 Cookie 发送到攻击者的服务器;
- 攻击者拿到 Cookie 后,可伪装成该用户登录目标站点,获取个人信息或执行敏感操作(如转账、改密码)。
第四部分:身份伪造攻击 ——CSRF(Cross-Site Request Forgery,跨站请求伪造)
CSRF 与 XSS 完全不同,其本质是 “利用浏览器自动携带同源 Cookie 的特性,伪造用户身份,在目标站点执行敏感操作”,核心是 “伪造操作而非窃取数据”。
1. 概念与定义
- 核心逻辑:攻击者构造一个 “目标站点的敏感操作请求”(如转账、改密码、发布评论),诱导用户在 “已登录目标站点” 的情况下,访问攻击者的页面或点击链接,浏览器会自动携带目标站点的 Cookie(因 Cookie 与目标站点同源),从而让服务端误以为是用户本人发起的操作,执行请求。
- 关键前提:用户必须已登录目标站点(浏览器中存在目标站点的登录 Cookie),否则无法伪造身份。
2. 攻击目标与执行流程
- 攻击目标:服务端的敏感操作(如转账、修改个人信息),而非用户的 Cookie 数据(CSRF 不直接获取 Cookie,仅利用 Cookie 自动携带的特性)。
- 执行流程(以 “转账” 为例):
- 用户登录
www.bank.com(银行站点),浏览器保存银行的登录 Cookie; - 用户未退出银行登录,误点击攻击者的钓鱼链接
http://attacker.com/evil.html; evil.html中隐藏一个表单或 AJAX 请求,指向银行的转账接口:http://www.bank.com/transfer?to=攻击者账号&money=1000;- 浏览器发起该请求时,自动携带
www.bank.com的 Cookie(同源特性); - 银行服务端验证 Cookie 有效,误以为是用户本人操作,执行转账。
- 用户登录
3. 与 XSS 的核心区别
| 对比维度 | XSS(跨站脚本) | CSRF(跨站请求伪造) |
|---|---|---|
| 核心目的 | 窃取用户数据(如 Cookie) | 伪造用户执行敏感操作(如转账) |
| 脚本执行位置 | 目标站点的页面中 | 攻击者的页面中 |
| 是否依赖 Cookie | 是(最终目的是窃取 Cookie) | 是(利用 Cookie 自动携带特性) |
| 漏洞职责 | DOM 型(前端)、反射 / 存储型(后端) | 后端(未验证请求来源) |
第五部分:Cookie 安全配置 —— 防御 XSS 与 CSRF 的关键
Cookie 是用户登录状态的核心载体,XSS 和 CSRF 的攻击均与 Cookie 相关。通过配置 Cookie 的安全属性,可直接降低攻击风险。
1. 三大安全属性详解
| 属性 | 作用说明 | 防御目标 | 配置示例 |
|---|---|---|---|
| HttpOnly | 禁止浏览器的 JavaScript 脚本读取 Cookie(document.cookie无法获取),仅允许浏览器在请求时自动携带。 |
XSS 攻击(无法通过脚本窃取 Cookie) | Set-Cookie: sessionId=xxx; HttpOnly |
| SameSite | 限制 Cookie 仅在 “同源请求” 或 “第一方请求” 中携带,禁止第三方站点(如攻击者页面)的请求携带。 | CSRF 攻击(第三方请求无法携带 Cookie) | Set-Cookie: sessionId=xxx; SameSite=Strict(仅同源请求携带)或SameSite=Lax(部分跨站请求允许,如链接跳转) |
| Secure | 仅允许 Cookie 在HTTPS 协议的请求中携带,HTTP 协议的请求会自动忽略该 Cookie。 | 防止 Cookie 在 HTTP 传输中被窃听(如中间人攻击) | Set-Cookie: sessionId=xxx; Secure |
2. 配置建议(组合使用)
生产环境中,应至少组合配置以下 3 个属性,最大化 Cookie 安全性:
1 | Set-Cookie: sessionId=abc123; HttpOnly; SameSite=Strict; Secure; Path=/; Domain=example.com |
Path=/:限制 Cookie 仅在example.com/及其子路径下生效;Domain=example.com:限制 Cookie 仅在example.com及其子域名(如blog.example.com)下生效。
第六部分:CSRF 终极防御 ——CSRF Token
CSRF 攻击的核心漏洞是服务端仅通过 Cookie 验证用户身份,未验证请求的真实来源。而 CSRF Token 是专门针对这一漏洞的后端防御机制,其核心逻辑是 “为每个合法请求绑定一个唯一的、不可预测的令牌,服务端同时验证 Cookie 与 Token,缺一不可”。
1. 概念与定义
- CSRF Token:是服务端生成的一串随机、唯一、一次性的字符串,用于标识 “当前请求是用户主动在目标站点发起的,而非第三方站点伪造的”。
- 核心原理:
- 服务端为每个已登录用户的会话(Session)生成一个唯一的 CSRF Token,并存储在服务端(如 Session 中);
- 目标站点的所有敏感操作表单(如转账、改密码),都会在页面渲染时,将 CSRF Token 以隐藏字段、请求头、URL 参数的形式嵌入;
- 用户提交表单时,浏览器会同时发送Cookie(身份验证) 和 CSRF Token(请求合法性验证);
- 服务端接收到请求后,不仅验证 Cookie 的有效性,还会验证请求中的 Token 是否与服务端存储的 Token 一致;
- 若 Token 一致,则认为是合法请求,执行操作;若 Token 不一致或缺失,则拒绝请求。
2. 攻击防御逻辑
CSRF 攻击无法绕过 CSRF Token 验证,原因如下:
- 攻击者的第三方站点无法获取目标站点的 CSRF Token(同源策略限制:第三方站点的脚本无法读取目标站点页面中的 Token,也无法通过 AJAX 请求获取 Token);
- 攻击者无法伪造有效的 CSRF Token(Token 是随机生成的,且与用户会话绑定,攻击者无法预测);
- 即使攻击者诱导用户提交请求,也只能携带 Cookie,无法携带有效的 Token,服务端会直接拒绝。
3. 实现方式与场景
| 实现方式 | 概念说明 | 适用场景 | 优缺点 |
|---|---|---|---|
| 表单隐藏字段 | 服务端在表单中嵌入 <input type="hidden" name="csrfToken" value="xxx">,用户提交表单时,Token 随表单数据一起发送。 |
传统表单提交(POST 请求) | 优点:实现简单,兼容性好;缺点:仅适用于表单提交,无法用于 AJAX 请求。 |
| 请求头携带 | 服务端在页面中渲染 Token(如存储在 meta 标签中),前端 AJAX 请求时,从 meta 标签中读取 Token,添加到自定义请求头(如 X-CSRF-Token: xxx)中发送。 |
现代 AJAX 请求(GET/POST/PUT/DELETE) | 优点:适用于所有请求类型,安全性更高(不易被第三方站点伪造);缺点:需要前端配合处理请求头。 |
| URL 参数携带 | 服务端在敏感操作的 URL 中添加 Token 参数(如 http://example.com/transfer?csrfToken=xxx&to=xxx&money=xxx)。 |
简单的 GET 请求(不推荐用于敏感操作) | 优点:实现简单;缺点:Token 会出现在 URL 中,可能被日志记录,安全性较低,不推荐用于转账、改密码等敏感操作。 |
4. 职责与执行环境
- 执行环境:服务端生成 + 前端携带 + 服务端验证(全链路后端主导)。
- 漏洞职责:若服务端未实现 CSRF Token 验证,或实现不当(如 Token 重复使用、与用户会话不绑定、未验证 Token),则属于服务端漏洞;若前端未正确携带 Token(如 AJAX 请求忘记添加 Token 头),则属于前端配置漏洞,但不会导致 CSRF 攻击,仅会导致合法请求被拒绝。
5. 与 SameSite Cookie 的配合
CSRF Token 与 SameSite Cookie 是互补的防御手段,生产环境中建议同时使用:
SameSiteCookie 是浏览器端的防御,可阻止第三方站点的请求携带 Cookie,是第一道防线;- CSRF Token 是服务端的防御,即使
SameSiteCookie 被绕过(如部分老旧浏览器不支持SameSite属性),也能有效防御 CSRF 攻击,是第二道防线。
第七部分:XSS 终极防御 —— 输出过滤(Input Validation & Output Escaping)
XSS 攻击的核心漏洞是用户输入的恶意代码未被过滤,直接被页面渲染执行。输出过滤是针对这一漏洞的核心防御机制,其核心逻辑是 “对所有用户输入进行严格的验证,对所有输出到页面的内容进行适当的转义,确保恶意代码被当作普通文本处理,而非可执行的脚本”。
1. 概念与定义
输出过滤包含两个核心环节,二者缺一不可:
- 输入验证(Input Validation):在数据进入系统时(前端提交→后端接收),对用户输入的内容进行格式、长度、内容的验证,拒绝不符合规则的输入。例如:手机号必须是 11 位数字,邮箱必须符合邮箱格式,评论内容不能包含特殊标签等。
- 输出转义(Output Escaping):在数据输出到页面时(后端渲染→前端展示),对要输出的内容进行转义处理,将特殊字符(如
<、>、"、'、&)转换为 HTML 实体,使得浏览器将其当作普通文本渲染,而非可执行的 HTML 或 JavaScript 代码。
2. 核心转义规则
HTML 中最常用的特殊字符转义规则如下,这是防御 XSS 的基础:
| 原始字符 | HTML 实体 | 作用说明 |
|---|---|---|
< |
< |
小于号,转义后不会被识别为 HTML 标签的开始(如 <script> 会被转义为 <script>)。 |
> |
> |
大于号,转义后不会被识别为 HTML 标签的结束。 |
" |
" |
双引号,转义后不会被识别为 HTML 属性的引号(如 onclick="alert(1)" 会被转义为 onclick="alert(1)")。 |
' |
' |
单引号,转义后不会被识别为 HTML 属性的单引号。 |
& |
& |
和号,转义后不会被识别为 HTML 实体的开始。 |
示例:
- 攻击者输入的恶意代码:
<script>alert('XSS')</script> - 经过输出转义后:
<script>alert('XSS')</script> - 浏览器渲染时,会显示为普通文本
<script>alert('XSS')</script>,而不会执行脚本。
3. 按 XSS 类型的防御策略
输出过滤需要根据不同类型的 XSS 漏洞,采取不同的防御策略,明确前端与后端的职责:
(1)存储型 & 反射型 XSS(后端漏洞)—— 后端主导过滤
这两种 XSS 的漏洞都在后端,因此防御的核心是后端,前端仅作为辅助验证。
- 防御策略:
- 后端输入验证:接收用户输入时,严格验证输入的格式、内容,拒绝包含恶意标签(如
<script>、<iframe>)、恶意事件(如onclick、onload)的输入; - 后端输出转义:将数据输出到 HTML 页面时,对所有用户输入的内容进行 HTML 转义处理;
- 前端辅助验证:在用户提交数据前,前端先进行一次输入验证(如表单验证),可以减少无效请求,但不能替代后端验证(攻击者可以绕过前端验证,直接向后端发送恶意请求)。
- 后端输入验证:接收用户输入时,严格验证输入的格式、内容,拒绝包含恶意标签(如
- 典型场景:论坛评论、搜索结果、用户昵称展示等,后端必须在输出时进行转义。
(2)DOM 型 XSS(前端漏洞)—— 前端主导过滤
DOM 型 XSS 的漏洞在前端,因此防御的核心是前端。
- 防御策略:
- 前端输入验证:对从 URL 参数、LocalStorage、DOM 中获取的用户输入,进行严格的验证;
- 前端输出转义:
- 避免使用危险的 DOM API:如
document.write、innerHTML、outerHTML,这些 API 会直接将内容作为 HTML 渲染,容易导致 XSS; - 使用安全的 DOM API:如
textContent,该 API 会将内容作为普通文本渲染,自动忽略所有 HTML 标签,不会执行脚本; - 若必须使用
innerHTML,则需要对输入的内容进行手动转义,将特殊字符转换为 HTML 实体。
- 避免使用危险的 DOM API:如
- 典型场景:前端通过
location.hash获取 URL 参数,然后插入到页面中,应使用textContent而非innerHTML。
4. 进阶防御:内容安全策略(CSP)
输出过滤是 XSS 的基础防御,而内容安全策略(Content Security Policy,CSP) 是进阶的补充防御手段,其核心逻辑是 “浏览器通过服务端下发的 CSP 头,限制页面可以加载的资源(如脚本、样式、图片)的来源,禁止执行内联脚本和 eval 函数,从而从根本上阻止 XSS 脚本的执行”。
核心作用:即使输出过滤被绕过,攻击者注入了恶意脚本,CSP 也能阻止脚本的执行。
配置方式:服务端通过响应头
Content-Security-Policy配置,例如:1
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self'; img-src 'self' data:;
该配置的含义是:
default-src 'self':默认情况下,仅允许加载同源的资源;script-src 'self' https://cdn.example.com:仅允许加载同源的脚本,以及https://cdn.example.com域名下的脚本;style-src 'self':仅允许加载同源的样式;img-src 'self' data::仅允许加载同源的图片,以及 base64 格式的图片。
5. 职责与执行环境
| 防御环节 | 执行环境 | 漏洞职责 | 核心要求 |
|---|---|---|---|
| 输入验证 | 前端 + 后端 | 前端(辅助)+ 后端(核心) | 后端必须进行输入验证,前端仅作为辅助,不能替代后端。 |
| 输出转义 | 前端 + 后端 | 反射 / 存储型(后端)+ DOM 型(前端) | 后端负责输出到 HTML 页面的转义,前端负责 DOM 操作的转义。 |
| 内容安全策略(CSP) | 服务端配置 + 浏览器执行 | 服务端 | 服务端负责配置合理的 CSP 头,浏览器负责执行 CSP 规则。 |
总结:Web 安全核心逻辑链
- 防御基础:同源策略隔离非同源资源,CORS 在安全前提下开放跨域权限;
- 主要攻击:
- XSS:注入脚本到目标站点,窃取 Cookie(前端 / 后端漏洞);
- CSRF:利用 Cookie 自动携带特性,伪造用户操作(后端漏洞);
- 关键防御:Cookie 的
HttpOnly(防 XSS)、SameSite(防 CSRF)、Secure(防窃听)配置,从载体层面阻断攻击。 - CSRF 防御:以 CSRF Token 为核心(服务端终极防御),配合 SameSite Cookie(浏览器端第一道防线),实现双重防御,彻底阻断身份伪造攻击;
- XSS 防御:以 输出过滤(输入验证 + 输出转义) 为核心(基础防御),配合 内容安全策略(CSP)(进阶补充防御),实现从 “源头过滤” 到 “执行阻断” 的全链路防御,彻底阻断脚本注入攻击;
- 职责划分:
- CSRF 防御的核心职责在后端;
- XSS 防御的核心职责:反射型 / 存储型在后端,DOM 型在前端。

