浏览器同源策略问题 - Cookie访问限制

本文涉及的产品
.cn 域名,1个 12个月
简介: 对应cookie来说,浏览器的同源策略将会限制不同源间的访问,对于跨站和跨域来说对访问cookie的影响也是不同的。同站请求,对于使用HTTPS协议的API,浏览器会存储cookie,不论`samesite`的值;对于使用HTTP协议的API,浏览器会存储`samesite`的值为`Lax`和`Strict`的cookie。跨站请求,对于HTTPS协议的API返回的cookie,如果设置了属性:`secure; samesite=none`,则浏览器会存储cookie,XHR请求也会带上目标域的cookie。

1. 跨站(cross-site)、跨域(cross-origin)

以下两个域名就属于跨站,他们具有不同的二级域名pro.comdev.com

ocs.pro.com

ocs.dev.com

以下两个域名就属于同站,具有相同的域名test.com

ocs.test.com

sts.test.com

2. Cookie 的 SameSite 属性

Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。

Cookie 的 SameSite属性是用于设置Cookie的访问范围的

它可以设置三个值。

  • Strict

    Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

    Set-Cookie: CookieName=CookieValue; SameSite=Lax;

    这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。

  • Lax Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

    Set-Cookie: CookieName=CookieValue; SameSite=Lax;

    设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

  • None

    Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性 (Cookie 只能通过 HTTPS 协议发送) ,否则无效。 下面的设置无效。

    Set-Cookie: widget_session=abc123; SameSite=None

    下面的设置有效

    Set-Cookie: widget_session=abc123; SameSite=None; Secure

3. XMLHttpRequest.withCredentials

XMLHttpRequest.withCredentials属性是一个布尔值,表示跨域请求时,用户信息(比如 Cookie 和认证的 HTTP 头信息)是否会包含在请求之中,默认为false,即向 example.com 发出跨域请求时,不会发送 example.com 设置在本机上的 Cookie(如果有的话)。

如果需要跨域 AJAX 请求发送 Cookie,需要withCredentials属性设为true。注意,同源的请求不需要设置这个属性。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://ocs.test.com/', true);
xhr.withCredentials = true;
xhr.send(null);

为了让这个属性生效,服务器必须显式返回Access-Control-Allow-Credentials这个头信息。

Access-Control-Allow-Credentials: true withCredentials属性打开的话,跨域请求不仅会发送 Cookie,还会设置远程主机指定的 Cookie。反之也成立,如果withCredentials属性没有打开,那么跨域的 AJAX 请求即使明确要求浏览器设置 Cookie,浏览器也会忽略。

注意,脚本总是遵守同源政策,无法从document.cookie或者 HTTP 回应的头信息之中,读取跨域的 Cookie,withCredentials属性不影响这一点。

4. Cookie的访问

同源(same-origin)

无限制,无论XMLHttpRequest.withCredentialstrue还是false,浏览器均可存储cookie,XHR请求中均会带上cookie。

顶级导航(top-level navigation),即浏览器地址栏中直接输入地址,浏览器会存储cookie,不论cookie的samesite的值是多少。

XMLHttpRequest.withCredentials=false,cross-origin,同站(same-site)

这种场景下,cookie不会被浏览器存储。

XMLHttpRequest.withCredentials=false,cross-origin,跨站(cross-site)

这种场景下,cookie不会被浏览器存储。

XMLHttpRequest.withCredentials=true,cross-origin,跨站(cross-site)

对于使用HTTP协议的API返回的cookie,浏览器不会存储,在浏览器开发者工具,网络面板中可以看到set-cookie后有告警图标,鼠标放上后可以看到相关说明。

对于HTTPS协议的API返回的cookie,如果设置了属性:secure; samesite=none,则浏览器会存储cookie。XHR请求也会带上目标域的cookie。

XMLHttpRequest.withCredentials=true,cross-origin,同站(same-site)

对于使用HTTPS协议的API,浏览器会存储cookie,不论samesite的值;

对于使用HTTP协议的API,浏览器会存储samesite的值为LaxStrict的cookie;

XHR请求会带上目标域的cookie;

// Java 设置secure; samesite=none 方法
@RestController
@RequestMapping
public class TestController {
    
    @GetMapping("/test")
    public Object test (HttpServletRequest request,
                    HttpServletResponse response) throws Exception {
        
        ResponseCookie cookie = ResponseCookie.from("myCookie", "myCookieValue") // key & value
                .httpOnly(true)     // 禁止js读取
                .secure(true)       // 在http下也传输
                .domain("localhost")// 域名
                .path("/")          // path
                .maxAge(Duration.ofHours(1))    // 1个小时候过期
                .sameSite("None")   // 大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外
                .build()
                ;
        
        // 设置Cookie Header 使用andHeader能设置多个,setHeader只能设置一个SET_COOKIE
        response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
        
        return "ok";
    }
}

5 总结

同源时cookie的存储与发送没有问题,顶级导航的情况可以看作是同源场景;

不同源场景,若XMLHttpRequest.withCredentials=false,则浏览器不会存储cookie;

不同源场景,且XMLHttpRequest.withCredentials=true,又可分为以下场景:

  • same-site

    对于使用HTTPS协议的API,浏览器会存储cookie,不论samesite的值;

    对于使用HTTP协议的API,浏览器会存储samesite的值为LaxStrict的cookie;

    XHR请求会带上目标域的cookie;

  • cross-site

    对于HTTPS协议的API返回的cookie,如果设置了属性:secure; samesite=none,则浏览器会存储cookie。XHR请求也会带上目标域的cookie。

跨站一定跨域。

目录
相关文章
|
1月前
|
存储 安全 JavaScript
浏览器的同源策略
【10月更文挑战第31天】浏览器的同源策略是浏览器安全模型的重要组成部分,它通过限制不同源之间的资源交互,有效地保护了用户和网站的安全。开发者在进行Web开发时,需要充分理解和遵循同源策略,同时合理地运用各种跨域技术来满足业务需求,确保网站的安全性和功能性的平衡。
57 2
|
1月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
1月前
|
域名解析 网络协议 前端开发
浏览器输入域名网址访问后的过程详解
1、以91处理网为例,客户端浏览器通过DNS解析到www.91chuli.com,IP地址是202.108.22.5,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到202.108.22.5,然后通过TCP进行封装数据包,输入到网络层。
71 2
|
1月前
|
Web App开发 API Windows
取接口访问者信息[IP,浏览器,操作系统]免费API接口教程
此API用于获取访问者的IP地址、浏览器和操作系统信息,支持70多种浏览器和操作系统。通过POST或GET请求至`https://cn.apihz.cn/api/ip/getapi.php`,需提供用户ID和KEY。返回结果包括状态码、消息、IP、浏览器和操作系统信息。示例:{"code":200,"ip":"175.154.88.178","browser":"Chrome","os":"Windows 10"}。详情见官网文档。
|
3月前
|
存储 编解码 JSON
解决浏览器存储问题,不得不了解的cookie、localStorage和sessionStorage
该文章详细对比了浏览器存储机制中的cookie、localStorage和sessionStorage的不同之处,以及各自的适用场景。
|
4月前
|
存储
【Azure APIM】APIM 策略语句如何来设置多个Cookie值让浏览器保存
【Azure APIM】APIM 策略语句如何来设置多个Cookie值让浏览器保存
|
4月前
Edge——如何打开IE浏览器进行访问
Edge——如何打开IE浏览器进行访问
77 4
|
5月前
|
安全 网络安全
用IE浏览器访问网站提示证书错误
当你在Internet Explorer中遇到证书错误提示,通常是因网站SSL/TLS证书问题或浏览器安全设置需调整。解决方法包括: 检查时间设置 调整IE设置 安装证书 调整计算机时间
146 3
|
5月前
|
存储 Web App开发 JavaScript
浏览器【详解】Cookie(含Cookie的起源,属性,个数和大小限制,作用,优点,缺点,JS 的操作方法等)
浏览器【详解】Cookie(含Cookie的起源,属性,个数和大小限制,作用,优点,缺点,JS 的操作方法等)
248 0
|
5月前
|
Web App开发
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问