好書一起讀(147):XSS,CSRF,SQL注入
零、前言
戰爭有著天大的魅力,進攻讓人熱血沸騰。
維埃里神威蓋世,因扎吉嗅覺無雙,李世石挖棋騙狗,安德森棄後殺王,馬薇薇溫柔刺客,林正疆怒目金剛,平安城圍敵雪恨,祭旗坡畫策渡江,月魔王分兵虎踞,法拉利破陣鷹揚……偉大的攻擊手生而具備敏銳的眼睛和凶暴的力量,別人眼裡的全身披掛,在他們眼裡破綻百出,雖有七層巨盾,猶如裸奔中原,當獵物對危險還茫然無知,獵人已經算計好了七八種致勝的方法,只等時機恰到,一擊必殺。
既然敵人如此可怕,潛在的受害者就不能掉以輕心,曹操陣前邀請,韓遂欣然相會,弱小的一方總是對敵人懷有僥倖的好意,他們也為之付出了太大的代價。只有挨打,一次,兩次,打得疼了,疼得怕了,如臨深淵,如履薄冰,隨時隨地都在想著自己會怎麼死,防禦能力就自然漲了三分。對方前鋒是要向左還是向右,要突還是要傳,還是要閃開空擋直接射門,被打成篩子若干次,才會對敵人一切可能的進攻變化有所準備,從而尋找到正確的應法。
要知生,先知死,要防禦,就要知道在敵人眼裡你可能有哪些漏洞。你要知道敵人可能攻你的偏師也可能攻你的本陣,可能打你的側背也可能中心突破,可能切後排法師也可能團控跳大直接秒肉裝核心,還可能飛補給線打掉你送裝備的信使。網站安全也是一樣,從瀏覽器到伺服器,至少兩個操作系統加上其間不知多少環節的網路線路,這樣龐大的戰場,任何一個點都可能被敵人定為主攻目標,那就要先看地圖,了解戰場。計算機組成原理,操作系統,計算機網路,這些學科是怎樣分工合作的;客戶端,服務端,中間的網路,它們的運行機理分別是什麼;聰明的壞人可能怎樣利用這些規則,來達到他們邪惡的意圖。
如果被壞人實現了意圖,從他的角度就算成功,為不讓他成功,就要修補自己的漏洞。漏洞在瀏覽器,伺服器,中間網路等不同位置可能出現的原因有哪些,雖然黑客智慧無窮,計算機世界複雜無邊,漏洞幾乎不可能完全消滅,但至少知道些慣常的套路總有助於少受損失並發散思維。當防禦體系一磚一瓦漸趨堅固,你的系統就在黑客眼中無懈可擊,銳利的眼光掃到可能突破的弱點,發現處處都已壁壘森嚴,嚴絲合縫,固若金湯。這是每個編程者的夢想,也是幾乎不可能實現的最高目標,對此只能一點點學,一步步走,一篇篇資料看下去。這是一條艱難的道路,但我們都必須出發。
這篇說說最常見的三種Web攻擊,參考書籍《白帽子講Web安全》和《Web前端黑客技術揭秘》。
一、XSS
有時候我們看到別人的QQ空間日誌發表了奇怪的內容,會想「中毒了吧」,其實準確說是XSS攻擊。
XSS,跨站腳本攻擊,本質是「對用戶當前瀏覽的頁面植入惡意腳本」。具體說,就是黑客為頁面添加網站開發者意圖之外的邏輯,其實現方式是在網站開發者提供的用於顯示用戶數據的地方加入腳本。
分為三種:反射型,持久型,DOM型。
反射型:
如果url中的一部分會直接顯示到頁面上,黑客可以構造一個惡意url,使其中含有xss代碼,再把這個url引誘無辜用戶點開,無辜用戶點開之後,xss代碼顯示到頁面上,被瀏覽器理解為腳本執行,達到黑客的目的。
持久型:
如果黑客可以將腳本代碼通過發布內容(如發博文、寫留言等)的方式發布到伺服器上,成為某個url正常的頁面的一部分,其他用戶訪問這個看似正常的url,則其頁面已經包含了xss代碼,被瀏覽器理解為腳本執行,達到黑客的目的。
DOM型:
是反射型的一種,但惡意url中的xss代碼不直接成為DOM的一部分,而是在其他用戶訪問頁面時,由頁面的原有腳本將其插入到DOM中,插入之後,瀏覽器即執行腳本中的xss代碼,達到黑客的目的。
因為惡意腳本的邏輯可能很長,所以xss代碼可能是簡短的插入script節點的語句,載入來自第三方域的含有具體惡意代碼的腳本,所以稱為跨站腳本攻擊。
具體的惡意代碼,常見的行為是讀取cookie,構造例如一個img標籤,將其src屬性指向惡意第三方網站,將cookie的內容作為參數附在src的url上,這樣黑客就能在其網站上獲得你的cookie信息,這就是所謂的cookie劫持。
惡意代碼另一種常見的行為是執行GET或POST等操作。GET操作同上,指定img的src方法,中招者的瀏覽器即會發起一個get請求,其性質可能是刪除某個中招者有許可權刪除的文章之類。POST操作可能是由惡意腳本構建一個表單並直接提交,也可能是構建一個ajax請求提交。
開頭所說的中招的QQ空間用戶,是典型的XSS蠕蟲場景,其特點是該頁面有發內容能力,又有交互行為。這樣一個用戶張三訪問其他用戶李四的日誌(或站內信、留言等)時,因為該日誌已經含有惡意腳本在裡面(持久型XSS),腳本在張三的瀏覽器執行,構造一個表單並提交,為張三也發表了一篇同樣內容的日誌,這樣病毒式傳播開來。
為了防禦XSS攻擊,需要採用以下方法:
1.為cookie設置HttpOnly以避免cookie劫持的危險。
2.為將進入HTML標籤、HTML屬性、腳本、事件、樣式表、鏈接的用戶輸入,做相應的編碼工作。
3.為用戶通過富文本編輯器輸入的內容,進行白名單的過濾。
4.針對DOM型XSS,一次編碼不夠,要編碼第二次,針對從javascript到DOM的步驟。
小結:
XSS攻擊的本質是:我要做些壞事,比如刪你的文章,但我沒權力,只有你(登錄後的瀏覽器,重點是cookie)有權力。
那我就寫好腳本,讓你的瀏覽器一不小心跑了它,我的壞事就做成了。
怎樣能讓我的腳本被你的瀏覽器跑呢?只要這腳本是你瀏覽器中網頁的一部分,你的瀏覽器自然就會帶著登錄狀態跑它了。
第一種思路,讓網路上某個url對應的網頁確實是「含有我腳本的網頁」,你訪問這url就可以了,這就是持久型。
第二種思路,網路上某個網頁其url參數直接進入內容,那我巧妙地構造一個url,你只要點開url,你看到的網頁里就有我的腳本,這就是反射型。
第三種思路,網路上某個網頁會將其url參數用javascript生成DOM節點,那我巧妙地構造一個url,你只要點開,那網頁里就有我的腳本,這就是DOM型。
總而言之,網站開發者要留神那些把用戶輸入的東西顯示到網頁上的地方:那些地方是用來顯示用戶數據的,不是用來載入用戶腳本的!
那問題就是,怎麼確定用戶輸入的東西是腳本還是數據?
第一種思路,可以過濾,指定白名單,只放行特定的數據型標籤,腳本標籤不放行。
第二種思路,粗暴轉碼,不管你輸入的是啥,一律數據化,你輸入數據,它還是數據,你輸入腳本,它也變成數據。
目的就是確定用戶輸入的內容顯示到網頁上之後,在形式上全是數據,不可能是腳本。
附:Java語言的防禦XSS攻擊的庫:
ESAPI: Category:OWASP Enterprise Security API
JSOUP:
Prevent cross site scripting with jsoup
二、CSRF
我要做些壞事,但我沒權力,只有你(登錄後的瀏覽器,重點是cookie)有權力。
那我就想辦法讓你的瀏覽器辦我的事,發送我希望的GET或POST請求。
這似乎跟XSS有交叉了,梳理一下,只要是讓受害者用戶因訪問某個頁面而無意中發了請求,來達到壞人的目的,就是CSRF攻擊,如果該頁面與請求目標頁面同源(即存在於正常網站上),就是XSS與CSRF結合的攻擊,不同源(即存在於惡意網站上)則是純CSRF攻擊。
XSS防禦防的是不讓壞人有機會把腳本放到我網站的頁面上;CSRF防禦防的是不讓壞人構造假的請求增刪我網站上的資源,這請求可能是來自於惡意腳本,也可能只是一個html標籤的src屬性發起的GET請求。
壞人想構造一個假的請求,需要知道幾件事:請求的方法GET還是POST;請求的url,請求的參數名,參數的值。
方法和url以及參數名總沒辦法保密,能動腦子的點就是參數值。
什麼樣的參數值,真正的用戶知道,造假請求的用戶不知道呢?一是驗證碼,二是token。
這兩者的原理其實一樣:用戶訪問網頁時,後台生成一個隨機串存到session里,並把這串放到網頁中給用戶,用戶提交表單時,檢查表單中串與session中串是否一致。
唯一區別是這串在網頁中的顯示,驗證碼是生成圖片讓用戶肉眼分辨,token是作為隱藏域直接成為表單的一部分。
所以重點表單常用驗證碼,而一般表單考慮到用戶體驗,採用token的方式。
三、SQL注入
我要做點壞事,但我沒權力,只有你(伺服器的後台代碼)有權力。
那我就想辦法讓你的後台代碼辦我的事,執行我的SQL代碼。
任何注入都是不慎給了壞人機會,讓他在本來給他輸入數據的地方輸入腳本,然後他的腳本在特定的有權上下文上被執行了。XSS和CSRF的有權上下文是帶無辜用戶cookie的瀏覽器環境,而SQL注入的有權上下文是可以訪問網站資料庫的網站後台程序。
什麼情況下會是本來給人輸入數據的地方被壞人輸入了腳本,那腳本還作為正常SQL的一部分被執行了呢?那就是拼裝SQL字元串。
有的網站的後台程序將用戶提交的數據(如查詢條件)與SQL串的邏輯部分用字元串連接的方式拼裝到一起,在正常的情況下,這能實現業務,但隱患就是,壞人可以在提交數據的地方,巧妙地編寫一些代碼,與你的SQL串邏輯部分拼裝之後,結果仍然是形式上合法的SQL串,但其內容可能是毀滅性的,比如刪除全表數據。
相對來說,SQL注入攻擊的威脅更大,與之相比XSS和CSRF只算是癬疥之疾——太表皮,疼得不深入,而SQL注入則是腹心之疾。
但SQL注入防禦起來極為簡單:保證代碼中不含有拼裝SQL的代碼就行了,一律採用參數化查詢。
還是那句話,不給壞人這樣的機會:把輸入數據轉為輸入邏輯。
附:OWASP 2013年版的TOP 10 常見安全問題
https://www.owasp.org/images/5/51/OWASP_Top_10_2013-Chinese-V1.2.pdf
推薦閱讀:
※「每日一題」XSS 是什麼?
※了解黑客:這是黑客思維
※XSS常見攻擊與防禦
※記一次沒什麼技術含量的XSS注入
※XSS學習之以關點面 11~15關