Open FrankKai opened 5 years ago
same-origin policy是一个严格的安全策略,它可以用来限制document或者script如何从一个origin加载,然后与另一个origin的资源进行交互。隔离了潜在危险的恶意documents,减少网站被攻击的次数。
如果两个URL协议相同、端口相同、主机也相同,那么它们是same origin。我们看到的一般是一下两种形式:
注释:tuple是一组数据的集合,可以是表单,也可以是2个,3个,4个参数等等。
以http://store.company.com/dir/page.html
为例:
URL | Outcome | Reason |
---|---|---|
http://store.company.com/dir2/other.html | Same origin | Only the path differs |
http://store.company.com/dir/inner/another.html | Same origin | Only the path differs |
https://store.company.com/page.html | Failure | Different protocol |
http://store.company.com:81/dir/page.html | Failure | Different port (http:// is port 80 by default) |
http://news.company.com/dir/page.html | Failure | Different host |
最后http://news.company.com/dir/page.html的不一定,如果在hosts文件中进行映射,例如下面这样,那么它们也是同源: /etc/hosts
192.168.0.23 news.company.com store.company.com:
因为此时它们的host是相同的。
一般来说,更多的是调用其getter。
const forbiddenDomain = "996.icu";
if(document.domain === forbiddenDomain){
// Scripts may close only the windows that were opened by it.
// 仅仅可以关闭由当前window打开的窗口.
window.close();
}
调用setter,可以将端口更改为null,可以进行端口不同跨域通信。
document.domain = document.domain;
同源策略主要控制着2个不同源的交互,例如当你使用XMLHttpRequest
或者<img>
标签。这个交互一般分为3类:
这里有一些跨域嵌的一些资源类型:
<script src="…"></script>
<link rel="stylesheet" href="…">
跨域CSS的Content-Type请求头必须正确<img>
显示的资源<video>``<audio>
请求的视频,音频<object>``<embed>``<applet>
嵌入的插件@font-face
获取到的字体,一些浏览器允许跨域fonts,其他的需要同源。<frame>
和<iframe>
标签中的内容。可以通过X-Frame-Options
请求头阻止跨域frame。拓展:
1.X-Frame-Options是什么?
是一个响应头,用来控制浏览器是否渲染<frame><iframe><embed><object>
。可以用来避免clickjacking
攻击。
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from https://example.com/
nginx配置:add_header X-Frame-Options sameorigin always;
2.什么是clickjacking 攻击?
中文名叫做点击劫持。
Clickjacking(通常被称为用户界面补救攻击),这是一个恶意技术,因为它会触发用户本不会去进行的一些点击,所以会潜在泄露保密信息的危险或者是会被恶意操控计算机。
在Web浏览器中,clickjacking是一个浏览器安全问题,这是很多浏览器和平台都存在的漏洞。Clickjacking可以在浏览器意外的应用程序中发生。
Clickjack采用嵌入式代码或脚本的形式,可以在用户不知情的情况下执行,例如单击看似执行其他功能的按钮。
那么如何避免Clickjacking呢? 凭借我有限的2年前端开发经验,可以通过事件对象events的isTrusted属性进行安全控制。可以查看:一些想不到的前端安全知识点
CORS,关于CORS,需要前后端的通力协作。
axios配置项
withCredentials: true
引用依赖koa-cors
var cors = require('koa-cors');
app.use(cors());
package com.arya.spring.vue.aryaspringvuebe;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@SpringBootApplication
public class AryaSpringVueBeApplication {
public static void main(String[] args) {
SpringApplication.run(AryaSpringVueBeApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 映射项目路由,允许/spring/vue下的所有接口跨域。注意**才是代表所有路由,否则*仅仅是类似/spring/vue/update一级路由,不支持/spring/vue/update?id=1。
registry.addMapping("/spring/vue/**")
// 设置Access-Control-Allow-Method: "GET", "POST", "PUT", "DELETE"
.allowedMethods("GET", "POST", "PUT", "DELETE")
// 设置Access-Control-Allow-Origin:http://localhost:3000,指定可访问源。注意PUT和DELETE引起的OPTIONS预检请求需要指定源,不可设置为*。
.allowedOrigins("http://localhost:3000")
// 设置Access-Control-Allow-Headers: content-type。
.allowedHeaders("Content-Type")
// 设置Access-Control-Max-Age: 3600。注意这里是Long类型的
.maxAge(3600L)
// 设置响应Access-Control-Allow-Credentials: true。
.allowCredentials(true);
}
};
}
}
像iframe.contentWindow, window.parent, window.open, and window.opener
这些API,允许文档直接互相调用。
当两个文档不在同源的情况下,会对window和location的API进行一些限制,就像下面两个部分描述的一样。
为了在不同的document间进行通信,需要用到window.postMessage。可以参考:什么是Web Workers?
下面的这些方法是允许 cross-origin 的。
window.blur
window.close
window.focus
window.postMessage
Attributes | 权限 |
---|---|
window.closed | Read only. |
window.frames | Read only. |
window.length | Read only. |
window.location | Read/Write. |
window.opener | Read only. |
window.parent | Read only. |
window.self | Read only. |
window.top | Read only. |
window.window | Read only. |
方法location.replace
属性URLUtils.href
只写
localStorage和IndexedDB也会有源的区分。每个源都有自己独立的storage,而且一个源下的js,不能读写另一个origin下的数据。
主要参考文档:https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Original_Document_Information