浏览器是XSS等前端攻击的战场,有些浏览器附带一些安全策略,包含自带的XSS过滤、同源策略等。
W3C组织还针对XSS攻击制定了一个叫做CSP的安全层,也就是内容安全策略(Content Security Policy)。它的出现是为了帮助检测和缓解某些类型的攻击,比如跨站脚本(XSS)和数据注入等攻击,从而引入的浏览器策略。开发者可以根据CSP的规范,去创建一些很严格的规则,比如说白名单策略,管理网站允许加载的内容。当网站加载了非预期的内容,浏览器会及时阻止并且上报,减少出现安全风险时的损失。
CSP有两种指令方式:
(1)HTTPheader:比如在HTTP的响应头中设置Content-Security-Policy的值。
(2)HTML:比如在html里插入meta标签来实现。
如果都设置的话,以HTTP响应头里的为准
这里使用PHPstudy搭建一个简易的网站,网站的代码如下:
<meta charset="utf-8">
<?php
//只允许加载本地源图片:
header("Content-Security-Policy:img-src 'self' ");
?>
//允许加载所有源下的图片
<meta http-equiv="Content-Security-Policy" content="img-src*;">
//加载的是一张我随意百度的图片
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=464542646,4082158470&fm=27&gp=0.jpg"/>
接着我们打开火狐浏览器,然后进行访问:
我们发现底下的红色字迹提示内容的安全政策,表明header生效了,只允许加载本地源图片。
除此之外,我们在网络模块中,可以看到响应头中的确出现了安全政策。
指令 | 说明 |
---|---|
base-url | 文档的基准URL |
child-src | web workers 以及嵌套的浏览上下文(如 和 )的源 |
connect-src | 请求、XMLHttpRequest、WebSocket和EvenSource的连接来源 |
default-src | child-src connect-src font-src:控制字体文件来源 img-src:控制图片来源 media-src:控制video和audio标签里的资源来源 object-src:控制 、 、 标签里资源的来源script-src:控制JavaScript的有效来源 style-src:控制css的有效来源 |
plugin-types | 控制 、 、 插件资源的来源 |
reflected-xss | 控制浏览器对于反射型xss的策略 |
report-url | 用于接收浏览器发送违反CSP页面的报告地址 |
sandbox | 控制是否控制阻止弹窗,插件,脚本执行等 |
cookie:由于HTTP协议是无状态的,因此要跟踪用户的状态比如登陆信息,就得在每一个HTTP请求中多放一段数据来进行标记。
http规范中已经设计好了一个位置让你存放,就是消息头中的cookie段。而cookie可以由服务端发送指令或者客户端通过JavaScript脚本让浏览器生成并保存。
Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265 (可以叫做浏览器缓存)。
这个Cookie一般是有期限的,当攻击者盗取了用户没有失效的Cookie时,就相当于有了用户的用户名和密码。
我们来举两个例子来说明:
假设一个网站是:https://abc.com/xxx
,在访问这个网站时会携带cookie
其中cookie的属性是:path=/xxx、domain=.abc.com、secure
访问以下URL | 是否会附带cookie | 原因 |
---|---|---|
http://abc.com/xxx |
否 | 浏览器遵循secure标记,只在https传输该cookie |
https://abc.com/xxxx |
否 | 这个URL的path是/xxxx |
https://abc.com/xxx/x |
是 | 这个path是/xxx/x属于xxxx文件夹中的,他们是包含关系 |
https://abc.com/xxx |
是 | 因为一模一样 |
https://1.abc.com/xxx |
是 | 1.abc.com是二级域名,domain里:.abc.com的的规则 |
https://1.2.abc.com/xxx |
否 | 域名1.2.abc.com是一个三级域名,不符合domain里:.abc.com的规则 |
除上述cookie的属性外,cookie还有一个属性:expires=Sun,19-Apr-2019 15:11:23 GMT;Max-Age=604799expires的意思就是cookie的有效期,到了期限之后,浏览器会删除这段cookie。
保证cookie在传输过程中的安全性:主要是domain、path、secure和HttpOnly的配套组合。
(1)使用开发者工具或者浏览器插件来修改,F12存储:
我们可以看到过期时间,还有值,我们双击值就可以进行修改了。
(2)使用Burp进行拦截数据包之后修改cookie;
或者修改服务端响应的cookie,可以添加一个cookie头:set-cookie:a=123
(3)使用Kali中sqllite管理工具:
点开后,点击下面的打开存放cookie的数据库。
最后找到这个cookies.sqlite文件:
我们双击打开,如下:
然后点击右侧Browse Data,浏览数据。我们就可以看到cookie了,然后再这里修改即可。
修改之后重启即可。
从上面我们可以看出来,cookie是可以被修改的。那么怎样做才可以保证cookie的安全性呢?
第1个就是加密:对cookie进行可逆、不可逆的加密方式。
第2个就是利用session,这个接下来会讲。
最后要说的是:cookie只是用户在客户端保存数据的一种机制,可以通过在浏览器中设置禁用cookie来防止浏览器的追踪。cookie禁用的话,session也会随之失效。如果有这样的情况出现,服务端一般用的方法是把session id 追加在全站所有的URL的参数后面。
Session是基于Cookie之上的,Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录。
session其实是把信息存放在服务器,然后将session在服务器的位置信息放在cookie里。这种位置信息通常是比较长的随机字符串,一般称为 session id ,而且是不可预测的。而且放在服务器也有过期时间,除非核心算法有缺陷,不然基本上等你穷举出来,服务器放的那段信息早就过期好多年了。
注意:我们可以通过session的名称,判断创建它的架构语言。例如:PHPSESSI=>架构:PHP
参考链接:https://www.cnblogs.com/endlessdream/p/4699273.html
同源策略的规定可以概括成:不同域的客户端脚本在没明确授权的情况下,不能读写对方的资源主要有三要素:协议相同、域名相同、端口相同
原URL | 比较URL |
---|---|
https://blog.csdn.net/a1766855068 |
https://www.csdn.net/a1766855068 www.csdn.net是二级域名,csdn.net是根域名http://blog.csdn.net/a1766855068 端口不同https://blog.csdn.net/qq_43912468 同源(协议相同、域名相同) |
虽然有同源策略在,但是可以协商的。只是被请求的一方用某种方式允许了访问,就可以突破同源策略的限制。
下来举几个业务上常见的允许跨院访问的例子:
1、jsonp:
jsonp的本质是跨源的对方给你一段JavaScript脚本让你执行,而script标签的src属性是允许跨源的,所以达到了跨源的目的。
2、CORS:
CORS的原理就是修改HTTP响应的过程,是被请求的服务端获取到发出请求方的请求后,决定给响应头上加上了Access-Control-Allow-Origin相关的信息,浏览器就会对响应放行,让请求方拿到数据。
3、WebSocket
WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
DOM:文档对象模型(Document Object Model),所以简称DOM。
下面我们做一个表格,代码如下:
<html>
<body>
<table>
<tbody>
<tr>
<td>first</td>
<td>second</td>
</tr>
<tr>
<td>third</td>
<td>fourth</td>
</tr>
</tbody>
</table>
</body>
</html>
效果如图:
我们把它图形化吧:
这其实就是一个DOM树,HTML DOM其实是定义了访问和操作 HTML 文档的标准方法,我们之所以要研究DOM树,是因为在Web前端中,很多攻击都是围绕DOM展开的,例如:XSS,它就是通过Javascript代码去修改页面的HTML而导致XSS的产生,而这里的修改页面HTML其实就是修改目标页面的DOM树结构。
下面我举个例子:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>test</title>
<!--
<link href="css/style.css" rel="stylesheet">
<script src="js/test.js"></script>
-->
<style>
.css_test{color:blue}
</style>
</head>
<body>
<h1 style="color: red;">Hello World!^_^</h1>
<p class="css_test">This is a subtitle,哈哈</p>
<p id="test"></p>
<script>
var p_el = document.getElementById('test');
p_el.innerHTML="JS修改的内容";
</script>
</body>
</html>
这部分代码,导致了页面中出现了一行文字内容"JS修改的内容", 这部分内容并没有在HTML原先的内容里,是JS修改DOM树加入的。
这里涉及到一个概念, DOM节点 ,根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
整个文档是一个文档节点 |
---|
每个 HTML 元素是元素节点 |
HTML 元素内的文本是文本节点 |
每个 HTML 属性是属性节点 |
注释是注释节点 |
同时节点有父子节点之分,比如我们之前所说的DOM树的那个结构,table是tbody的父节点,反之tbody是table的子节点,而tr又是tbody的子节点。
Javascript对DOM树的操作是通过操作节点来实现了,比如上面的代码中,我们可以看到:
var p_el = document.getElementById('test');
这个就是使用JS方法document.getElementById
通过目标节点的ID属性找到节点id=”test”
,然后在对这个节点修改HTML内容。
首先我们知道,当浏览器收到来自服务器的HTML语言时,它需要进行解析。解析之后我们就能在浏览器界面看到各种颜色字样的样式呈现在我们的浏览器中了,那么我们需要了解浏览器的渲染机制是怎样一回事儿的:
解析顺序: | HTML > CSS > JS |
---|---|
解码顺序: | HTML解码>URL解码>JS解码 |
我们在细化一下,大概的处理过程是这几步:
序号 | 过程 |
---|---|
1 | 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree); |
2 | 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树; |
3 | 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件),修改DOM树、CSSOM树 |
4 | 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。 |
5 | 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置; |
6 | 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成; |
流程图如下:
这里需要说明的是:
①浏览器会尽可能快的展现内容,而不会等到文档所有内容到达才开始解析和构建布局渲染树,而是每次处理一部分,并展现在屏幕上,这也是为什么我们经常可以看到页面的时候内容是从上到下每次加载出一部分,就展示一部分的
②渲染还和浏览器支持的内核有关系,内核也可以理解为“渲染引擎”,浏览器支持的内核如下:
内核 | 浏览器 |
---|---|
Webkit | 谷歌(曾经)、Safari |
Gecko | 火狐 |
Blink | 谷歌(现在) |
Trident | IE(6、7、8、9、10) |
有的浏览器不止一种内核,可能是双核甚至是多核。
渲染树就代表一个文档的视觉展示,浏览器通过它将文档内容绘制在浏览器窗口,展示给用户,它由按顺序展示在屏幕上的一系列矩形对象组成,这些矩形对象都带有字体,颜色和尺寸,位置等视觉样式属性。
对于这些矩对象,FireFox称之为框架(frame),Webkit浏览器称之为渲染对象(render object, renderer),后文统称为渲染对象。
最终就是布局和绘制,布局是一个从上到下,从外到内进行的递归过程,从根渲染对象,即对应着HTML文档根元素,然后下一级渲染对象,如对应着元素,如此层层递归,依次计算每一个渲染对象的几何信息(位置和尺寸),然后通过绘制就是最终展现到我们眼前的情况。