文章目錄
Web安全2.3:CSP安全策略、Cookie、Session、同源策略、HTML DOM樹
一、CSP安全策略:
瀏覽器是XSS等前端攻擊的戰場,有些瀏覽器附帶一些安全策略,包含自帶的XSS過濾、同源策略等。
W3C組織還針對XSS攻擊制定了一個叫做CSP的安全層,也就是內容安全策略(Content Security Policy)。它的出現是爲了幫助檢測和緩解某些類型的攻擊,比如跨站腳本(XSS)和數據注入等攻擊,從而引入的瀏覽器策略。開發者可以根據CSP的規範,去創建一些很嚴格的規則,比如說白名單策略,管理網站允許加載的內容。當網站加載了非預期的內容,瀏覽器會及時阻止並且上報,減少出現安全風險時的損失。
1、CSP的部分命令:
CSP有兩種指令方式:
(1)HTTPheader:比如在HTTP的響應頭中設置Content-Security-Policy的值。
(2)HTML:比如在html裏插入meta標籤來實現。
如果都設置的話,以HTTP響應頭裏的爲準
2、策略控制:
這裏使用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"/>
(1)首先我們先把meta標籤註釋掉,如下:
接着我們打開火狐瀏覽器,然後進行訪問:
我們發現底下的紅色字跡提示內容的安全政策,表明header生效了,只允許加載本地源圖片。
除此之外,我們在網絡模塊中,可以看到響應頭中的確出現了安全政策。
(2)我們這次只註釋掉header:
然後我們發現加載出了圖片,哈哈。
(3)兩段CSP代碼都不註釋:
阿哦!我們的圖片找不到了,說明HTTP頭起作用了。
3、CSP完整命令:
指令 | 說明 |
---|---|
base-url | 文檔的基準URL |
child-src | web workers 以及嵌套的瀏覽上下文(如<frame> 和<iframe> )的源 |
connect-src | 請求、XMLHttpRequest、WebSocket和EvenSource的連接來源 |
default-src | child-src connect-src font-src:控制字體文件來源 img-src:控制圖片來源 media-src:控制video和audio標籤裏的資源來源 object-src:控制 <object> 、<embed> 、<applet> 標籤裏資源的來源script-src:控制JavaScript的有效來源 style-src:控制css的有效來源 |
plugin-types | 控制<object> 、<embed> 、<applet> 插件資源的來源 |
reflected-xss | 控制瀏覽器對於反射型xss的策略 |
report-url | 用於接收瀏覽器發送違反CSP頁面的報告地址 |
sandbox | 控制是否控制阻止彈窗,插件,腳本執行等 |
二、Cookie安全:
cookie:由於HTTP協議是無狀態的,因此要跟蹤用戶的狀態比如登陸信息,就得在每一個HTTP請求中多放一段數據來進行標記。
http規範中已經設計好了一個位置讓你存放,就是消息頭中的cookie段。而cookie可以由服務端發送指令或者客戶端通過JavaScript腳本讓瀏覽器生成並保存。
Cookie,有時也用其複數形式 Cookies,指某些網站爲了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。定義於 RFC2109 和 2965 中的都已廢棄,最新取代的規範是 RFC6265 (可以叫做瀏覽器緩存)。
這個Cookie一般是有期限的,當攻擊者盜取了用戶沒有失效的Cookie時,就相當於有了用戶的用戶名和密碼。
我們來舉兩個例子來說明:
1、服務端如何在響應的消息頭中告訴瀏覽器設置一個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的配套組合。
2、修改cookie:
(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:
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://(加密)作爲協議前綴。該協議不實行同源政策,只要服務器支持,就可以通過它進行跨源通信。
五、HTML DOM樹:
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樹結構。
1、節點:
下面我舉個例子:
<!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>
效果如下:
上面部分中的代碼如下:
<script>
var p_el = document.getElementById('test');
p_el.innerHTML="JS修改的內容";
</script>
這部分代碼,導致了頁面中出現了一行文字內容"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內容。
2、瀏覽器的渲染機制:
首先我們知道,當瀏覽器收到來自服務器的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文檔根元素,然後下一級渲染對象,如對應着元素,如此層層遞歸,依次計算每一個渲染對象的幾何信息(位置和尺寸),然後通過繪製就是最終展現到我們眼前的情況。