Web 安全中的同源策略与跨域风险

同源策略(Same-Origin Policy)是现代浏览器最核心的安全基石之一。它定义了浏览器如何隔离来自不同源的文档与脚本,从而防止恶意站点读取或篡改另一站点的数据。然而,随着前后端分离、微服务架构和第三方集成的普及,跨域需求日益增多,围绕同源策略的绕过与防御也成为 Web 安全攻防的焦点。本文将从同源策略的基本概念出发,分析常见的跨域风险,并结合 XSS、SQL 注入、服务器加固等关联话题,给出可落地的防御建议。

一、什么是同源策略

同源策略要求两个 URL 的协议、域名和端口完全一致,才视为“同源”。例如:

  • https://example.com/apphttps://example.com/api 同源(协议、域名、端口均相同)。
  • http://example.comhttps://example.com 不同源(协议不同)。
  • https://example.comhttps://api.example.com 不同源(域名不同)。
  • https://example.com:443https://example.com:8443 不同源(端口不同)。

同源策略主要限制以下行为:

  1. Cookie、LocalStorage、IndexedDB 等存储的跨源读取:不同源的页面无法读取彼此的存储数据。
  2. DOM 访问:不同源的 iframe 无法读取或修改彼此的 DOM。
  3. AJAX/Fetch 请求的响应读取:跨源请求可以发出,但默认无法读取响应内容(除非目标服务器明确允许)。

需要注意的是,同源策略只限制“读取”,不限制“发送”。这意味着跨源请求仍然可以被触发,从而引出了 CSRF(跨站请求伪造)等风险。

二、跨域风险的常见来源

1. CORS 配置不当

CORS(跨源资源共享)是 W3C 标准,允许服务器通过响应头声明哪些源可以读取资源。常见错误配置包括:

  • Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true 同时使用。浏览器会拒绝这种组合,但若开发者错误地动态反射 Origin 头,则可能允许任意站点携带用户 Cookie 读取敏感数据。
  • Origin 头进行简单字符串匹配,例如只检查是否包含 example.com,攻击者可用 example.com.evil.com 绕过。
  • 允许 null 源,攻击者可通过沙盒 iframe 或本地文件发起请求。

2. JSONP 的历史遗留

JSONP 通过 <script> 标签绕过同源策略,但只支持 GET 请求,且容易受到 XSS 和 CSRF 影响。现代应用应优先使用 CORS,逐步淘汰 JSONP。

3. postMessage 使用不当

window.postMessage 允许跨源窗口通信,但若接收方未验证 event.origin 或未校验消息内容,攻击者可通过恶意页面发送伪造消息,导致数据泄露或逻辑篡改。

4. XSS 与同源策略的交互

XSS(跨站脚本攻击)本质上是在目标源内执行恶意脚本。由于脚本与目标站点同源,它可以完全绕过同源策略,读取 Cookie、LocalStorage、发起同源请求等。常见 XSS 方式包括:

  • 反射型 XSS:恶意脚本作为请求参数,服务器未过滤直接返回。
  • 存储型 XSS:恶意脚本被存入数据库,其他用户访问时触发。
  • DOM 型 XSS:前端 JavaScript 不安全地操作 innerHTMLevaldocument.write 等。

前端防御 XSS 的常见措施

  • 对用户输入进行输出编码,根据上下文使用 HTML 编码、JavaScript 编码、URL 编码。
  • 使用 textContent 而非 innerHTML 插入文本。
  • 启用 CSP(内容安全策略),限制脚本来源,禁止 unsafe-inline
  • 对富文本使用白名单过滤库(如 DOMPurify)。
  • 设置 Cookie 的 HttpOnlySecureSameSite 属性,降低 XSS 窃取会话的风险。

三、跨域风险与后端及服务器的关联

同源策略主要作用于浏览器端,但跨域风险往往与后端配置和服务器安全紧密相关。

1. SQL 注入与跨域数据泄露

如果后端 API 存在 SQL 注入,攻击者可通过跨源请求(结合 CORS 错误配置)或直接请求接口,读取数据库中的敏感信息。防止 SQL 注入的几种常见写法:

  • 参数化查询(Prepared Statements):使用 ? 或命名参数,将 SQL 语句与数据分离。例如 PHP PDO:
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
    $stmt->execute(['email' => $email]);
    
  • 使用 ORM 框架:如 SQLAlchemy、Hibernate、Eloquent,避免手写拼接 SQL。
  • 输入验证与白名单:对排序字段、表名等无法参数化的部分,使用严格白名单。
  • 最小权限原则:数据库账户只授予必要权限,避免 DROPFILE 等高危操作。
  • 错误信息脱敏:不向前端返回详细 SQL 错误,防止信息泄露。

2. Linux 服务器安全加固清单

服务器是 Web 应用的运行环境,加固服务器可降低跨域攻击面。以下是一份实用的加固清单:

  • 系统更新:定期安装安全补丁,启用自动更新。
  • 最小化服务:关闭不必要的端口、服务和守护进程。
  • SSH 加固:禁用 root 远程登录,使用密钥认证,修改默认端口,限制来源 IP。
  • 防火墙配置:使用 iptables/nftables 或云安全组,仅开放必要端口。
  • 文件权限:Web 目录权限最小化,避免 777;敏感文件(如 .envconfig.php)不可通过 Web 访问。
  • 日志与监控:启用审计日志(auditd),集中收集 Nginx/Apache 访问日志,设置异常告警。
  • Web 服务器加固:隐藏版本号,配置安全响应头(CSP、X-Frame-Options、X-Content-Type-Options、Referrer-Policy)。
  • 定期备份与恢复演练:确保备份可用,防止勒索软件或误删除。

四、综合防御建议

  1. 严格配置 CORS:只允许可信源,避免反射 Origin,不要同时使用 * 和凭据。
  2. 优先使用 SameSite Cookie:将敏感 Cookie 设为 SameSite=LaxStrict,减少 CSRF 和跨域泄露。
  3. 实施 CSP:限制脚本、样式、帧的来源,缓解 XSS 和跨域数据注入。
  4. 验证 postMessage 来源:始终检查 event.origin,并对消息结构做严格校验。
  5. 前后端双重防御:前端编码与 CSP 不能替代后端参数化查询、权限校验和输入验证。
  6. 定期安全测试:使用 DAST/SAST 工具,结合人工渗透测试,重点关注 CORS、XSS、SQL 注入和服务器配置。

同源策略不是万能的,它只是浏览器安全模型的第一道防线。真正的安全需要从前端、后端到服务器层层设防,并持续关注新的绕过技术与防御策略。只有理解同源策略的边界与跨域风险的来源,才能在设计 API、配置服务器和编写代码时做出正确的安全决策。

未经允许不得转载:任鹏个人博客 » Web 安全中的同源策略与跨域风险

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏