XSS中的同源策略和跨域问题
转自 https://www.cnblogs.com/chaoyuehedy/p/5556557.html
1 同源策略
所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源a的js不能读取或设置引入的源b的元素属性。
那么先定义下什么是同源,所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可。
可以看下面的几个示例来更加清楚的了解一下同源的概念:
| URL1 | URL2 | 说明 | 是否允许通信 |
|---|---|---|---|
| http://www.foo.com/js/a.js | http://www.foo.com/js/b.js | 协议、域名、端口都相同 | 允许 |
| http://www.foo.com/js/a.js | http://www.foo.com:8888/js/b.js | 协议、域名相同,端口不同 | 不允许 |
| https://www.foo.com/js/a.js | http://www.foo.com/js/b.js | 主机、域名相同,协议不同 | 不允许 |
| http://www.foo.com/js/a.js | http://www.bar.com/js/b.js | 协议、端口相同,域名不同 | 不允许 |
| http://www.foo.com/js/a.js | http://foo.com/js/b.js | 协议、端口相同,主域名相同,子域名不同 | 不允许 |
同源策略限制了不同源之间的交互,但是有人也许会有疑问,我们以前在写代码的时候也常常会引用其他域名的js文件,样式文件,图片文件什么的,没看到限制啊,这个定义是不是错了。其实不然,同源策略限制的不同源之间的交互主要针对的是js中的XMLHttpRequest等请求,下面这些情况是完全不受同源策略限制的。
- 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。链接就不用说了,导航网站上的链接都是链接到其他站点的。而你在域名
www.foo.com下面提交一个表单到www.bar.com是完全可以的。 - 跨域资源嵌入是允许的,当然,浏览器限制了Javascript不能读写加载的内容。如前面提到的嵌入的
<script src="..."></script>,<img>,<link>,<iframe>等。当然,如果要阻止iframe嵌入我们网站的资源(页面或者js等),我们可以在web服务器加上一个X-Frame-Options DENY头部来限制。nginx就可以这样设置add_header X-Frame-Options DENY;。
既然有这么多的情况是没有同源策略限制的,那么通常的跨域问题从何而来呢?转到下一节跨域问题。
2 跨域问题
这一节来讨论下跨域问题,当然前置条件是我们在WEB服务器或者服务端脚本中设置ACCESS-CONTROL-ALLOW-ORIGIN头部,如果设置了这些头部并允许某些域名跨域访问,则浏览器就会跳过同源策略的限制返回对应的内容。此外,如果你不是通过浏览器去获取资源,比如你通过一个python脚本去调用接口或者获取js文件,也不在这个限制之内。
2.1 Ajax跨域
通过ajax调用其他域的接口会有跨域问题。比如下面的例子,我在http://www.foo.com/index.html中通过ajax调用请求http://www.bar.com/js/test.js页面,此时是会报错的。
XMLHttpRequest cannot load http://www.bar.com/js/test.js.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://www.foo.com' is therefore not allowed access.
这是因为我们的WEB服务器没有设置ACCESS-CONTROL-ALLOW-ORIGIN头部,默认情况下是禁止跨域引用资源的。当然这里有一点要注意,其实这个跨域请求是发送成功了的,服务器也有返回test.js内容,只是浏览器禁止Javascript去取response的数据而已。如果要设置ACCESS-CONTROL-ALLOW-ORIGIN头部,nginx可以使用下面的代码
add_header 'Access-Control-Allow-Origin' 'http://www.foo.com';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST';
另外,我们看到直接通过Javascript去取iframe中的元素也是会报错的,因为域名不同。报错如下所示
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://www.foo.com" from accessing a frame with origin "http://foo.com".
The frame being accessed set "document.domain" to "foo.com", but the frame requesting access did not. Both must set "document.domain" to the same value to allow access.
这时因为我们的主域名相同,因此可以在index.html和test.html中设置document.domain='foo.com'来访问iframe中的元素。注意,是两个域名下面的文件都要设置,即便是同样的主域名。当然这是特例,如果是两个完全不同的域名,是没有办法的,你不能把www.foo.com的domain设置成www.163.com。
此外,在index.html里面也可以看到通过<script>,<iframe>等标签都是可以跨域内嵌资源的。
# index.html
<!DOCTYPE html>
<html>
<head>
<title>test cross domain</title>
<script src="/js/jquery.js"></script>
<script src="http://www.bar.com/js/test.js"></script>
<script>
$(function(){
document.domain = 'foo.com'; //1 注释掉则会报错
var ifr = document.getElementById("testframe");
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
}
}); $.ajax("http://www.bar.com/js/test.js"); //2 报错
</script> </head>
<body>
<h1>Test Cross Domain</h1>
<iframe id="testframe" src="http://foo.com/test.html"></iframe>
</body>
</html>
当然还可以通过iframe,location.hash,window.name,HTML5的postMessage等方法来实现跨域资源访问,更多内容参见Rain Man的这篇文章 JavaScript跨域总结和解决办法。
2.2 JSONP跨域访问
JSONP也是开发中常见到的内容,在jquery中就有封装,通过ajax请求多带上一个jsonp的参数即可。JSONP也能够实现跨域访问资源,但是它的实现原理其实跟ajax没有多少关系,它是通过动态插入<script>标签来实现跨域资源访问的,因为根据前面内容我们已经知道,嵌入跨域资源浏览器是允许的。
下面通过一个简单的例子来说明JSONP的原理。
两个文件,第一个是http://www.foo.com/jsonp.html,通过动态创建script标签加载了http://www.bar.com/js/outer.js文件,然后outer.js文件返回的内容正好是一个函数调用,如此,实现了数据传递和回调过程。当然,实际的jsonp接口中,会让你传一个函数名过去,然后返回的数据中回调函数名就是你传的函数名,回调函数的参数则是封装的json格式。jQuery中的jsonp实现原理基本就是这样,更详细的jsonp原理可以参见这篇大作深入浅出JSONP。
# jsonp.html
<script type="text/javascript">
function callback(data) {
alert(data.message);
}
function addScriptTag(src){
var script = document.createElement('script');
script.src = src;
document.body.appendChild(script);
} window.onload = function(){
addScriptTag("http://www.foo.com/js/outer.js");
}
</script> # outer.js
callback({message:"success"});
XSS中的同源策略和跨域问题的更多相关文章
- JS同源策略和跨域访问
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的,浏览器只 ...
- 11. cookie_session_原生ajax_readyState的值_同源策略_跨域_jsonp的使用
1. cookie 浏览器存储技术.(服务器将少量数据交于浏览器存储管理) 作用: 存储数据, 解决 http 协议无状态问题 工作流程: 浏览器发送请求给服务器,请求登录 服务器返回响应给浏览器,此 ...
- 第二百七十四节,同源策略和跨域Ajax
同源策略和跨域Ajax 什么是同源策略 尽管浏览器的安全措施多种多样,但是要想黑掉一个Web应用,只要在浏览器的多种安全措施中找到某种措施的一个漏洞或者绕过一种安全措施的方法即可.浏览器的各种保安措 ...
- JS同源策略和跨域问题
同源策略和跨域问题:http://www.cnblogs.com/chaoyuehedy/p/5556557.html 深入浅出JSONP--解决ajax跨域问题:http://www.cnblogs ...
- cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案
cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...
- Ajax_同源策略以及跨域问题
Ajax_同源策略 同源策略是浏览器的一种安全策略, 同源指的是:协议.域名.端口.必须完全相同. 违背同源策略就是跨域. 而AJAX是默认遵循同源策略的: 同源说通俗一点呢就是页面跟获取请求的接口是 ...
- 1.7 xss之同源策略与跨域访问
同源策略: 同源策略 在web应用的安全模型中是一个重要概念.在这个策略下,web浏览器允许第一个页面的脚本访问第二个页面里的数据,但是也只有在两个页面有相同的源时.源是由URI,主机名,端口号组合而 ...
- django中同源策略和跨域解决方案
一 同源策略 1.1何谓同源? 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同 ...
- script标签crossorigin属性及同源策略和跨域方法
首先介绍(同源策略) 同源策略是浏览器最核心且基本的安全约定,要求协议.域名.端口都相同为同源,如果非同源时请求数据浏览器会在控制台抛出跨域异常错误,同源策略是浏览器的行为,即使客户端请求发送了,服务 ...
随机推荐
- AMBA——slave的HREADY信号
在前几天的ARM面试中,被问到总线架构,主要是AMBA那一套东西.对于AMBA之前上课学过一点,但很肤浅.为了面试上网查了一下.也看了部分协议补充了一下,但是接触的少,理解的不深入,被问到之前没遇到的 ...
- Android Studio [ImageView/使用第三方库加载图片]
ImageViewActivity.class package com.xdw.a122; import android.support.v7.app.AppCompatActivity; impor ...
- 工厂模式(整理自李建忠<C++设计模式>视频)
整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...
- CF #579 (Div. 3) C.Common Divisors
C.Common Divisors time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...
- 基于Spark的电影推荐系统(实战简介)
写在前面 一直不知道这个专栏该如何开始写,思来想去,还是暂时把自己对这个项目的一些想法 和大家分享 的形式来展现.有什么问题,欢迎大家一起留言讨论. 这个项目的源代码是在https://github. ...
- js---电商中常见的放大镜效果
js中的放大镜效果 在电商中,放大镜效果是很常见的,如下图所示: 当鼠标悬浮时,遮罩所在区域在右侧进行放大. 在动手写之前,我们要先理清思路,分析需求,所需知识点,再将每一块进行组装,最后进行功能的完 ...
- JIRA集成GitHub
原因: 作为管理员, 为用户提高效率的角度,配置测试此服务.让用户从JIRA内看到代码分支,提交信息,pull requests等等, 让Github的代码提交记录和JIRA的任务管理系统集成在一起, ...
- Spring 梳理-接收请求的输入(原)
Spring MVC 允许一下方式将客户端的数据传送到控制器的处理方法中 查询参数(Query Parameter) 表单参数(Form Parameter) 路径变量(Path Variable ...
- # C# 中的Task创建指南
本文还处于草稿阶段,难免还有错误修改改正,逻辑还不是很清晰,笔者会努力完善,长期更新! [0000] 前言 标题起得有些"大",意在集大家的力量,总结出来一份关于Task相对&qu ...
- 自定义TabLayout的Indicator
最近项目要使用类似TabLayout的控件,其实我感觉就是TabLayout只是换了一个Indicator,先说一说TabLayout这是Android Support Design的控件要使用的同学 ...