Web安全中的同源策略(Same-Origin Policy)与跨域安全机制详解
字数 1914 2025-11-29 03:20:48

Web安全中的同源策略(Same-Origin Policy)与跨域安全机制详解

1. 同源策略(Same-Origin Policy)的基本概念

同源策略是浏览器最核心的安全机制之一,用于限制不同源的文档或脚本之间的交互。其核心目的是防止恶意网站通过脚本窃取其他网站的数据。

  • 同源的定义:两个URL的协议(Protocol)、域名(Domain)、端口(Port) 完全一致。例如:
    • https://example.com/app1https://example.com/app2 同源(协议、域名、端口相同)。
    • http://example.comhttps://example.com 不同源(协议不同)。
    • https://example.comhttps://api.example.com 不同源(域名不同)。

同源策略的限制范围

  • Cookie、LocalStorage、IndexedDB 等存储数据的访问。
  • DOM 元素的读写(例如通过iframe嵌入的页面)。
  • AJAX 请求的响应(通过XMLHttpRequestfetch发起)。

2. 同源策略的例外场景与跨域需求

实际开发中,不同子域或端口的前后端服务需要协作,因此需安全地绕过同源策略。常见场景包括:

  • 前端域名(https://www.example.com)需调用后端API(https://api.example.com)。
  • 集成第三方服务(如支付、地图)。

3. 跨域安全机制:CORS(跨域资源共享)

CORS 是W3C标准,允许服务器明确声明哪些外部源可以访问其资源。

3.1 简单请求与非简单请求

  • 简单请求(满足以下所有条件):

    • 方法为 GET、POST、HEAD。
    • 请求头仅包含AcceptAccept-LanguageContent-LanguageContent-Type(限application/x-www-form-urlencodedmultipart/form-datatext/plain)。
    • 浏览器行为:自动在请求头中添加Origin,服务器通过响应头Access-Control-Allow-Origin决定是否允许跨域。
  • 非简单请求(如PUT、DELETE或携带自定义头):

    • 浏览器先发送预检请求(Preflight Request)(OPTIONS方法),询问服务器是否允许实际请求。
    • 服务器响应预检请求时需包含以下头部:
      Access-Control-Allow-Origin: https://www.example.com  // 允许的源  
      Access-Control-Allow-Methods: GET, POST, PUT          // 允许的方法  
      Access-Control-Allow-Headers: X-Custom-Header         // 允许的自定义头  
      
    • 通过预检后,浏览器才发送实际请求。

3.2 CORS 安全风险与防护

  • 风险:若服务器配置Access-Control-Allow-Origin: *(允许所有源),可能导致敏感数据泄露。
  • 防护措施
    • 严格限制允许的源(避免使用通配符*)。
    • 对敏感请求强制要求预检机制。
    • 结合认证机制(如Cookie或Token)验证请求合法性。

4. 其他跨域方案与安全考量

4.1 JSONP(JSON with Padding)

  • 原理:通过<script>标签的src属性绕过同源策略(因为script标签允许跨域)。
  • 风险
    • 仅支持GET请求,难以防御CSRF。
    • 依赖回调函数,易遭受XSS攻击(若返回内容未过滤)。
  • 适用场景:获取公开数据(如天气API),但已逐渐被CORS替代。

4.2 PostMessage API

  • 原理:允许不同源的窗口之间安全地传递消息。
  • 安全实践
    • 发送方指定目标窗口的源:
      targetWindow.postMessage("数据", "https://trusted-site.com");  
      
    • 接收方验证消息来源:
      window.addEventListener("message", (event) => {  
        if (event.origin !== "https://expected-origin.com") return;  
        // 处理数据  
      });  
      
  • 风险:若未验证event.origin,可能导致恶意网站窃听消息。

4.3 代理服务器

  • 原理:前端请求同源服务器,由服务器转发请求至目标API(服务器之间无同源限制)。
  • 安全优势:隐藏后端API地址,避免直接暴露给浏览器。

5. 实战中的安全配置示例

5.1 CORS 服务器配置(Node.js/Express)

app.use((req, res, next) => {  
  const allowedOrigins = ["https://www.example.com", "https://app.example.com"];  
  const origin = req.headers.origin;  
  if (allowedOrigins.includes(origin)) {  
    res.setHeader("Access-Control-Allow-Origin", origin);  
  }  
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");  
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");  
  // 允许携带Cookie  
  res.setHeader("Access-Control-Allow-Credentials", "true");  
  if (req.method === "OPTIONS") return res.sendStatus(200); // 处理预检请求  
  next();  
});  

5.2 防御CSRF(跨站请求伪造)

  • 同源策略不阻止跨域请求的发起,但会拦截响应。因此需额外防护:
    • 使用CSRF Token(要求请求携带服务器生成的随机Token)。
    • 设置Cookie的SameSite属性(限制第三方Cookie的发送)。

6. 总结

  • 同源策略是浏览器安全的基石,但需通过CORS等机制平衡功能与安全。
  • 跨域方案需根据场景选择,并严格验证源、方法、头部等参数。
  • 错误配置(如CORS通配符、JSONP回调过滤不严)可能导致数据泄露或XSS攻击。
Web安全中的同源策略(Same-Origin Policy)与跨域安全机制详解 1. 同源策略(Same-Origin Policy)的基本概念 同源策略 是浏览器最核心的安全机制之一,用于限制不同源的文档或脚本之间的交互。其核心目的是防止恶意网站通过脚本窃取其他网站的数据。 同源的定义 :两个URL的 协议(Protocol)、域名(Domain)、端口(Port) 完全一致。例如: https://example.com/app1 和 https://example.com/app2 同源 (协议、域名、端口相同)。 http://example.com 和 https://example.com 不同源 (协议不同)。 https://example.com 和 https://api.example.com 不同源 (域名不同)。 同源策略的限制范围 : Cookie、LocalStorage、IndexedDB 等存储数据的访问。 DOM 元素的读写(例如通过 iframe 嵌入的页面)。 AJAX 请求的响应(通过 XMLHttpRequest 或 fetch 发起)。 2. 同源策略的例外场景与跨域需求 实际开发中,不同子域或端口的前后端服务需要协作,因此需 安全地绕过同源策略 。常见场景包括: 前端域名( https://www.example.com )需调用后端API( https://api.example.com )。 集成第三方服务(如支付、地图)。 3. 跨域安全机制:CORS(跨域资源共享) CORS 是W3C标准,允许服务器明确声明哪些外部源可以访问其资源。 3.1 简单请求与非简单请求 简单请求 (满足以下所有条件): 方法为 GET、POST、HEAD。 请求头仅包含 Accept 、 Accept-Language 、 Content-Language 、 Content-Type (限 application/x-www-form-urlencoded 、 multipart/form-data 、 text/plain )。 浏览器行为 :自动在请求头中添加 Origin ,服务器通过响应头 Access-Control-Allow-Origin 决定是否允许跨域。 非简单请求 (如PUT、DELETE或携带自定义头): 浏览器先发送 预检请求(Preflight Request) (OPTIONS方法),询问服务器是否允许实际请求。 服务器响应预检请求时需包含以下头部: 通过预检后,浏览器才发送实际请求。 3.2 CORS 安全风险与防护 风险 :若服务器配置 Access-Control-Allow-Origin: * (允许所有源),可能导致敏感数据泄露。 防护措施 : 严格限制允许的源(避免使用通配符 * )。 对敏感请求强制要求预检机制。 结合认证机制(如Cookie或Token)验证请求合法性。 4. 其他跨域方案与安全考量 4.1 JSONP(JSON with Padding) 原理 :通过 <script> 标签的 src 属性绕过同源策略(因为 script 标签允许跨域)。 风险 : 仅支持GET请求,难以防御CSRF。 依赖回调函数,易遭受XSS攻击(若返回内容未过滤)。 适用场景 :获取公开数据(如天气API),但已逐渐被CORS替代。 4.2 PostMessage API 原理 :允许不同源的窗口之间安全地传递消息。 安全实践 : 发送方指定目标窗口的源: 接收方验证消息来源: 风险 :若未验证 event.origin ,可能导致恶意网站窃听消息。 4.3 代理服务器 原理 :前端请求同源服务器,由服务器转发请求至目标API(服务器之间无同源限制)。 安全优势 :隐藏后端API地址,避免直接暴露给浏览器。 5. 实战中的安全配置示例 5.1 CORS 服务器配置(Node.js/Express) 5.2 防御CSRF(跨站请求伪造) 同源策略不阻止跨域请求的发起,但会拦截响应。因此需额外防护: 使用CSRF Token(要求请求携带服务器生成的随机Token)。 设置Cookie的 SameSite 属性(限制第三方Cookie的发送)。 6. 总结 同源策略是浏览器安全的基石,但需通过CORS等机制平衡功能与安全。 跨域方案需根据场景选择,并严格验证源、方法、头部等参数。 错误配置(如CORS通配符、JSONP回调过滤不严)可能导致数据泄露或XSS攻击。