浏览器SOP

Posted 行似深夜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器SOP相关的知识,希望对你有一定的参考价值。

同源策略(SOP)

同源策略(Same origin policy)是一个重要的安全策略,它用于限制一个源的资源如何与另一个源的资源进行交互。

通过fetch跨域请求

让index文件运行在client服务器上,然后用fetch请求server服务器。

index.html

<script>
    fetch("http://127.0.0.1:3001/script");
</script>

client.js

 const http = require("http");
 const fs = require("fs");
 const  exec  = require("child_process");
 
 http.createServer((req, res) => 
     const url = req.url;
 
     if (url === "/") 
         fs.createReadStream("index.html").pipe(res);
     
 ).listen(3000);
 
 exec("start http://127.0.0.1:3000/");

server.js

 const http = require("http");
 
 http.createServer((req, res) => 
     const url = req.url;
 
     if (url === "/script") 
         console.log(
             "\\n>>>消息\\n\\n我收到了来自“http://127.0.0.1:3000/”的“http://127.0.0.1:3001/script”请求\\n\\n<<<消息",
         );
     
 ).listen(3001);

用node启动client和server。

查看network,status是待处理;再看看node日志,已经接收到跨域请求了。

然后再让server服务器响应本次请求。

 if (url === "/script") 
     console.log(
         "\\n>>>消息\\n\\n我收到了来自“http://127.0.0.1:3000/”的“http://127.0.0.1:3001/script”请求\\n\\n<<<消息",
     );
     return res.end("/script");
 

重新启动server服务器,刷新页面,发现控制台报错了。

这个就是CORS错误,原因是响应头没有配置“Access-Control-Allow-Origin”标头,未公开的资源说明不太安全,所以屏蔽掉了响应体。

查看请求头,发现有一个Origin标头,这是浏览器告诉服务器本次请求来自于哪里。

尽管浏览器SOP阻止跨域行为,但是如果证明跨域资源足够安全,就允许该资源在本地执行,所以有了CORS。

跨域资源共享策略(CORS)

跨域资源共享策略(Cross-origin Resource Sharing)是浏览器端和服务器端的一种约定,通过约定来表示跨域资源的安全性;这种约定由请求头和响应头来完成。

服务器对于安全性比较低或者公开的资源,例如图片、公共js库等,允许任意源访问。

在报文发送前,添加Access-Control-Allow-Origin标头。

res.writeHead(200, 
    "Access-Control-Allow-Origin": "*",
);

重新启动server服务器,刷新页面,这个时候跨域请求就成功了。

CORS 策略将跨域请求分为两类:简单请求和非简单请求;我们上面的情况属于简单请求。

非简单请求在发送前,会先发送一次预检请求(OPTIONS),服务器同意以后开始发送实际请求。

根据MDN的文档定义,请求方法为:GET、POST、HEAD,请求头Content-Type为:text/plain、multipart/form-data、application/x-www-form-urlencoded的就属于简单请求。

下面发送一个非简单请求。

在index.js中添加自定义标头:

 <script>
     fetch("http://127.0.0.1:3001/script", 
         headers: 
             "test-1": "a",
             "test-2": "b",
         ,
     );
 </script>

在server.js中添加三个标头:

 "Access-Control-Allow-Headers": "test-1,test-3",
 "Access-Control-Allow-Methods": "GET,PUT,DELETE",
 "Access-Control-Max-Age": 10,

重新启动server服务器,刷新页面,发现有报错。

可以看到,fetch请求使用了服务器不支持的标头,所以预检请求没通过。test-3改成test-2再试一次,预检通过。

Access-Control-Max-Age表示本次预检请求的时效性,单位是s,在这个时间内再次发起相同的请求,不需要再次提交预检请求;10秒内连续刷新页面试试。

以上是关于浏览器SOP的主要内容,如果未能解决你的问题,请参考以下文章

通过浏览器缓存bypass同源策略(SOP)

我可以在任何浏览器上禁用 SOP(同源策略)进行开发吗?

看我如何发现Chrome浏览器阅读辅助插件SOP绕过漏洞

反向代理背后的 SOP 问题

xss利用——BeEF#stage3(绕过同源策略与浏览器代理)

PHP-安裝SOP