不管你是React
、Angular
、Vue.js
,仍是原生JavaScript
開發者,你的代碼都有可能成爲黑客眼中的獵物。javascript
做爲一個前端開發者,咱們可能更加關注性能、SEO
、UI/UX
,每每會忽視安全問題。前端
當你瞭解了大型框架是如何讓你對xss攻擊保持開放態度時,也許你會感受到很意外。例如,React
中的dangerouslySetInnerHTML
或者Angular
中的bypassSecurityTrust
都是一些高危操做。java
咱們須要記住,就安全而言,前端如今和後端、DevOps
同樣承擔着相同的職責。前端也可能遭受到成千上萬的惡意攻擊。程序員
讓咱們來了解一下常見的攻擊類型有哪些。web
這種攻擊方式是將惡意文件上傳到服務器中並執行,從而攻擊系統。攻擊包括:文件系統或者數據庫超載、徹底接管系統、將攻擊轉發到後端系統或者簡單的破壞。chrome
這是一種誘導用戶點擊非本站網頁或元素的攻擊方式。這種攻擊可能致使用戶在不經意之間提供證書或者敏感信息,下載惡意軟件,訪問惡意網頁,在線購買產品或者被偷偷轉移資產。數據庫
譯者注:簡單的說就是在用戶觀看到的網站上覆蓋一層透明的惡意網站,誘導用戶點擊惡意網站上的按鈕來觸發攻擊行爲npm
這是一種將惡意腳本JS腳本注入到網頁中的攻擊方式。網站上的缺陷使這些攻擊得以成功並普遍傳播。後端
這是一種經過用戶輸入將惡意的SQL注入到數據庫中,進而破壞數據庫的攻擊方式。api
這是一種經過流量轟炸服務器,致使正常的用戶沒法正常訪問服務器的攻擊方式。
這是一種攔截客戶端和服務端之間的通訊,從中竊取用戶的密碼、帳號或者任何我的詳細信息的攻擊方式。
攻擊者將會竭盡全力的在前端尋找安全漏洞,在本文中,咱們將看到一些編寫前端代碼時安全相關的最佳實踐。
應該始終嚴格的對待用戶輸入,避免諸如SQL注入、點擊劫持等等。所以,在將用戶輸入發送到服務端以前,校驗並過濾用戶輸入是很重要的。
能夠經過刪除或替換危險的字符來過濾數據,例如,使用白名單並轉義輸入的數據。
可是,我意識到過濾和編碼用戶輸入並非一件容易的事,所以咱們可使用如下開源庫:
HTML5
、SVG
、MathML
中使用。HTML
、JavaScript
、內聯CSS
等等。當你想利用用戶的輸入生成JavaScript
或者CSS
時,這個庫特別好用。若是是文件上傳,請務必檢查文件類型而且使用文件過濾功能僅容許某些文件類型上傳。
若是咱們利用type="hidden"
來隱藏頁面中敏感數據,或者把他們放到瀏覽器的localStorage
、sessionStorage
、cookies
時,咱們須要謹慎的考慮這些數據是否安全。
攻擊者能夠輕鬆訪問添加到瀏覽器中的全部內容。攻擊者能夠打開開發工具並更改全部保存在內存中的變量。若是你根據localStorage
、sessionStorage
、cookies
中的值隱藏了身份驗證界面,該怎麼辦?
像ZapProxy這樣的工具,能夠在攻擊者找到注入腳本的方法後,將這些值暴露給攻擊者,而後攻擊者可使用它們進行進一步的攻擊。
所以,避免使用type="hidden"
,避免將密鑰、身份驗證令牌等儘量多的存到瀏覽器的內存中。
永遠不要相信服務器返回的全部內容,在Http header
中定義一個強大的CSP
策略,僅僅容許受信任的內容在瀏覽器中執行。
最好有一個白名單列表,即便攻擊者注入了腳本,該腳本和白名單不匹配,它也不會執行。
舉個例子:
// header
content-security-policy: script-src ‘self’ https://apis.xyz.com
複製代碼
這裏定義咱們的Web應用僅僅信任https://apis.xyz.com
和自己域名的腳本。對於其餘域名的資源都會在控制檯中報錯。
注意:強大CSP
策略也沒辦法解決內聯腳本執行的問題,所以xss
攻擊仍然存在。
你能夠在MDN網站上閱讀更詳細CSP
說明。
譯者注:不只能夠在header
中設置csp
規則,你也能夠在meta
標籤中設置。
若是攻擊者經過某種方式在用戶輸入中插入攻擊代碼,咱們能夠經過"X-XSS-Protection": "1; mode=block"
來告訴瀏覽器阻止響應。
大多數現代瀏覽器默認狀況下都啓用了XSS保護模式,但仍建議添加X-XSS-Protection
。 這有助於提升不支持CSP
的舊版瀏覽器的安全性。
Dom API innerHTML
常常被用做XSS
攻擊的入口。例如:
document.querySelector('.tagline').innerHTML = nameFromQueryString
複製代碼
任何攻擊者均可以使用上面的代碼行注入惡意代碼。
你們能夠考慮使用textContent
來代替innerHTML
,避免直接生成HTML
。若是你不生成HTML
,那就不會有JavaScript
插入到頁面中,即便你能夠在頁面中看到攻擊代碼,可是,什麼也不會發生。
密切關注Trusted Types(MDN地址),這是由google程序員開發出來的,旨在防範全部基於DOM的XSS攻擊的方案。
在React.js中,dangerouslySetInnerHTML
可能產生和innerHTML
相似的影響。
注意:不要直接將用戶輸入作了innerHTML
的值,儘可能使用textContent
。
另外,咱們應該正常的設置http響應頭Content-Type
和X-Content-Type-Options
。例如,請勿將JSON
數據編碼成text/HTML
,以避免意外執行。
禁用iframe
能夠幫助咱們免受點擊劫持攻擊。咱們應該在header中添加"X-Frame-Options": "DENY"
,來禁止瀏覽器在頁面中渲染iframe
。
咱們也可使用CSP指令frame-ancestors
,它能夠更好的控制咱們的頁面能夠被哪些父頁面經過iframe
的形式來嵌套展現。
相似"您的密碼有誤"這樣的提示對用戶很友好,同時,他對攻擊者也很友好。他們能夠經過服務端返回的錯誤信息來判斷他下一步須要進行什麼樣的攻擊。
當處理用戶的帳號、郵件、我的信息時,咱們應該嘗試使用一些模棱兩可的錯誤提示,相似「錯誤的登錄信息」。
在對外的公共服務(登錄、註冊)上使用驗證碼。驗證碼的目的在於幫助咱們區分真人和機器人,而且也能夠阻止DoS攻擊。
Referrer-Policy
當咱們使用<a>
標籤或者超連接引導用戶離開咱們的網站時,確保你在請求header裏面添加了"Referrer-Policy": "no-referrer"
,或者在<a>
標籤中添加了rel="noopener"
或rel="noreferrer"
屬性。
當咱們不設置header
或者rel
屬性時,目標網站就能夠獲取到一些用戶相關的數據。
譯者注:rel=noopener
保證跳轉過去的網站沒法經過window.opener
竊取原來網頁的信息。rel=noreferrer
做用是防止將引用者信息傳遞到目標網站。上面提到的策略你們能夠去mdn上了解一下MDN Referrer-Policy、MDN Link Type
就像CSP
能夠限制可信的資源域名同樣,咱們也能夠限制瀏覽器提供哪些能力給咱們用。咱們能夠利用http header中的Feature-Policy
字段來限制使用瀏覽器提供的功能。
提示:禁用一切你不使用的功能
譯者注:Feature-Policy
是一個實驗中的header
屬性,目前在chrome
瀏覽器中的兼容性尚可,IE
和Safari
都不支持。具體能夠在MDN Feature-Policy中瞭解。
常常跑一下npm audit
來獲取存在漏洞的npm包列表,升級他們避免一些安全問題。
GitHub
如今會標記出哪些存在漏洞的依賴。咱們也可使用Snyk
來自動檢查你的源碼,而且自動升級版本號。
與後端同樣,咱們也擁有微服務架構,其中,將單一的Web應用轉變爲多個小型前端應用的聚合,每一個小型前端應用能夠單獨運行。
相同的原理能夠應用於前端。 例如,一個Web應用能夠分爲公共部分,身份驗證部分和後臺管理部分,每一個應用都託管在單獨的子域中,例如https://public.example.com
、https://users.example.com
和https://admin.example.com
。這將減小web應用中的漏洞。
注意:適當的分隔還能夠防止應用程序公共部分出現XSS漏洞,從而防止它自動破壞用戶信息。
一行代碼就可使用相似Google Analytics
的第三方服務,同時,也可能會給你的應用帶來漏洞。想想這些第三方服務腳本被篡改的狀況。
擁有一套健全的CSP
策略很重要。大多數第三方服務都有定義的CSP
指令,所以請務必添加它們。
一樣,若是可能的話,請確保給你的script
標籤都加上integrity
屬性。子資源完整性功能(SRI
)能夠驗證腳本的hash
值,並確保其未被篡改。
<script src= "https://example.com/example-framework.js" integrity= "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin= "anonymous" ></script>
複製代碼
譯者注:將使用base64編碼
事後的文件哈希值寫入你所引用的 <script>
或 <link>
標籤的 integrity
屬性值中便可啓用子資源完整性校驗功能。
存儲在瀏覽器的自動填充裏面的用戶我的數據對用戶和攻擊者都很方便。
攻擊者添加了第三方的腳本,利用瀏覽器的自動填充來提取用戶的郵箱地址去構建追蹤標識。他們可使用這些信息創建用戶瀏覽歷史記錄配置文件,而後將其出售給壞人。
咱們許多人甚至都不知道他們的瀏覽器自動填充功能存儲了哪些信息。
提示:禁止將敏感信息自動填入表單
譯者注:MDN中也有一個web安全相關的專題,你們有興趣能夠關注一下MDN web security
我是一個莫得感情的代碼搬運工,最近搞了一個公衆號,每週會按期更新一、2篇前端文章,你們有興趣的話關注一下,咱們一塊兒交流前端知識~
好啦,翻譯完畢啦, 原文連接在此。