問題先導
什么是XSS攻擊(概念、攻擊方式、危害)?如何預防XSS攻擊?【
瀏覽器
】-
兩數(shù)之和【
算法
】求給定數(shù)組中和為指定數(shù)字的兩個下標。 輸入:nums = [2,7,11,15], target = 9 輸出:[0,1] 解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
知識梳理
什么是XSS攻擊?如何預防XSS攻擊?
概念
XSS是Cross Site Scripting的縮寫,由于CSS在網(wǎng)頁設計領域已經(jīng)被廣泛指層疊樣式表(Cascading Style Sheets),而Cross又有“交叉”的含義,所以將Cross改以交叉形的X做為縮寫。因此XSS就是我們常說的跨站腳本攻擊。
跨站腳本攻擊是一種安全漏洞,攻擊者可以利用這種漏洞向網(wǎng)站注入具有攻擊性的腳本代碼,當被攻擊者登錄網(wǎng)站時就會自動執(zhí)行這些惡意代碼,攻擊者甚至可以突破網(wǎng)站訪問權,冒充受害者,并進行更多攻擊性操作。
根據(jù)開放式 Web 應用安全項目(OWASP),XSS 在 2017 年被認為 7 種最常見的 Web 應用程序漏洞之一。
攻擊方式
XSS根據(jù)攻擊腳本的來源不同,一般分為三種類型:
- 存儲型XSS:惡意腳本存儲到了目標服務器上。當瀏覽器請求到數(shù)據(jù)時,腳本從服務器上傳并執(zhí)行。
- 反射型XSS:當用戶點擊一個惡意鏈接,或者提交一個表單,或者進入一個惡意網(wǎng)站時,注入腳本進入被攻擊者的網(wǎng)站。Web服務器將注入腳本,比如一個錯誤信息,搜索結(jié)果等 返回到用戶的瀏覽器上。由于瀏覽器認為這個響應來自"可信任"的服務器,所以會執(zhí)行這段腳本。
- 基于DOM的XSS:通過修改原始的客戶端代碼,受害者瀏覽器的 DOM 環(huán)境改變,導致有效載荷的執(zhí)行。也就是說,頁面本身并沒有變化,但由于DOM環(huán)境被惡意修改,有客戶端代碼被包含進了頁面,并且意外執(zhí)行。
簡答來說,存儲型XSS腳本被存儲到了服務器中,并由服務器上傳至頁面并執(zhí)行,存儲型XSS也稱為持久性XSS,由于攻擊腳本被存儲到了服務器,可見其危害之廣、影響之大。
比如較為經(jīng)典的留言板持久型XSS攻擊,如某網(wǎng)站對用戶輸入沒有做特殊處理,而用戶直接輸入類似下面的內(nèi)容:
<script>alert(“you see me!”)</script>
由于留言板會緩存到服務器,讓每個人都能看到,當用戶打開這個留言頁面時,就會觸發(fā)這段腳本代碼。
而非持久性也就是反射型XSS,一般是用戶經(jīng)過某些惡意鏈接后重定向回某個可信任網(wǎng)站,但由于這些惡意鏈接攜帶了一些攻擊性的表單信息,并被重定向的網(wǎng)站攜帶回來,然后在用戶界面執(zhí)行。由于腳本由用戶觸發(fā),服務器只是中轉(zhuǎn)站,然后又帶回給頁面,所以稱之為反射型XSS。經(jīng)過了可信任服務器的”轉(zhuǎn)載“,這些來自惡意網(wǎng)站的腳本就變成了可信任數(shù)據(jù),然后被執(zhí)行。
比如某個惡意鏈接中攜帶了腳本代碼:
<a
>
點我就送大驚喜</a>
而某些攻擊者利用http://192.168.1.102/xss/example.php
這個頁面的打開邏輯,知道name
參數(shù)會被插入頁面進而編寫了具有攻擊性的誘導鏈接,當用戶點擊之后就觸發(fā)了設計好的腳本代碼。
最后一種,基于DOM的XSS不常見,這往往是瀏覽器環(huán)境被惡意篡改導致了惡意代碼在某些頁面上的執(zhí)行。
危害
如果腳本在頁面執(zhí)行,最壞的情況就是頁面上的所有信息都被獲取,甚至偽造成用戶與服務器進行交互,進行更大的破壞。一般來說,有以下幾方面的危害:
- 獲取隱私數(shù)據(jù):客戶cookie、session等網(wǎng)站信息
- DOS攻擊:向服務器發(fā)送請求,占用服務器資源,讓用戶無法正常訪問服務器
- 修改頁面信息
- 流量劫持。將鏈接指向其他網(wǎng)站,進一步進行惡意控制或其他操作。
如何預防XSS攻擊
從XSS的攻擊方式來看,造成腳本執(zhí)行的原因有兩方面,一是服務器接收了腳本,但沒有識別,讓客戶端保持了信任條件,二是瀏覽器本身沒有對腳本進行甄別,我們發(fā)現(xiàn),惡意腳本執(zhí)行基本都是要操作DOM才能出發(fā)的,而DOM的操作是客戶端能夠控制的。所以,XSS的預防要從服務器端和客戶端兩頭抓。
針對不同的腳本攻擊有不同的處理辦法,可能有的攻擊方式還未出現(xiàn),但層層把關是我們能做到的:
對上傳的用戶數(shù)據(jù)進行轉(zhuǎn)譯處理:客戶端轉(zhuǎn)譯或進行輸入限制;服務器端也要進行轉(zhuǎn)譯,避免漏網(wǎng)之魚。
對DOM操作慎之又慎:很多時候DOM操作不規(guī)范才使得腳本語言有機可乘,要對DOM來源有明確的把控。
-
設置CSP安全策略。嚴格的CSP設置可以
禁止加載外域代碼,防止復雜的攻擊邏輯。
禁止外域提交,網(wǎng)站被攻擊后,用戶的數(shù)據(jù)不會泄露到外域。
禁止內(nèi)聯(lián)腳本執(zhí)行(規(guī)則較嚴格,目前發(fā)現(xiàn) GitHub 使用)。
禁止未授權的腳本執(zhí)行(新特性,Google Map 移動版在使用)。
-
合理使用上報可以及時發(fā)現(xiàn) XSS,利于盡快修復問題。
更多細節(jié)可參考內(nèi)容安全策略( CSP ) - MDN。
增強對敏感數(shù)據(jù)的保護,提交攻擊門檻:比如cookie中使用
http-only
,讓腳本無法獲取隱私信息,設置驗證操作等提高腳本攻擊門檻。主動檢測:利用XSS攻擊檢測工具掃描網(wǎng)站數(shù)據(jù)是否存在XSS漏洞。
擴展:XSS攻擊小游戲
以下是幾個 XSS 攻擊小游戲,開發(fā)者在網(wǎng)站上故意留下了一些常見的 XSS 漏洞。玩家在網(wǎng)頁上提交相應的輸入,完成 XSS 攻擊即可通關。
參考:
關鍵字:瀏覽器安全、XSS
兩數(shù)之和
求給定數(shù)組中和為指定數(shù)字的兩個下標。
輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
暴力解法很容易想到,遍歷數(shù)組兩兩相加來判斷是否等于目標值即可。
我們發(fā)現(xiàn)關鍵語句為nums[i] + nums[j] == target
,這樣我們需要知道同時知道i
和j
才行,這樣就不得不遍歷兩次數(shù)組。
實際上,這個關鍵式子可以轉(zhuǎn)換為求差:nums[i] == target - nums[j]
。看似沒有區(qū)別,但我們可以理解為判斷目標值與下標j
的差是否為出現(xiàn)過的num[i]
的值,我們一般遍歷一遍記錄nums[i]
的值即可,這樣,當遇到適合的nums[j]
就能匹配上,也就只需要遍歷一遍數(shù)組。
參考代碼:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
const map = new Map(); // 存儲遍歷過的數(shù)據(jù)
for(let i = 0; i < nums.length; i++) {
const diff = target - nums[i];
if(map.has(diff)) {
return [map.get(diff), i];
}
map.set(nums[i], i);
}
}
關鍵字:轉(zhuǎn)變求解思路,異曲同工