XSS中的同源和跨域的问题
学习自https://www.cnblogs.com/-qing-/p/10966047.html
也谈谈同源策略和跨域问题
所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源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中的元素也是会报错的,因为域名不同。报错如下所示
另外,我们看到直接通过Javascript去取iframe中的元素也是会报错的,因为域名不同。报错如下所示
这时因为我们的主域名相同,因此可以在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")[].childNodes[].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 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中的同源和跨域的问题的更多相关文章
- 小结ajax中的同源和跨域 jsonp和cors
网上的同源和跨域一般都比较复杂,最近也稍微总结了一下: 所谓同源,是浏览器的一种安全机制,作用在于保护网页数据的安全,不同源的网页之间不允许cookie dom ajax等行为 同源的条件:1.协议相 ...
- js中ajax如何解决跨域请求
js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...
- Web API中使用CORS解决跨域
Web API中使用Cros解决跨域 如果两个页面的协议,端口和域名都相同,则两个页面具有相同的源,注:IE不考虑端口,同源策略不会阻止浏览器发送请求,但是它会阻止应用程序看到响应.如下图所示 COR ...
- spring boot 中通过CORS实现跨域
一.跨域问题出现的原因 出现跨域问题的原因是同源策略. 同源策略 主要是三同:同协议.同域名.同端口, 同源策略目的 保证用户信息安全,防止恶意网站窃取数据.同源策略是必须的,否则cookie可以共享 ...
- mvc中使用jsonp进行跨域请求详细说明
在web开发中,如果你要在不同域下进行数据异步请求,会出现一个No ‘Access-Control-Allow-Origin’ header is present on the requested r ...
- html5中的postMessage解决跨域问题
解决跨域问题的方法有很多,如:图像ping(简单).jsonp(缺点是不能实现跨域post).CROS(CORS的本质让服务器通过新增响应头Access-Control-Allow-Origin,通过 ...
- 在ExpressJS中设置二级域名跨域共享Cookie
问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.ses ...
- 在dotnet core web api中支持CORS(跨域访问)
最近在写的Office add-in开发系列中,其中有一个比较共性的问题就是在add-in的客户端脚本中访问远程服务时,要特别注意跨域访问的问题. 关于CORS的一些基本知识,请参考维基百科的说明:h ...
- Spring Boot中通过CORS解决跨域问题
今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由Netscap ...
随机推荐
- Manacher模版
现在讲的也是一种处理字符串的方法,叫做Manacher,有点像“马拉车” 1179: [视频][Manacher]最长回文子串 时间限制: 1 Sec 内存限制: 128 MB提交: 209 解决 ...
- 从入门到自闭之Python高阶函数
高阶函数:内部帮忙做了一个for循环 filter:筛选过滤 语法: filter(function,iterable) function: 1.指定过滤规则(函数的内存地址) 2.用来筛选的函数,在 ...
- # 关于设置AUTH_USER_MODEL出现的问题
关于设置AUTH_USER_MODEL出现的问题 在运行的时候出现了一个bug: AttributeError: type object 'UserProfile' has no attribute ...
- redis 学习(10)-- redis 慢查询
redis 慢查询 什么是慢查询 MySQL会记录下查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称为慢查询,都记在慢查询日志里. redis 的生命周期 客户端向Redis服务器发送命令 ...
- 如何去除List集合中的重复元素? a,b,c,a,c,b,d,,,,,,
package com.fs.test; import java.util.ArrayList; import java.util.List; public class Listdemo { publ ...
- 日志:slf4j+logback 的配置与使用
1. 常用日志组件和选择 java开发日志处理是发现和调试bug所 必不可少的,那么现在企业中常用的日志组件有哪些呢,JCL . JUL. SLF4j.Log4j. Log4j2 . Logbac ...
- python tkinter 基本使用
这里只放表格和一个控件基本属性 grid(**options) 属性-- 下方表格详细列举了各个选项的具体含义和用法: 选项 含义column 1. 指定组件插入的列(0 表示第 1 列)2. 默认值 ...
- Delphi 程序调试
- Win10下注册APlayer组件的正确姿势
1. 官网下载SDK 和 解码器 APlayer媒体播放引擎 2.解压SDK和解码器,把解码器codecs文件夹内所有文件复制到SDK文件夹内的bin\codecs目录里面 3.使用管理员权限打开CM ...
- PyCharm上unittest 测试用例两种执行方式
每次讲到unittest测试框架的时候,经常有同学在群里反映,为啥我的运行不是按照我往suite里添加的用例顺序执行的,为什么别人的能跑出来报告,我的就不行... 当然,首先确认代码是OK的,如果代码 ...