花點時間弄懂XSS攻擊.
最近在segmentfault發現了劉小夕.
很喜歡劉小夕寫出來的技術博文,被安排的明明白白.
此文章為學習劉小夕的WEB安全筆記.歡迎大家也去Pick她.
文章最後有原文連結.
前端有哪幾種攻擊方式?
XSS攻擊.CSRF攻擊.點選劫持以及URL跳轉漏洞
什麼是XSS攻擊?
XSS(Cross-Site Scripting,跨站指令碼攻擊)是一種程式碼注入攻擊。攻擊者在目標網站上注入惡意程式碼,當用戶(被攻擊者)登入網站時就會執行這些惡意程式碼,通過這些指令碼可以讀取cookie,session tokens,或者網站其他敏感的網站資訊,對使用者進行釣魚欺詐。
XSS的本質:惡意程式碼未經過濾,與網站的正常程式碼混在一起,瀏覽器無法分辨哪些指令碼是可信的,導致惡意指令碼被執行。由於直接在使用者的終端程式碼執行,惡意程式碼能夠直接獲取使用者的資訊,利用這些資訊冒充使用者向網站發起攻擊請求.
XSS攻擊有哪些型別?
反射型XSS
反射型XSS漏洞常見於通過URL傳遞引數的功能,如網站搜尋,跳轉等。由於需要使用者主動開啟惡意的URL才能生效,攻擊者往往會結合多種手段誘導使用者點選.
POST的內容也可以觸發反射型XSS,只不過它的觸發條件比較苛刻(構建表單提交頁面,並引導使用者點選),所以非常少見.
反射型XSS的攻擊步驟
1.攻擊者構造出特殊的URL,其中包含惡意程式碼.
2.使用者開啟有惡意程式碼的URL時,網站伺服器端將惡意程式碼從URL取出,拼接在HTML返回給瀏覽器.
3.使用者瀏覽器接收到響應後解析執行,混在其中的惡意程式碼也會被執行。
4.惡意程式碼竊取使用者資料併發送到攻擊者的網站,或者冒充使用者行為,呼叫目標網站介面執行攻擊者指定的操作.
注意:Chrome和Safari能夠檢測到url上的xss攻擊,將網頁攔截掉,但是其他瀏覽器不行,如IE和Firefox。
如何防禦反射型XSS攻擊
對url查詢引數進行轉義後再輸出到頁面。
app.get('/welcome',function(req,res){ //對查詢引數進行編碼,避免反射型 XSS攻擊 res.send(`${encodeURIComponent(req.query.type)}`); })
DOM型XSS
DOM型XSS攻擊,實際上就是前端javascript程式碼不夠嚴謹,把不可信的內容插入到了頁面,在使用.innerHTML、.outerHTML、.appendChild、document.write()等API時要特別小心,不要把不可信的資料作為HTML插入到頁面上,儘量使用.innerText、.textContent、.setAttribut()等.
DOM型XSS的攻擊步驟
1.攻擊者構造出特殊資料,其中包含惡意程式碼。
2.使用者瀏覽器執行了惡意程式碼
3.惡意竊取使用者資料併發送到攻擊者的網站,或冒充使用者行為,呼叫目標網站介面執行攻擊者指定的操作.
如何防禦DOM型XSS攻擊
防範DOM型XSS攻擊的核心就是對輸入內容進行轉義(DOM中的內聯事件監聽順和連結跳轉都能把字串作為程式碼執行,需對內容進行檢查).
1.對於url連結(例如圖片的src屬性)那麼直接使用encodeURIComponent來轉義。
2.對於非url,我們可以進行編碼:
function encodeHtml(str){ return str.replace(/"/g,'"') .replace(/'/g,''') .replace(/</g,'<') .replace(/>/g,'>') }
DOM型XSS攻擊中,取出和執行惡意程式碼由瀏覽器端完成,屬於前端javascript自身的安全漏洞.
儲存型XSS
惡意指令碼永久儲存在目標伺服器上。當瀏覽器請求資料時,指令碼從伺服器傳回並執行,影響範圍比反射型和DOM型XSS更大。儲存型XSS攻擊的原因仍然是沒有做好資料過濾:前端提交資料至伺服器端時,沒有做好過濾;服務端在按受到資料時,在儲存之前,沒有做過濾;前端從伺服器端請求到資料,沒有過濾輸出。
儲存型XSS的攻擊步驟
1.攻擊者將惡意程式碼提交到目標網站的資料庫中。
2.使用者開啟目標網站時,網站服務端將惡意程式碼從資料庫中取出,拼接在HTML中返回給瀏覽器。
3.使用者瀏覽器接收到響應後解析執行,混在其中的惡意程式碼也被執行。
4.惡意程式碼竊取使用者資料併發送到攻擊者的網站,或冒充使用者行為,凋用目標網站介面執行攻擊者指定的操作.
這種攻擊常見於帶有使用者儲存資料的網站功能,如論壇發帖,商品評論,使用者私信等。
如何防範儲存型XSS攻擊
1.前端資料傳遞給伺服器之彰,先轉義/過濾(防範不了抓包修改資料的情況)
2.伺服器接收到資料,在儲存到資料庫之前,進行轉義和過濾
3.前端接收到伺服器傳遞過來的資料,在展示到頁面前,先進行轉義/過濾.
function getList() { $.get('/getComments2').then(res=> { if(res.code === 0){ let list =""; $each(res.comments,(index,comment)=>{ content = encodeHtml(comment.content); console.log(comment.content,'*****',content); lists += '<li class="list-group-item"><span>${comment.username};</span>${content}'; }); $('.list-group').html(lists); } } ) }
除了謹慎的轉義,其他一些手段來防範XSS攻擊:
1.Content Security Policy
在服務端使用HTTP的Content-Security-Policy頭部來指定策略,或者在前端設定meta標答。
例如下面的配置只允許載入同域下的資源:
Content-Security-Policy:default-src 'self'`請輸入程式碼`
<meta http-equiv="Content-Security-Policy" content="form-action 'self';">
前端和伺服器設定CSP的效果相同.
嚴格的CSP在XSS的防範中可以起到以下的作用:
1.禁止載入外域程式碼,防止複雜的邏輯攻擊.
2.禁止外域提交,網站被攻擊後,使用者資料不會被洩露到外域
3.禁止內聯指令碼執行(規則較嚴格,目前發現github使用)
4.禁止未授權的指令碼執行
5.合理使用上報可以及時發現XSS,利用盡快修復問題.
2.輸入內容長度控制
對於不受信任的輸入,都應該限定一個合理的長度。雖無法完全防止XSS發生,但是可以增加XSS攻擊的難度。
3.輸入內容限制
對於部分輸入,可以限定不能包含特殊字元或者僅能輸入數字等。
4.其他安全措施
HTTP-only Cookie:禁止JavaScript讀取某些敏感Cookie,攻擊者完成XSS注入後也無法竊取此Cookie
驗證碼:防止指令碼冒充使用者提交危險操作
XSS檢測
1.使用通用XSS攻擊字串手動檢測XSS漏洞,如:
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
能夠檢測到存在於HTML屬性、HTML文字內容、HTML註釋、跳轉連結、內聯Javascript字串、內聯CSS樣式表等多種上下文中的XSS漏洞,也能檢測eval()、setTimeout()、setInterval()、Function()、innerHTML、document.write()等DOM型XSS漏洞,並且能繞過一些XSS過濾器.
2.安全掃描工具
Arachni
Mozilla HTTP Observatory
w3af