常見六大Web安全攻防解析
一(yī)、XSS
XSS (Cross-Site Scripting),跨站腳本攻擊,因為(wèi)縮寫和(hé) CSS重疊,所以隻能叫 XSS。跨站腳本攻擊是指通過存在安全漏洞的(de)Web網站注冊用戶的(de)浏覽器內(nèi)運行非法的(de)HTML标簽或JavaScript進行的(de)一(yī)種攻擊。
跨站腳本攻擊有可(kě)能造成以下影響:
利用虛假輸入表單騙取用戶個人信息。
利用腳本竊取用戶的(de)Cookie值,被害者在不知情的(de)情況下,幫助攻擊者發送惡意請求。
顯示僞造的(de)文章(zhāng)或圖片。
XSS 的(de)原理(lǐ)是惡意攻擊者往 Web 頁面裏插入惡意可(kě)執行網頁腳本代碼,當用戶浏覽該頁之時,嵌入其中 Web 裏面的(de)腳本代碼會被執行,從而可(kě)以達到攻擊者盜取用戶信息或其他侵犯用戶安全隐私的(de)目的(de)。
XSS 的(de)攻擊方式千變萬化,但還是可(kě)以大緻細分為(wèi)幾種類型。
1.非持久型 XSS(反射型 XSS )
非持久型 XSS 漏洞,一(yī)般是通過給别人發送帶有惡意腳本代碼參數的(de) URL,當 URL 地(dì)址被打開時,特有的(de)惡意代碼參數被 HTML 解析、執行。
非持久型 XSS 漏洞攻擊有以下幾點特征:
即時性,不經過服務器存儲,直接通過 HTTP 的(de) GET 和(hé) POST 請求就能完成一(yī)次攻擊,拿到用戶隐私數據。
攻擊者需要誘騙點擊,必須要通過用戶點擊鏈接才能發起
反饋率低(dī),所以較難發現和(hé)響應修複
盜取用戶敏感保密信息
為(wèi)了防止出現非持久型 XSS 漏洞,需要确保這麽幾件事情:
Web 頁面渲染的(de)所有內(nèi)容或者渲染的(de)數據都必須來自(zì)于服務端。
盡量不要從
URL
,document.referrer
,document.forms
等這種 DOM API 中獲取數據直接渲染。盡量不要使用
eval
,new Function()
,document.write()
,document.writeln()
,window.setInterval()
,window.setTimeout()
,innerHTML
,document.createElement()
等可(kě)執行字符串的(de)方法。如(rú)果做(zuò)不到以上幾點,也必須對涉及 DOM 渲染的(de)方法傳入的(de)字符串參數做(zuò) escape 轉義。
前端渲染的(de)時候對任何的(de)字段都需要做(zuò) escape 轉義編碼。
2.持久型 XSS(存儲型 XSS)
持久型 XSS 漏洞,一(yī)般存在于 Form 表單提交等交互功能,如(rú)文章(zhāng)留言,提交文本信息等,黑客利用的(de) XSS 漏洞,将內(nèi)容經正常功能提交進入數據庫持久保存,當前端頁面獲得後端從數據庫中讀出的(de)注入代碼時,恰好将其渲染執行。
舉個例子(zǐ),對于評論功能來說,就得防範持久型 XSS 攻擊,因為(wèi)我可(kě)以在評論中輸入以下內(nèi)容
主要注入頁面方式和(hé)非持久型 XSS 漏洞類似,隻不過持久型的(de)不是來源于 URL,referer,forms 等,而是來源于後端從數據庫中讀出來的(de)數據 。持久型 XSS 攻擊不需要誘騙點擊,黑客隻需要在提交表單的(de)地(dì)方完成注入即可(kě),但是這種 XSS 攻擊的(de)成本相對還是很高(gāo)。
攻擊成功需要同時滿足以下幾個條件:
POST 請求提交表單後端沒做(zuò)轉義直接入庫。
後端從數據庫中取出數據沒做(zuò)轉義直接輸出給前端。
前端拿到後端數據沒做(zuò)轉義直接渲染成 DOM。
持久型 XSS 有以下幾個特點:
持久性,植入在數據庫中
盜取用戶敏感私密信息
危害面廣
3.如(rú)何防禦
對于 XSS 攻擊來說,通常有兩種方式可(kě)以用來防禦。
1) CSP
CSP 本質上就是建立白名單,明确告訴浏覽器哪些外部資源可(kě)以加載和(hé)執行。我們隻需要配置規則,如(rú)何攔截是由浏覽器自(zì)己實現的(de)。我們可(kě)以通過這種方式來盡量減少 XSS 攻擊。
通常可(kě)以通過兩種方式來開啓 CSP:
設置 HTTP Header 中的(de) Content-Security-Policy
設置 meta 标簽的(de)方式
這裏以設置 HTTP Header 來舉例:
隻允許加載本站資源
Content-Security-Policy: default-src 'self'
隻允許加載 HTTPS 協議圖片
Content-Security-Policy: img-src https://*
允許加載任何來源框架
Content-Security-Policy: child-src 'none'
對于這種方式來說,隻要配置了正确的(de)規則,那麽即使網站存在漏洞,攻擊者也不能執行它的(de)攻擊代碼,并且 CSP 的(de)兼容性也不錯。
2) 轉義字符
用戶的(de)輸入永遠不可(kě)信任的(de),最普遍的(de)做(zuò)法就是轉義輸入輸出的(de)內(nèi)容,對于引号、尖括号、斜杠進行轉義
但是對于顯示富文本來說,顯然不能通過上面的(de)辦法來轉義所有字符,因為(wèi)這樣會把需要的(de)格式也過濾掉。對于這種情況,通常采用白名單過濾的(de)辦法,當然也可(kě)以通過黑名單過濾,但是考慮到需要過濾的(de)标簽和(hé)标簽屬性實在太多,更加推薦使用白名單的(de)方式。
3) HttpOnly Cookie。
這是預防XSS攻擊竊取用戶cookie最有效的(de)防禦手段。Web應用程序在設置cookie時,将其屬性設為(wèi)HttpOnly,就可(kě)以避免該網頁的(de)cookie被客戶端惡意JavaScript竊取,保護用戶cookie信息。
二、CSRF
CSRF(Cross Site Request Forgery),即跨站請求僞造,是一(yī)種常見的(de)Web攻擊,它利用用戶已登錄的(de)身份,在用戶毫不知情的(de)情況下,以用戶的(de)名義完成非法操作。
1.CSRF攻擊的(de)原理(lǐ)
下面先介紹一(yī)下CSRF攻擊的(de)原理(lǐ):
完成 CSRF 攻擊必須要有三個條件:
用戶已經登錄了站點 A,并在本地(dì)記錄了 cookie
在用戶沒有登出站點 A 的(de)情況下(也就是 cookie 生效的(de)情況下),訪問了惡意攻擊者提供的(de)引誘危險站點 B (B 站點要求訪問站點A)。
站點 A 沒有做(zuò)任何 CSRF 防禦
我們來看一(yī)個例子(zǐ): 當我們登入轉賬頁面後,突然眼前一(yī)亮(liàng)驚現"XXX隐私照片,不看後悔一(yī)輩子(zǐ)"的(de)鏈接,耐不住內(nèi)心躁動,立馬點擊了該危險的(de)網站(頁面代碼如(rú)下圖所示),但當這頁面一(yī)加載,便會執行submitForm
這個方法來提交轉賬請求,從而将10塊轉給黑客。
2.如(rú)何防禦
防範 CSRF 攻擊可(kě)以遵循以下幾種規則:
Get 請求不對數據進行修改
不讓第三方網站訪問到用戶 Cookie
阻止第三方網站請求接口
請求時附帶驗證信息,比如(rú)驗證碼或者 Token
1) SameSite
可(kě)以對 Cookie 設置 SameSite 屬性。該屬性表示 Cookie 不随着跨域請求發送,可(kě)以很大程度減少 CSRF 的(de)攻擊,但是該屬性目前并不是所有浏覽器都兼容。
2) Referer Check
HTTP Referer是header的(de)一(yī)部分,當浏覽器向web服務器發送請求時,一(yī)般會帶上Referer信息告訴服務器是從哪個頁面鏈接過來的(de),服務器籍此可(kě)以獲得一(yī)些信息用于處理(lǐ)。可(kě)以通過檢查請求的(de)來源來防禦CSRF攻擊。正常請求的(de)referer具有一(yī)定規律,如(rú)在提交表單的(de)referer必定是在該頁面發起的(de)請求。所以通過檢查http包頭referer的(de)值是不是這個頁面,來判斷是不是CSRF攻擊。
但在某些情況下如(rú)從https跳轉到http,浏覽器處于安全考慮,不會發送referer,服務器就無法進行check了。若與該網站同域的(de)其他網站有XSS漏洞,那麽攻擊者可(kě)以在其他網站注入惡意腳本,受害者進入了此類同域的(de)網址,也會遭受攻擊。出于以上原因,無法完全依賴Referer Check作為(wèi)防禦CSRF的(de)主要手段。但是可(kě)以通過Referer Check來監控CSRF攻擊的(de)發生。
3) Anti CSRF Token
目前比較完善的(de)解決方案是加入Anti-CSRF-Token。即發送請求時在HTTP 請求中以參數的(de)形式加入一(yī)個随機産生的(de)token,并在服務器建立一(yī)個攔截器來驗證這個token。服務器讀取浏覽器當前域cookie中這個token值,會進行校驗該請求當中的(de)token和(hé)cookie當中的(de)token值是否都存在且相等,才認為(wèi)這是合法的(de)請求。否則認為(wèi)這次請求是違法的(de),拒絕該次服務。
這種方法相比Referer檢查要安全很多,token可(kě)以在用戶登陸後産生并放于session或cookie中,然後在每次請求時服務器把token從session或cookie中拿出,與本次請求中的(de)token 進行比對。由于token的(de)存在,攻擊者無法再構造出一(yī)個完整的(de)URL實施CSRF攻擊。但在處理(lǐ)多個頁面共存問題時,當某個頁面消耗掉token後,其他頁面的(de)表單保存的(de)還是被消耗掉的(de)那個token,其他頁面的(de)表單提交時會出現token錯誤。
4) 驗證碼
應用程序和(hé)用戶進行交互過程中,特别是賬戶交易這種核心步驟,強制用戶輸入驗證碼,才能完成最終請求。在通常情況下,驗證碼夠很好地(dì)遏制CSRF攻擊。但增加驗證碼降低(dī)了用戶的(de)體驗,網站不能給所有的(de)操作都加上驗證碼。所以隻能将驗證碼作為(wèi)一(yī)種輔助手段,在關鍵業務點設置驗證碼。
三、點擊劫持
點擊劫持是一(yī)種視(shì)覺欺騙的(de)攻擊手段。攻擊者将需要攻擊的(de)網站通過 iframe 嵌套的(de)方式嵌入自(zì)己的(de)網頁中,并将 iframe 設置為(wèi)透明,在頁面中透出一(yī)個按鈕誘導用戶點擊。
1. 特點
隐蔽性較高(gāo),騙取用戶操作
"UI-覆蓋攻擊"
利用iframe或者其它标簽的(de)屬性
2. 點擊劫持的(de)原理(lǐ)
用戶在登陸 A 網站的(de)系統後,被攻擊者誘惑打開第三方網站,而第三方網站通過 iframe 引入了 A 網站的(de)頁面內(nèi)容,用戶在第三方網站中點擊某個按鈕(被裝飾的(de)按鈕),實際上是點擊了 A 網站的(de)按鈕。 接下來我們舉個例子(zǐ):我在優酷發布了很多視(shì)頻,想讓更多的(de)人關注它,就可(kě)以通過點擊劫持來實現
[object Object][object Object]
3. 如(rú)何防禦
1)X-FRAME-OPTIONS
X-FRAME-OPTIONS
是一(yī)個 HTTP 響應頭,在現代浏覽器有一(yī)個很好的(de)支持。這個 HTTP 響應頭 就是為(wèi)了防禦用 iframe 嵌套的(de)點擊劫持攻擊。
該響應頭有三個值可(kě)選,分别是
DENY,表示頁面不允許通過 iframe 的(de)方式展示
SAMEORIGIN,表示頁面可(kě)以在相同域名下通過 iframe 的(de)方式展示
ALLOW-FROM,表示頁面可(kě)以在指定來源的(de) iframe 中展示
2)JavaScript 防禦
對于某些遠古浏覽器來說,并不能支持上面的(de)這種方式,那我們隻有通過 JS 的(de)方式來防禦點擊劫持了。
四、URL跳轉漏洞
定義:借助未驗證的(de)URL跳轉,将應用程序引導到不安全的(de)第三方區域,從而導緻的(de)安全問題。
1.URL跳轉漏洞原理(lǐ)
黑客利用URL跳轉漏洞來誘導安全意識低(dī)的(de)用戶點擊,導緻用戶信息洩露或者資金的(de)流失。其原理(lǐ)是黑客構建惡意鏈接(鏈接需要進行僞裝,盡可(kě)能迷惑),發在QQ群或者是浏覽量多的(de)貼吧(ba)/論壇中。 安全意識低(dī)的(de)用戶點擊後,經過服務器或者浏覽器解析後,跳到惡意的(de)網站中。
惡意鏈接需要進行僞裝,經常的(de)做(zuò)法是熟悉的(de)鏈接後面加上一(yī)個惡意的(de)網址,這樣才迷惑用戶。
Header頭跳轉
Javascript跳轉
META标簽跳轉
這裏我們舉個Header頭跳轉實現方式:
<?php $url=$_GET['jumpto']; header("Location: $url"); ?>
http://www.***.org/login.php?jumpto=http://www.***.com
這裏用戶會認為(wèi)www.****.org
都是可(kě)信的(de),但是點擊上述鏈接将導緻用戶最終訪問www.****.com
這個惡意網址。
3.如(rú)何防禦
1)referer的(de)限制
如(rú)果确定傳遞URL參數進入的(de)來源,我們可(kě)以通過該方式實現安全限制,保證該URL的(de)有效性,避免惡意用戶自(zì)己生成跳轉鏈接
2)加入有效性驗證Token
我們保證所有生成的(de)鏈接都是來自(zì)于我們可(kě)信域的(de),通過在生成的(de)鏈接裏加入用戶不可(kě)控的(de)Token對生成的(de)鏈接進行校驗,可(kě)以避免用戶生成自(zì)己的(de)惡意鏈接從而被利用,但是如(rú)果功能本身要求比較開放,可(kě)能導緻有一(yī)定的(de)限制。
五、SQL注入
SQL注入是一(yī)種常見的(de)Web安全漏洞,攻擊者利用這個漏洞,可(kě)以訪問或修改數據,或者利用潛在的(de)數據庫漏洞進行攻擊。
1.SQL注入的(de)原理(lǐ)
我們先舉一(yī)個鑰匙的(de)例子(zǐ)來說明其原理(lǐ):
這是我們經常見到的(de)登錄頁面,但如(rú)果有一(yī)個惡意攻擊者輸入的(de)用戶名是 admin' --,密碼随意輸入,就可(kě)以直接登入系統了。why! ----這就是SQL注入
我們之前預想的(de)SQL 語句是:
SELECT * FROM user WHERE username='admin' AND psw='password'
但是惡意攻擊者用奇怪用戶名将你的(de) SQL 語句變成了如(rú)下形式:
SELECT * FROM user WHERE username='admin' --' AND psw='xxxx'
在 SQL 中,' --
是閉合和(hé)注釋的(de)意思,-- 是注釋後面的(de)內(nèi)容的(de)意思,所以查詢語句就變成了:
SELECT * FROM user WHERE username='admin' 複制代碼
所謂的(de)密碼,本質上就是SQL注入的(de)一(yī)種利用方式。
一(yī)次SQL注入的(de)過程包括以下幾個過程:
獲取用戶請求參數
拼接到代碼當中
SQL語句按照我們構造參數的(de)語義執行成功
SQL注入的(de)必備條件: 1.可(kě)以控制輸入的(de)數據 2.服務器要執行的(de)代碼拼接了控制的(de)數據。
我們會發現SQL注入流程中與正常請求服務器類似,隻是黑客控制了數據,構造了SQL查詢,而正常的(de)請求不會SQL查詢這一(yī)步,SQL注入的(de)本質:數據和(hé)代碼未分離(lí),即數據當做(zuò)了代碼來執行。
2.危害
獲取數據庫信息
管理(lǐ)員後台用戶名和(hé)密碼
獲取其他數據庫敏感信息:用戶名、密碼、手機号碼、身份證、銀行卡信息……
整個數據庫:脫褲
獲取服務器權限
植入Webshell,獲取服務器後門
讀取服務器敏感文件
3.如(rú)何防禦
嚴格限制Web應用的(de)數據庫的(de)操作權限,給此用戶提供僅僅能夠滿足其工作的(de)權限,從而限度的(de)減少注入攻擊對數據庫的(de)危害
後端代碼檢查輸入的(de)數據是否符合預期,嚴格限制變量的(de)類型,例如(rú)使用正則表達式進行一(yī)些匹配處理(lǐ)。
對進入數據庫的(de)特殊字符(',",\,<,>,&,*,; 等)進行轉義處理(lǐ),或編碼轉換。基本上所有的(de)後端語言都有對字符串進行轉義處理(lǐ)的(de)方法,比如(rú) lodash 的(de) lodash._escapehtmlchar 庫。
所有的(de)查詢語句建議使用數據庫提供的(de)參數化查詢接口,參數化的(de)語句使用參數而不是将用戶輸入變量嵌入到 SQL 語句中,即不要直接拼接 SQL 語句。例如(rú) Node.js 中的(de) mysqljs 庫的(de) query 方法中的(de) ? 占位參數。
六、OS命令注入攻擊
OS命令注入和(hé)SQL注入差不多,隻不過SQL注入是針對數據庫的(de),而OS命令注入是針對操作系統的(de)。OS命令注入攻擊指通過Web應用,執行非法的(de)操作系統命令達到攻擊的(de)目的(de)。隻要在能調用Shell函數的(de)地(dì)方就有存在被攻擊的(de)風險。倘若調用Shell時存在疏漏,就可(kě)以執行插入的(de)非法命令。
命令注入攻擊可(kě)以向Shell發送命令,讓Windows或Linux操作系統的(de)命令行啓動程序。也就是說,通過命令注入攻擊可(kě)執行操作系統上安裝着的(de)各種程序。
1.原理(lǐ)
黑客構造命令提交給web應用程序,web應用程序提取黑客構造的(de)命令,拼接到被執行的(de)命令中,因黑客注入的(de)命令打破了原有命令結構,導緻web應用執行了額外的(de)命令,web應用程序将執行的(de)結果輸出到響應頁面中。
2.如(rú)何防禦
後端對前端提交內(nèi)容進行規則限制(比如(rú)正則表達式)。
在調用系統命令前對所有傳入參數進行命令行參數轉義過濾。
編輯:--ns868