前言
本系列最開始是為了自己面試準備的.後來發現整理越來越多,差不多有十二萬字元,最後決定還是分享出來給大家.
為了分享整理出來,花費了自己大量的時間,起碼是隻自己用的三倍時間.如果喜歡的話,歡迎收藏,關注我!謝謝!
文章連結
- 前端面試查漏補缺--(一) 防抖和節流
- 前端面試查漏補缺--(二) 垃圾回收機制
- 前端面試查漏補缺--(三) 跨域及常見解決辦法
- 前端面試查漏補缺--(四) 前端本地儲存
- 前端面試查漏補缺--(五) 渲染機制及重繪和迴流
- 前端面試查漏補缺--(六) 瀏覽器快取
- 前端面試查漏補缺--(七) XSS攻擊與CSRF攻擊
- 前端面試查漏補缺--(八) 前端加密
- 前端面試查漏補缺--(九) HTTP與HTTPS
- 前端面試查漏補缺--(十) 前端鑑權
- 前端面試查漏補缺--(十一) 前端軟體架構模式MVC/MVP/MVVM
- 前端面試查漏補缺--(十二) 從輸入URL到看到頁面發生的全過程(含三握手,四揮手詳解)
- 前端面試查漏補缺--(十三) 記憶體洩漏
- 前端面試查漏補缺--(十四) 演算法及排序
- 前端面試查漏補缺--(十五) Event Loop
合集篇:
前端面試查漏補缺--Index篇(12萬字元合集) 包含目前已寫好的系列其他十幾篇文章.後續新增值文章不會再在每篇新增連結,強烈建議議點贊,關注合集篇!!!!,謝謝!~
後續更新計劃
後續還會繼續新增設計模式,前端工程化,專案流程,部署,閉環,vue常考知識點 等內容.如果覺得內容不錯的話歡迎收藏,關注我!謝謝!
求一份內推
目前本人也在準備跳槽,希望各位大佬和HR小姐姐可以內推一份靠譜的武漢 前端崗位!郵箱:bupabuku@foxmail.com.謝謝啦!~
XSS攻擊
什麼是 XSS
Cross-Site Scripting(跨站指令碼攻擊)簡稱 XSS,是一種程式碼注入攻擊。攻擊者通過在目標網站上注入惡意指令碼,使之在使用者的瀏覽器上執行。利用這些惡意指令碼,攻擊者可獲取使用者的敏感資訊如 Cookie、SessionID 等,進而危害資料安全。
所以,網頁上哪些部分會引起XSS攻擊?簡單來說,任何可以輸入的地方都有可能引起,包括URL!
XSS 常見的注入方法:
- 在 HTML 中內嵌的文字中,惡意內容以 script 標籤形成注入。
- 在內聯的 JavaScript 中,拼接的資料突破了原本的限制(字串,變數,方法名等)。
- 在標籤屬性中,惡意內容包含引號,從而突破屬性值的限制,注入其他屬性或者標籤。
- 在標籤的 href、src 等屬性中,包含
javascript:
(偽協議)等可執行程式碼。 - 在 onload、onerror、onclick 等事件中,注入不受控制程式碼。
- 在 style 屬性和標籤中,包含類似
background-image:url("javascript:...");
的程式碼(新版本瀏覽器已經可以防範)。 - 在 style 屬性和標籤中,包含類似
expression(...)
的 CSS 表示式程式碼(新版本瀏覽器已經可以防範)。
XSS 攻擊的分類
根據攻擊的來源,XSS 攻擊可分為儲存型、反射型和 DOM 型三種。
儲存型 XSS
儲存型 XSS 的攻擊步驟:
- 攻擊者將惡意程式碼提交到目標網站的資料庫中。
- 使用者開啟目標網站時,網站服務端將惡意程式碼從資料庫取出,拼接在 HTML 中返回給瀏覽器。
- 使用者瀏覽器接收到響應後解析執行,混在其中的惡意程式碼也被執行。
- 惡意程式碼竊取使用者資料併傳送到攻擊者的網站,或者冒充使用者的行為,呼叫目標網站介面執行攻擊者指定的操作。
儲存型 XSS(又被稱為永續性XSS)攻擊常見於帶有使用者儲存資料的網站功能,如論壇發帖、商品評論、使用者私信等。
它是最危險的一種跨站指令碼,相比反射型XSS和DOM型XSS具有更高的隱蔽性,所以危害更大,因為它不需要使用者手動觸發。任何允許使用者儲存資料的web程式都可能存在儲存型XSS漏洞,當攻擊者提交一段XSS程式碼後,被伺服器端接收並儲存,當所有瀏覽者訪問某個頁面時都會被XSS。
反射型 XSS
反射型 XSS 的攻擊步驟:
- 攻擊者構造出特殊的 URL,其中包含惡意程式碼。
- 使用者開啟帶有惡意程式碼的 URL 時,網站服務端將惡意程式碼從 URL 中取出,拼接在 HTML 中返回給瀏覽器。
- 使用者瀏覽器接收到響應後解析執行,混在其中的惡意程式碼也被執行。
- 惡意程式碼竊取使用者資料併傳送到攻擊者的網站,或者冒充使用者的行為,呼叫目標網站介面執行攻擊者指定的操作。
反射型 XSS 跟儲存型 XSS 的區別是:儲存型 XSS 的惡意程式碼存在資料庫裡,反射型 XSS 的惡意程式碼存在 URL 裡。
反射型 XSS (也被稱為非永續性XSS)漏洞常見於通過 URL 傳遞引數的功能,如網站搜尋、跳轉等。
由於需要使用者主動開啟惡意的 URL 才能生效,攻擊者往往會結合多種手段誘導使用者點選。
POST 的內容也可以觸發反射型 XSS,只不過其觸發條件比較苛刻(需要構造表單提交頁面,並引導使用者點選),所以非常少見。
DOM 型 XSS
DOM 型 XSS 的攻擊步驟:
- 攻擊者構造出特殊的 URL,其中包含惡意程式碼。
- 使用者開啟帶有惡意程式碼的 URL。
- 使用者瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意程式碼並執行。
- 惡意程式碼竊取使用者資料併傳送到攻擊者的網站,或者冒充使用者的行為,呼叫目標網站介面執行攻擊者指定的操作。
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, '<') str = str.replace(/>/g, '>') str = str.replace(/"/g, '&quto;') str = str.replace(/'/g, ''') str = str.replace(/`/g, '`') str = str.replace(/\//g, '/') return str } 複製程式碼
-
白名單: 對於顯示富文字來說,不能通過上面的辦法來轉義所有字元,因為這樣會把需要的格式也過濾掉。這種情況通常採用白名單過濾的辦法,當然也可以通過黑名單過濾,但是考慮到需要過濾的標籤和標籤屬性實在太多,更加推薦使用白名單的方式。
預防儲存型和反射型 XSS 攻擊
儲存型和反射型 XSS 都是在服務端取出惡意程式碼後,插入到響應 HTML 裡的,攻擊者刻意編寫的“資料”被內嵌到“程式碼”中,被瀏覽器所執行。
預防這兩種漏洞,有兩種常見做法:
- 改成純前端渲染,把程式碼和資料分隔開。
- 對 HTML 做充分轉義。
HTML轉義前面已經說過,這裡僅僅談談純前端渲染
純前端渲染的過程:
- 瀏覽器先載入一個靜態 HTML,此 HTML 中不包含任何跟業務相關的資料。
- 然後瀏覽器執行 HTML 中的 JavaScript。
- JavaScript 通過 Ajax 載入業務資料,呼叫 DOM API 更新到頁面上。
在純前端渲染中,我們會明確的告訴瀏覽器:下面要設定的內容是文字(.innerText
),還是屬性(.setAttribute
),還是樣式(.style
)等等。瀏覽器不會被輕易的被欺騙,執行預期外的程式碼了。
但純前端渲染還需注意避免 DOM 型 XSS 漏洞(例如 onload
事件和 href
中的 javascript:xxx
等,請參考下文”預防 DOM 型 XSS 攻擊“部分)。
在很多內部、管理系統中,採用純前端渲染是非常合適的。但對於效能要求高,或有 SEO 需求的頁面,我們仍然要面對拼接 HTML 的問題,這時就需要對HTML進行充分的轉義。
預防 DOM 型 XSS 攻擊
DOM 型 XSS 攻擊,實際上就是網站前端 JavaScript程式碼本身不夠嚴謹,把不可信的資料當作程式碼執行了。
在使用 .innerHTML
、.outerHTML
、document.write()
時要特別小心,不要把不可信的資料作為 HTML 插到頁面上,而應儘量使用 .textContent
、.setAttribute()
等。
如果用 Vue/React 技術棧,並且不使用 v-html
/dangerouslySetInnerHTML
功能,就在前端 render 階段避免 innerHTML
、outerHTML
的 XSS 隱患。
DOM 中的內聯事件監聽器,如 location
、onclick
、onerror
、onload
、onmouseover
等,<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攻擊?
感謝及參考
- 前端安全系列(一):如何防止XSS攻擊? (真的非常詳細!)
- 前端安全系列之二:如何防止CSRF攻擊?(真的非常詳細!+1)