Stories

Detail Return Return

前端安全13條,除了XSS/CSRF你還知道哪些? - Stories Detail

大家好,我是沐華。最近面了一些前端,發現每次問到安全相關的問題,一些面試者只能説上來 XSS、CSRF、中間人攻擊,就沒了,於是寫了這篇文章,總結了前端安全相關的點,給大家查缺補漏

瀏覽器

XSS

XSS 攻擊是一種代碼注入攻擊,通過惡意注入腳本在瀏覽器運行,然後盜取用户信息。本質上其實是因為網站沒有過濾惡意代碼,與正常代碼混在一起之後,瀏覽器沒有辦法分辨哪些是可信的,然後導致惡意代碼也被執行

結果是可能會導致:頁面數據或用户信息被竊取、偽造登錄窗口或在頁面生成浮窗廣告、監聽鍵盤事件竊取賬號密碼、流量被支持到其他網站等

XSS 攻擊有三種類型:

  1. 存儲型:通過輸入框把惡意代碼提交到網站數據庫中,然後比如在顯示評論的頁面就會從數據獲取,並直接執行
  2. 反射型:和存儲型不同的是不會儲存在服務器裏。比如打開包含帶惡意腳本的鏈接,當打開後會向服務器請求後,服務器會獲取URL中的數據然後拼接在HTML上返回,然後執行
  3. 基於DOM型:是通過一些劫持手段,在頁面資源傳輸過程中劫持並修改頁面的數據,插入惡意代碼

防範:比如對輸入框內容進行過濾和用轉義符進行轉碼、添加白名單、關閉 Cookie 訪問權限、使用驗證碼防止腳本偽裝成用户執行操作等

CSRF

CSRF 就是跨站請求偽造攻擊,主要就是利用用户的登錄狀態發起跨站請求

比如郵箱裏的亂七八糟的鏈接,打開鏈接的時候郵箱肯定是處於登錄狀態,然後黑客就可以用這個登錄狀態,偽造帶有正確 Cookiehttp 請求,直接繞過後台的登錄驗證,然後冒充用户執行一些操作,本質是利用 Cookie 在同源請求中攜帶發送給服務器的特點,來實現冒充用户

發起 CSRF 攻擊有幾個必要條件:

  1. 目標網站一定要有 CSRF 漏洞
  2. 用户登錄過目標網站,並且瀏覽器保存了登錄狀態
  3. 需要用户主動打開第三方站點

CSRF 攻擊也有三種類型:

  • 自動發GET類型:比如imgiframe標籤等,當用户打開這個網站時會自動發起帶 Cookie 的資源請求
  • 自動發POST類型:比如整一個隱藏的表單,在用户進入頁面的時候自動提交表單
  • 誘導鏈接型:就是誘導用户主動點擊鏈接,比如a標籤

防範:比如 Token 驗證、雙重 Cookie、通過 origin/referer 驗證請求來源等

CSP

CSP 就是白名單,作用是可以禁止加載外域的代碼,禁止外域的提交,只允許本域下的請求表單提交之類的,簡單説就是告訴瀏覽器哪些資源可以加載執行,讓那些真的插入進入的惡意代碼也不會被執行;或者允許向哪些第三方站點提交數據,因為攻擊者竊取信息的根本還是向外域提交

開啓 CSP 的方式有兩種

1. meta

<meta http-equiv="content-security-policy" content="policy">
<meta http-equiv="content-security-policy-report-only" content="policy">

2. http request header

如果不支持 Content-Security-Policy,可以用 X-XSS-Proterction 代替

# 所加載的內容必須來自同源站點
Content-Security-Policy: default-src "self"
# 添加可信域名
Content-Security-Policy: *.baidu.com
# 和上面同理
Content-Security-Policy-Report-Only: policy

HSTS

HSTSHTTP 嚴格傳輸安全協議,作用是強制客户端使用 https 與服務器建立連接,以避免因為 http 而被中間人攻擊

HSTS 設置須添加在請求頭中,如下

Strict-Transport-Security: max-age=12345;includeSubDomains;

參數:

  • max-age: 指定該設置過期的時間,單位毫秒
  • includeSubDomains: 可選參數,表示所有子域名也必須通過 https 訪問
  • preload: 可選參數,可以設置一個使用 https 的域名列表

設置 HSTS 後,再使用 http 訪問時,只要 max-age 沒有過期,客户端內部會進行跳轉,會出現 307 Redirect Internel 狀態碼,變成 https 後,再訪問請求的資源服務器

X-Frame-Options

X-Frame-Options 是用於控制當前頁面是否可以被嵌入到 iframe 中,以防盜鏈及點擊劫持攻擊

X-Frame-Options 設置須添加在請求頭中,如下

X-Frame-Options: DENY

參數:

  • DENY: 不允許,同域名嵌套也不行
  • SAMEORIGIN: 允許同域名嵌套
  • ALLOW_FORM url: 可以指定允許嵌套訪問的來源

設置 X-Frame-Options 後,可以確保我們的網站沒有被嵌入到別人的站點裏去(以防內容被惡意嵌套,並且在表面加一個透明層,誘導用户點擊),從而避免點擊劫持攻擊及惡意盜鏈

SRI

SRI 指子資源完整性,該方案的作用是確保我們站點的資源文件永遠不會被改變,如果被改變,瀏覽器會拒絕執行

比如我們打包的時候有一個 xxx.js 文件,被 index.html 引用,並上傳 CDN,用户在訪問的時候,會去請求 xxx.js,而這個文件可能被劫持篡改,或者由於網絡等原因,接收到的文件不完整,怎麼辦?

而設置了 SRI 就可以確保當請求的文件被篡改或不完整的時候就拒絕執行該文件,設置如下:

<link href="https://xxx/x.css" intergrity="sha1/asdhfkjasdf">
<script src="https://xxx/x.js" intergrity="sha1/asdhfkjasdf"></script>

標籤上的 intergrity 屬性值的格式是:哈希算法/base64後的哈希值

原理:

打包的時候會根據文件內容生成 hash,並且把 hash 作為 intergrity 屬性注入到標籤上,客户端接收到文件後,根據文件內容生成 hashintergrity 上的進行對比是否一致,如果不一致就會認為是不安全的,拒絕執行

Referrer-Policy

Referrer-Policy 是一種 HTTP 安全方案,用於控制 referer 攜帶策略,用於監管哪些訪問來源信息會在 referer 中發送

注意 referer 實際上是單詞 referrer 的錯誤拼寫。而 Referrer-Policy 這個首部並沒有延續這個錯誤拼寫

開啓 Referrer-Policy 的方式有兩種

1. meta

<meta name="referrer" content="same-origin">

2. http general

Referrer-Policy: same-origin

參數:

  • no-referrer:不發送 referer
  • no-referrer-when-downgrade:默認值,同安全級別發送 referrer 並且是完整 url,不同安全級別則不發送
  • origin:只發送協議、域名、端口,不發送完整 url,比如 https://juejin.cn/index.html,會變成https//juejin.cn/
  • origin-when-cross-origin:同源才發送完整 url,不同源只發送協議、域名、端口
  • same-origin:同源才發送 referer,並且是完整的 url
  • strict-origin:同安全級別和 origin 是一樣的,比如 https 請求 https,如 https 請求 http 是不同安全級別了,就不發送
  • strict-origin-when-cross-origin:同源發送完整 url,同安全級別才發送協議、域名、端口,不同源或不同安全級別不發送 referer
  • unsafe-url:這是最不安全的策略,不管同不同源都發送完整 url

HTTPS

由於 http 是明文傳輸,是不安全的,所以在 http 傳輸過程中信息可能被竊取、偽造、篡改,這種攻擊方式被稱為中間人攻擊

避免中間人攻擊的方法就是用 https,在應用層與傳輸層之間添加一個安全層 TLS,但也不是就絕對安全了

安全層會通過加密算法和公鑰私鑰加密傳遞的數據,好處是即使被劫持,中間人沒有私鑰就拿不到加密生成的隨機數,就無法生成最終密鑰

但問題是:假如一開始就被 DNS 劫持,或者説域名劫持攻擊,拿到的公鑰就是中間人的,中間人解密拿到數據後,再請求實際服務器,拿到服務器公鑰,再把信息發給服務器,這樣不知不覺間信息還是會被竊取

所以,還需要搭配數字證書,來幫我們驗證服務器身份。可 https 還有一個安全問題就是偽造證書的存在,比如

  • 比如 CA 機構沒有正確校驗申請者的身份而無意簽發了一些錯誤的證書
  • 比如 CA 機構在利益的驅使下,發放的證書
  • 比如冒充或偽造某個域名的擁有者,申請到一張證書,畢竟域名擁有者是無法知曉哪些 CA 機構給他簽發了證書,也不知道是否有人冒充他的身份申請了證書的
  • ...

CA 證書公鑰可信度是靠操作系統裏面預置的 CA 證書公鑰列表來保證的,就像白名單,用户一般也不知道 CA 證書公鑰的真假,那如果有黑客有能力把自己的公鑰放到用户系統的 CA 證書公鑰列表裏,那也可以偽造數字證書放到用户的電腦上,而用户卻無法感知就信任了這個證書,然後你懂的

為了解決證書問題,有一個解決方案,就是證書透明度(CT),能夠審計、監控證書的簽發和使用,一旦發現偽造的證書,可以快速聯繫到 CA 機構,吊銷該證書

使用證書透明度服務就是添加請求頭 Expect-CT 用來告訴瀏覽器期望使用證書透明度服務的,這能更有效的避免中間人攻擊等

但誰也不能説這就有 100% 的絕對安全了,只是現行架構下的這些解決方案,已經大大增加了中間人的攻擊成本,一般都是可以放心的

Node(服務端)

本地文件操作

指由於本地文件操作相關或路徑拼接導致的文件資源泄露,所帶來的安全問題

  • 比如提供了一個靜態服務,通過請求的參數 url 來給客户端返回想要資源,而用户手動修改 url 上的路徑卻可以訪問到
  • 比如暴露了一個服務或接口也可以操作文件的話,如果對它的校驗不是那麼安全的,就會有攻擊者能訪問到我們的文件,比如 ssh 文件、密碼之類的

預防:express-statickoa-staticresolve-path,都可以解決這個

WebShell

WebShell 是指一種惡意腳本,或者腳本木馬

原理:

利用文件上傳漏洞、SQL注入漏洞等等,把惡意文件放到服務器中,作為後門,然後通過服務器開放的端口+後門獲取服務器的操作權限,比如竊取用户數據、修改權限、文件管理 修改甚至刪除 web 頁面、數據庫管理等等

常見的 WebShell 編寫語言是 jsp、asp、php

攻擊方式:

  • 上傳漏洞。網站上有上傳文件的功能,過濾又不嚴,就可以直接把 jsp、asp、php 文件直接上傳到服務器
  • 上傳文件類型。項目上有添加上傳類型或重命名文件功能的,比如把 WebShell 文件重命名成.jpg之類的允許上傳的文件,上傳完成後,再重命名改回如 .jsp 這樣類型的文件
  • 隱藏到合法文件。比如把 php 代碼放到 jpg 文件裏,再使用@運算符防止發生錯誤,或者刪除空格換行等,導致代碼比較混亂,再使用編碼或者加密來隱藏惡意函數等
  • 隱藏到日誌。修改發送數據包的頭部,添加 WebShell 。 web 服務器一般會保存訪問記錄到Web日誌,如果找到web日誌,且放到可執行目錄下,可能獲得 shell
  • .....

ReDos

ReDos 就是正則表達式攻擊,利用正則表達式攻擊或者利用開發者正則寫的不規範,而瘋狂佔用服務器資源,造成服務器宕機

正則表達式匹配規則是:會先匹配第一種要能性,每當一次匹配不成功,就會嘗試回溯到上一個字符,看看能不能有其他組合來匹配到這個字符串,比如,匹配 aaa 會向下面這樣匹配

aaa
aa + a
a + aa
a + a + a

再看下圖三條正則表達式執行時間,第一條 0.198ms,第二條 26.445ms,第三條沒有結果,因為跑不完,會一直瘋狂佔用資源

時序攻擊

時序攻擊由於條件非常嚴荷,所以瞭解一下即可,哪怕只能説出時序攻擊這四個字,但知道有這麼回事就比不知道的強

比如攻擊者嘗試 arr = [1,2]arr = [1,3],發現響應時間幾乎一致,則可以認為第一個數字不是 1,再嘗試 arr = [2,1],依此類推,不斷碰撞嘗試,直到最後碰撞出來真實的 arr

像是對比兩個數組是否相同,下面代碼看似沒什麼問題,業務效果完全能達到,但是在絕對安全層面上是不安全的

當然業務代碼中沒必要這麼嚴苛,因為比如上述代碼上如果還有其他 if else 判斷,就完全沒辦法碰撞出來了

爬蟲

爬蟲就是一種按照一定規則自動抓取資源的程序或者腳本,搜索引擎可以用爬蟲抓取網頁、圖片、視頻、音頻等

對於有一些沒有防範的系統,通過爬蟲,甚至可以把人家會員才能看或者付費下載的資源直接給爬下來,假設網站上有一個 10MB 的文件,使用爬蟲抓取上千上萬次,就會導致網站產生大量出站流量,很可能還會使服務器癱瘓無法訪問了

防範其實主要就是服務端安全校驗的問題,比如設置 robots.txt 文件、比如對請求中的 User Agent 識別和限制,説到底防爬蟲主要是防範這幾個點:iporiginrefererrequest headers

如果沒有併發的去請求去爬蟲的時候,它不會針對 ip 做校驗,只會判斷後面幾個,而如果沒有後幾點就會認為你是不安全的系統,就給爺爬

結語

如果本文對你有一點點幫助,點個贊支持一下吧,你的每一個【贊】都是我創作的最大動力 ^_^

更多前端文章,或者加入前端交流羣,歡迎關注公眾號【沐華説技術】,大家一起共同交流和進步呀

Add a new Comments

Some HTML is okay.