前端面試查漏補缺--(七) XSS攻擊與CSRF攻擊

前言

本系列最開始是爲了本身面試準備的.後來發現整理愈來愈多,差很少有十二萬字符,最後決定仍是分享出來給你們.javascript

爲了分享整理出來,花費了本身大量的時間,起碼是隻本身用的三倍時間.若是喜歡的話,歡迎收藏,關注我!謝謝!php

文章連接

合集篇:

前端面試查漏補缺--Index篇(12萬字符合集) 包含目前已寫好的系列其餘十幾篇文章.後續新增值文章不會再在每篇添加連接,強烈建議議點贊,關注合集篇!!!!,謝謝!~html

後續更新計劃

後續還會繼續添加設計模式,前端工程化,項目流程,部署,閉環,vue常考知識點 等內容.若是以爲內容不錯的話歡迎收藏,關注我!謝謝!前端

求一分內推

目前本人也在準備跳槽,但願各位大佬和HR小姐姐能夠內推一份靠譜的武漢 前端崗位!郵箱:bupabuku@foxmail.com.謝謝啦!~vue

XSS攻擊

什麼是 XSS

Cross-Site Scripting(跨站腳本攻擊)簡稱 XSS,是一種代碼注入攻擊。攻擊者經過在目標網站上注入惡意腳本,使之在用戶的瀏覽器上運行。利用這些惡意腳本,攻擊者可獲取用戶的敏感信息如 Cookie、SessionID 等,進而危害數據安全。java

因此,網頁上哪些部分會引發XSS攻擊?簡單來講,任何能夠輸入的地方都有可能引發,包括URL!web

XSS 常見的注入方法:面試

  • 在 HTML 中內嵌的文本中,惡意內容以 script 標籤造成注入。
  • 在內聯的 JavaScript 中,拼接的數據突破了本來的限制(字符串,變量,方法名等)。
  • 在標籤屬性中,惡意內容包含引號,從而突破屬性值的限制,注入其餘屬性或者標籤。
  • 在標籤的 href、src 等屬性中,包含 javascript: (僞協議)等可執行代碼。
  • 在 onload、onerror、onclick 等事件中,注入不受控制代碼。
  • 在 style 屬性和標籤中,包含相似 background-image:url("javascript:..."); 的代碼(新版本瀏覽器已經能夠防範)。
  • 在 style 屬性和標籤中,包含相似 expression(...) 的 CSS 表達式代碼(新版本瀏覽器已經能夠防範)。

XSS 攻擊的分類

根據攻擊的來源,XSS 攻擊可分爲存儲型、反射型和 DOM 型三種。算法

存儲型 XSS

存儲型 XSS 的攻擊步驟:數據庫

  1. 攻擊者將惡意代碼提交到目標網站的數據庫中。
  2. 用戶打開目標網站時,網站服務端將惡意代碼從數據庫取出,拼接在 HTML 中返回給瀏覽器。
  3. 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。

存儲型 XSS(又被稱爲持久性XSS)攻擊常見於帶有用戶保存數據的網站功能,如論壇發帖、商品評論、用戶私信等。

它是最危險的一種跨站腳本,相比反射型XSS和DOM型XSS具備更高的隱蔽性,因此危害更大,由於它不須要用戶手動觸發任何容許用戶存儲數據的web程序均可能存在存儲型XSS漏洞,當攻擊者提交一段XSS代碼後,被服務器端接收並存儲,當全部瀏覽者訪問某個頁面時都會被XSS

反射型 XSS

反射型 XSS 的攻擊步驟:

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 用戶打開帶有惡意代碼的 URL 時,網站服務端將惡意代碼從 URL 中取出,拼接在 HTML 中返回給瀏覽器。
  3. 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。

反射型 XSS 跟存儲型 XSS 的區別是:存儲型 XSS 的惡意代碼存在數據庫裏,反射型 XSS 的惡意代碼存在 URL 裏。

反射型 XSS (也被稱爲非持久性XSS)漏洞常見於經過 URL 傳遞參數的功能,如網站搜索、跳轉等。

因爲須要用戶主動打開惡意的 URL 才能生效,攻擊者每每會結合多種手段誘導用戶點擊。

POST 的內容也能夠觸發反射型 XSS,只不過其觸發條件比較苛刻(須要構造表單提交頁面,並引導用戶點擊),因此很是少見。

DOM 型 XSS

DOM 型 XSS 的攻擊步驟:

  1. 攻擊者構造出特殊的 URL,其中包含惡意代碼。
  2. 用戶打開帶有惡意代碼的 URL。
  3. 用戶瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意代碼並執行。
  4. 惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。

DOM 型 XSS 跟前兩種 XSS 的區別:DOM 型 XSS 攻擊中,取出和執行惡意代碼由瀏覽器端完成,屬於前端 JavaScript 自身的安全漏洞,而其餘兩種 XSS 都屬於服務端的安全漏洞。

注意:
DOM一般表明在html、xhtml和xml中的對象,使用DOM能夠容許程序和腳本動態的訪問和更新文檔的內容、結構和樣式。它不須要服務器解析響應的直接參與,觸發XSS靠的是瀏覽器端的DOM解析,因此防範DOM型XSS徹底就是前端的責任,必須注意!!!

對比:

類型 存儲區 插入點
存儲型 XSS 後端數據庫 HTML
反射型 XSS URL HTML
DOM 型 XSS 後端數據庫/前端存儲/URL 前端 JavaScript

防護XSS

只要有輸入數據的地方,就可能存在 XSS 危險。

經常使用防範方法

  • httpOnly: 在 cookie 中設置 HttpOnly 屬性後,js腳本將沒法讀取到 cookie 信息。

  • 輸入過濾: 通常是用於對於輸入格式的檢查,例如:郵箱,電話號碼,用戶名,密碼……等,按照規定的格式輸入。不只僅是前端負責,後端也要作相同的過濾檢查。由於攻擊者徹底能夠繞過正常的輸入流程,直接利用相關接口向服務器發送設置。

  • 轉義 HTML: 若是拼接 HTML 是必要的,就須要對於引號,尖括號,斜槓進行轉義,但這還不是很完善.想對 HTML 模板各處插入點進行充分的轉義,就須要採用合適的轉義庫.(能夠看下這個,仍是中文的)

    function escape(str) {
      str = str.replace(/&/g, '&')
      str = str.replace(/</g, '&lt;')
      str = str.replace(/>/g, '&gt;')
      str = str.replace(/"/g, '&quto;')
      str = str.replace(/'/g, '&#39;')
      str = str.replace(/`/g, '&#96;')
      str = str.replace(/\//g, '&#x2F;')
      return str
    }
    複製代碼
  • 白名單: 對於顯示富文原本說,不能經過上面的辦法來轉義全部字符,由於這樣會把須要的格式也過濾掉。這種狀況一般採用白名單過濾的辦法,固然也能夠經過黑名單過濾,可是考慮到須要過濾的標籤和標籤屬性實在太多,更加推薦使用白名單的方式。

預防存儲型和反射型 XSS 攻擊

存儲型和反射型 XSS 都是在服務端取出惡意代碼後,插入到響應 HTML 裏的,攻擊者刻意編寫的「數據」被內嵌到「代碼」中,被瀏覽器所執行。

預防這兩種漏洞,有兩種常見作法:

  • 改爲純前端渲染,把代碼和數據分隔開。
  • 對 HTML 作充分轉義。

HTML轉義前面已經說過,這裏僅僅談談純前端渲染

純前端渲染的過程:

  1. 瀏覽器先加載一個靜態 HTML,此 HTML 中不包含任何跟業務相關的數據。
  2. 而後瀏覽器執行 HTML 中的 JavaScript。
  3. JavaScript 經過 Ajax 加載業務數據,調用 DOM API 更新到頁面上。

在純前端渲染中,咱們會明確的告訴瀏覽器:下面要設置的內容是文本(.innerText),仍是屬性(.setAttribute),仍是樣式(.style)等等。瀏覽器不會被輕易的被欺騙,執行預期外的代碼了。

但純前端渲染還需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,請參考下文」預防 DOM 型 XSS 攻擊「部分)。

在不少內部、管理系統中,採用純前端渲染是很是合適的。但對於性能要求高,或有 SEO 需求的頁面,咱們仍然要面對拼接 HTML 的問題,這時就須要對HTML進行充分的轉義。

預防 DOM 型 XSS 攻擊

DOM 型 XSS 攻擊,實際上就是網站前端 JavaScript代碼自己不夠嚴謹,把不可信的數據看成代碼執行了。

在使用 .innerHTML.outerHTMLdocument.write() 時要特別當心,不要把不可信的數據做爲 HTML 插到頁面上,而應儘可能使用 .textContent.setAttribute() 等。

若是用 Vue/React 技術棧,而且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 階段避免 innerHTMLouterHTML 的 XSS 隱患。

DOM 中的內聯事件監聽器,如 locationonclickonerroronloadonmouseover 等,<a> 標籤的 href 屬性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串做爲代碼運行。若是不可信的數據拼接到字符串中傳遞給這些 API,很容易產生安全隱患,請務必避免。

<!-- 內聯事件監聽器中包含惡意代碼 -->
<img onclick="UNTRUSTED" onerror="UNTRUSTED" src="data:image/png,"> <!-- 連接內包含惡意代碼 --> <a href="UNTRUSTED">1</a> <script> // setTimeout()/setInterval() 中調用惡意代碼 setTimeout("UNTRUSTED") setInterval("UNTRUSTED") // location 調用惡意代碼 location.href = 'UNTRUSTED' // eval() 中調用惡意代碼 eval("UNTRUSTED") </script> 複製代碼

CSRF 跨站點請求僞造

什麼是 CSRF

跨站請求僞造(英語:Cross-site request forgery),也被稱爲 one-click attack 或者 session riding,一般縮寫爲 CSRF 或者 XSRF, 是一種挾制用戶在當前已登陸的 Web 應用程序上執行非本意的操做的攻擊方法。如:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的註冊憑證,繞事後臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操做的目的。

CSRF攻擊流程

下圖引自這位大佬的淺談CSRF攻擊方式,感謝!

簡而言之:網站過度相信用戶

從上圖能夠看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:

  • 1.登陸受信任網站A,並在本地生成Cookie。
  • 2.在不登出A的狀況下,訪問危險網站B。

看到這裏,你也許會說:「若是我不知足以上兩個條件中的一個,我就不會受到CSRF的攻擊」。是的,確實如此,但你不能保證如下狀況不會發生:

  • 1.你不能保證你登陸了一個網站後,再也不打開一個tab頁面並訪問另外的網站。
  • 2.你不能保證你關閉瀏覽器了後,你本地的Cookie馬上過時,你上次的會話已經結束。(事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認爲關閉瀏覽器就等於退出登陸/結束會話了......)
  • 3.上圖中所謂的攻擊網站,多是一個存在其餘漏洞的可信任的常常被人訪問的網站。

常見的CSRF攻擊類型

  • GET類型的CSRF

GET類型的CSRF利用很是簡單,只須要一個HTTP請求,通常會這樣利用:

<img src="http://bank.example/withdraw?amount=10000&for=hacker" > 
複製代碼

在受害者訪問含有這個img的頁面後,瀏覽器會自動向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker發出一次HTTP請求。bank.example就會收到包含受害者登陸信息的一次跨域請求。

  • POST類型的CSRF

這種類型的CSRF利用起來一般使用的是一個自動提交的表單,如:

<form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 
複製代碼

訪問該頁面後,表單會自動提交,至關於模擬用戶完成了一次POST操做。

POST類型的攻擊一般比GET要求更加嚴格一點,但仍並不複雜。任何我的網站、博客,被黑客上傳頁面的網站都有多是發起攻擊的來源,後端接口不能將安全寄託在僅容許POST上面

  • 連接類型的CSRF

連接類型的CSRF並不常見,比起其餘兩種用戶打開頁面就中招的狀況,這種須要用戶點擊連接纔會觸發。這種類型一般是在論壇中發佈的圖片中嵌入惡意連接,或者以廣告的形式誘導用戶中招,攻擊者一般會以比較誇張的詞語誘騙用戶點擊,例如:

<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
  <a/>
複製代碼

CSRF的特色

  • 攻擊通常發起在第三方網站,而不是被攻擊的網站。被攻擊的網站沒法防止攻擊發生。
  • 攻擊利用受害者在被攻擊網站的登陸憑證,冒充受害者提交操做;而不是直接竊取數據。
  • 整個過程攻擊者並不能獲取到受害者的登陸憑證,僅僅是「冒用」。
  • 跨站請求能夠用各類方式:圖片URL、超連接、CORS、Form提交等等。部分請求方式能夠直接嵌入在第三方論壇、文章中,難以進行追蹤。

CSRF一般是跨域的,由於外域一般更容易被攻擊者掌控。可是若是本域下有容易被利用的功能,好比能夠發圖和連接的論壇和評論區,攻擊能夠直接在本域下進行,並且這種攻擊更加危險。

CSRF與 XSS 區別

  • 一般來講 CSRF 是由 XSS 實現的,CSRF 時常也被稱爲 XSRF(CSRF 實現的方式還能夠是直接經過命令行發起請求等)。
  • 本質上講,XSS 是代碼注入問題,CSRF 是 HTTP 問題。 XSS 是內容沒有過濾致使瀏覽器將攻擊者的輸入當代碼執行。CSRF 則是由於瀏覽器在發送 HTTP 請求時候自動帶上 cookie,而通常網站的 session 都存在 cookie裏面(Token驗證能夠避免)。

防護

  • 驗證碼;強制用戶必須與應用進行交互,才能完成最終請求。此種方式能很好的遏制 csrf,可是用戶體驗比較差。

  • Referer check;請求來源限制,此種方法成本最低,可是並不能保證 100% 有效,由於服務器並非何時都能取到 Referer,並且低版本的瀏覽器存在僞造 Referer 的風險。

  • token;token 驗證的 CSRF 防護機制是公認最合適的方案。(具體能夠查看本系列前端鑑權中對token有詳細描述)若網站同時存在 XSS 漏洞的時候,這個方法也是空談。

其餘更詳細的防護方法能夠查看: 前端安全系列之二:如何防止CSRF攻擊?

感謝及參考

相關文章
相關標籤/搜索