web安全基础

Web 安全的核心是围绕 “如何保护用户数据与服务端资源” 构建的防御体系,而同源策略、CORS、XSS、CSRF 及 Cookie 安全设置是其中最基础且关键的模块。以下将按 “基础安全策略→跨域机制→攻击手段→防御配置” 的逻辑,从概念定义、核心作用、关联场景三个层级,拆解各模块的核心信息,并明确漏洞职责与执行环境。

第一部分:基础安全基石 —— 同源策略(Same-Origin Policy, SOP)

同源策略是浏览器的默认安全 “防火墙”,是所有 Web 安全机制的基础,其核心目的是 “隔离不同站点的资源,防止恶意站点非法访问合法站点的数据”。

1. 概念与定义

  • 同源的判定标准:两个 URL 需同时满足以下 3 个条件,才被视为 “同源”:
    1. 协议相同(如均为http或均为https);
    2. 域名相同(如均为www.example.comblog.example.comwww.example.com不同源);
    3. 端口相同(如均为 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. 跨域请求执行流程

  1. 浏览器发起请求:若为 “简单请求”(如GET/POST,请求头无自定义字段),直接发送请求;若为 “复杂请求”(如PUT/DELETE、带自定义头),先发送预检请求(OPTIONS),询问服务端是否允许跨域。

  2. 服务端响应:返回业务数据的同时,附带Access-Control-*头。

  3. 浏览器过滤:根据 “同源策略 + 服务端 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.writeinnerHTML等 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 劫持”,流程如下:

  1. 攻击者通过 XSS 注入恶意脚本(如<script>var cookie=document.cookie; 发送到攻击者服务器</script>);
  2. 用户访问被注入的页面,脚本在用户浏览器执行,读取当前站点的 Cookie(包含登录状态);
  3. 脚本通过 AJAX 或图片请求,将 Cookie 发送到攻击者的服务器;
  4. 攻击者拿到 Cookie 后,可伪装成该用户登录目标站点,获取个人信息或执行敏感操作(如转账、改密码)。

第四部分:身份伪造攻击 ——CSRF(Cross-Site Request Forgery,跨站请求伪造)

CSRF 与 XSS 完全不同,其本质是 “利用浏览器自动携带同源 Cookie 的特性,伪造用户身份,在目标站点执行敏感操作”,核心是 “伪造操作而非窃取数据”。

1. 概念与定义

  • 核心逻辑:攻击者构造一个 “目标站点的敏感操作请求”(如转账、改密码、发布评论),诱导用户在 “已登录目标站点” 的情况下,访问攻击者的页面或点击链接,浏览器会自动携带目标站点的 Cookie(因 Cookie 与目标站点同源),从而让服务端误以为是用户本人发起的操作,执行请求。
  • 关键前提:用户必须已登录目标站点(浏览器中存在目标站点的登录 Cookie),否则无法伪造身份。

2. 攻击目标与执行流程

  • 攻击目标服务端的敏感操作(如转账、修改个人信息),而非用户的 Cookie 数据(CSRF 不直接获取 Cookie,仅利用 Cookie 自动携带的特性)。
  • 执行流程(以 “转账” 为例)
    1. 用户登录www.bank.com(银行站点),浏览器保存银行的登录 Cookie;
    2. 用户未退出银行登录,误点击攻击者的钓鱼链接http://attacker.com/evil.html
    3. evil.html中隐藏一个表单或 AJAX 请求,指向银行的转账接口:http://www.bank.com/transfer?to=攻击者账号&money=1000
    4. 浏览器发起该请求时,自动携带www.bank.com的 Cookie(同源特性);
    5. 银行服务端验证 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:是服务端生成的一串随机、唯一、一次性的字符串,用于标识 “当前请求是用户主动在目标站点发起的,而非第三方站点伪造的”。
  • 核心原理
    1. 服务端为每个已登录用户的会话(Session)生成一个唯一的 CSRF Token,并存储在服务端(如 Session 中);
    2. 目标站点的所有敏感操作表单(如转账、改密码),都会在页面渲染时,将 CSRF Token 以隐藏字段、请求头、URL 参数的形式嵌入;
    3. 用户提交表单时,浏览器会同时发送Cookie(身份验证)CSRF Token(请求合法性验证)
    4. 服务端接收到请求后,不仅验证 Cookie 的有效性,还会验证请求中的 Token 是否与服务端存储的 Token 一致;
    5. 若 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 攻击,仅会导致合法请求被拒绝。

CSRF Token 与 SameSite Cookie 是互补的防御手段,生产环境中建议同时使用

  • SameSite Cookie 是浏览器端的防御,可阻止第三方站点的请求携带 Cookie,是第一道防线;
  • CSRF Token 是服务端的防御,即使 SameSite Cookie 被绕过(如部分老旧浏览器不支持 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 的漏洞都在后端,因此防御的核心是后端,前端仅作为辅助验证。

  • 防御策略
    1. 后端输入验证:接收用户输入时,严格验证输入的格式、内容,拒绝包含恶意标签(如 <script><iframe>)、恶意事件(如 onclickonload)的输入;
    2. 后端输出转义:将数据输出到 HTML 页面时,对所有用户输入的内容进行 HTML 转义处理;
    3. 前端辅助验证:在用户提交数据前,前端先进行一次输入验证(如表单验证),可以减少无效请求,但不能替代后端验证(攻击者可以绕过前端验证,直接向后端发送恶意请求)。
  • 典型场景:论坛评论、搜索结果、用户昵称展示等,后端必须在输出时进行转义。

(2)DOM 型 XSS(前端漏洞)—— 前端主导过滤

DOM 型 XSS 的漏洞在前端,因此防御的核心是前端

  • 防御策略
    1. 前端输入验证:对从 URL 参数、LocalStorage、DOM 中获取的用户输入,进行严格的验证;
    2. 前端输出转义
      • 避免使用危险的 DOM API:如 document.writeinnerHTMLouterHTML,这些 API 会直接将内容作为 HTML 渲染,容易导致 XSS;
      • 使用安全的 DOM API:如 textContent,该 API 会将内容作为普通文本渲染,自动忽略所有 HTML 标签,不会执行脚本;
      • 若必须使用 innerHTML,则需要对输入的内容进行手动转义,将特殊字符转换为 HTML 实体。
  • 典型场景:前端通过 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 安全核心逻辑链

  1. 防御基础:同源策略隔离非同源资源,CORS 在安全前提下开放跨域权限;
  2. 主要攻击
    • XSS:注入脚本到目标站点,窃取 Cookie(前端 / 后端漏洞);
    • CSRF:利用 Cookie 自动携带特性,伪造用户操作(后端漏洞);
  3. 关键防御:Cookie 的HttpOnly(防 XSS)、SameSite(防 CSRF)、Secure(防窃听)配置,从载体层面阻断攻击。
  4. CSRF 防御:以 CSRF Token 为核心(服务端终极防御),配合 SameSite Cookie(浏览器端第一道防线),实现双重防御,彻底阻断身份伪造攻击;
  5. XSS 防御:以 输出过滤(输入验证 + 输出转义) 为核心(基础防御),配合 内容安全策略(CSP)(进阶补充防御),实现从 “源头过滤” 到 “执行阻断” 的全链路防御,彻底阻断脚本注入攻击;
  6. 职责划分
    • CSRF 防御的核心职责在后端
    • XSS 防御的核心职责:反射型 / 存储型在后端,DOM 型在前端