官术网_书友最值得收藏!

第一篇 世界觀安全

第1章 我的安全世界觀

互聯網本來是安全的,自從有了研究安全的人之后,互聯網就變得不安全了。

1.1 Web安全簡史

起初,研究計算機系統和網絡的人,被稱為“Hacker”,他們對計算機系統有著深入的理解,因此往往能夠發現其中的問題。“Hacker”在中國按照音譯,被稱為“黑客”。在計算機安全領域,黑客是一群破壞規則、不喜歡被拘束的人,因此總想著能夠找到系統的漏洞,以獲得一些規則之外的權力。

對于現代計算機系統來說,在用戶態的最高權限是root(administrator),也是黑客們最渴望能夠獲取的系統最高權限。“root”對黑客的吸引,就像大米對老鼠的吸引,美女對色狼的吸引。

不想拿到“root”的黑客,不是好黑客。漏洞利用代碼能夠幫助黑客們達成這一目標。黑客們使用的漏洞利用代碼,被稱為“exploit”。在黑客的世界里,有的黑客,精通計算機技術,能自己挖掘漏洞,并編寫exploit;而有的黑客,則只對攻擊本身感興趣,對計算機原理和各種編程技術的了解比較粗淺,因此只懂得編譯別人的代碼,自己并沒有動手能力,這種黑客被稱為“Script Kids”,即“腳本小子”。在現實世界里,真正造成破壞的,往往并非那些挖掘并研究漏洞的“黑客”們,而是這些腳本小子。而在今天已經形成產業的計算機犯罪、網絡犯罪中,造成主要破壞的,也是這些“腳本小子”。

1.1.1 中國黑客簡史

中國黑客的發展分為幾個階段,到今天已經形成了一條黑色產業鏈。

筆者把中國黑客的發展分為了:啟蒙時代、黃金時代、黑暗時代。

首先是啟蒙時代,這個時期大概處在20世紀90年代,此時中國的互聯網也剛剛處于起步階段,一些熱愛新興技術的青年受到國外黑客技術的影響,開始研究安全漏洞。啟蒙時代的黑客們大多是由于個人愛好而走上這條道路,好奇心與求知欲是驅使他們前進的動力,沒有任何利益的瓜葛。這個時期的中國黑客們通過互聯網,看到了世界,因此與西方發達國家同期誕生的黑客精神是一脈相傳的,他們崇尚分享、自由、免費的互聯網精神,并熱衷于分享自己的最新研究成果。

接下來是黃金時代,這個時期以中美黑客大戰為標志。在這個歷史背景下,黑客這個特殊的群體一下子幾乎吸引了社會的所有眼球,而此時黑客圈子所宣揚的黑客文化以及黑客技術的獨特魅力也吸引了無數的青少年走上這條道路。自此事件后,各種黑客組織如雨后春筍般冒出。此階段的中國黑客,其普遍的特點是年輕,有活力,充滿激情,但在技術上也許還不夠成熟。此時期黑客圈子里販賣漏洞、惡意軟件的現象開始升溫,同時因為黑客群體的良莠不齊,也開始出現以贏利為目的的攻擊行為,黑色產業鏈逐漸成型。

最后是黑暗時代,這個階段從幾年前開始一直延續到今天,也許還將繼續下去。在這個時期黑客組織也遵循著社會發展規律,優勝劣汰,大多數的黑客組織沒有堅持下來。在上一個時期非常流行的黑客技術論壇越來越缺乏人氣,最終走向沒落。所有門戶型的漏洞披露站點,也不再公布任何漏洞相關的技術細節。

伴隨著安全產業的發展,黑客的功利性越來越強。黑色產業鏈開始成熟,這個地下產業每年都會給互聯網造成數十億的損失。而在上一個時期技術還不成熟的黑客們,凡是堅持下來的,都已經成長為安全領域的高級人才,有的在安全公司貢獻著自己的專業技能,有的則帶著非常強的技術進入了黑色產業。此時期的黑客群體因為互相之間缺失信任已經不再具有開放和分享的精神,最為純粹的黑客精神實質上已經死亡。

整個互聯網籠罩在黑色產業鏈的陰影之下,每年數十億的經濟損失和數千萬的網民受害,以及黑客精神的死亡,使得我們沒有理由不把此時稱為黑暗時代。也許黑客精神所代表的Open、Free、Share,真的一去不復返了!

1.1.2 黑客技術的發展歷程

從黑客技術發展的角度看,在早期,黑客攻擊的目標以系統軟件居多。一方面,是由于這個時期的Web技術發展還遠遠不成熟;另一方面,則是因為通過攻擊系統軟件,黑客們往往能夠直接獲取root權限。這段時期,涌現出了非常多的經典漏洞以及“exploit”。比如著名的黑客組織TESO,就曾經編寫過一個攻擊SSH的exploit,并公然在exploit的banner中宣稱曾經利用這個exploit入侵過cia.gov(美國中央情報局)。

下面是這個exploithttp://staff.washington.edu/dittrich/misc/ssh-analysis.txt的一些信息。

    root@plac /bin >> ./ssh

    linux/x86 sshd1 exploit by zip/TESO (zip@james.kalifornia.com) - ripped from
    openssh 2.2.0 src
    greets: mray, random, big t, sh1fty, scut, dvorak
    ps. this sploit already owned cia.gov :/

    **please pick a type**

    Usage: ./ssh host [options]
    Options:
      -p port
      -b baseBase address to start bruteforcing distance, by default 0x1800,
    goes as high as 0x10000
      -t type
      -d          debug mode
      -o     Add this to delta_min

    types:

    0: linux/x86 ssh.com 1.2.26-1.2.31 rhl
    1: linux/x86 openssh 1.2.3 (maybe others)
    2: linux/x86 openssh 2.2.0p1 (maybe others)
    3: freebsd 4.x, ssh.com 1.2.26-1.2.31 rhl

有趣的是,這個exploit還曾經出現在著名電影《黑客帝國2》中:

電影《黑客帝國2》

放大屏幕上的文字可以看到:

電影《黑客帝國2》中使用的著名exploit

在早期互聯網中,Web并非互聯網的主流應用,相對來說,基于SMTP、POP3、FTP、IRC等協議的服務擁有著絕大多數的用戶。因此黑客們主要的攻擊目標是網絡、操作系統以及軟件等領域,Web安全領域的攻擊與防御技術均處于非常原始的階段。

相對于那些攻擊系統軟件的exploit而言,基于Web的攻擊,一般只能讓黑客獲得一個較低權限的賬戶,對黑客的吸引力遠遠不如直接攻擊系統軟件。

但是時代在發展,防火墻技術的興起改變了互聯網安全的格局。尤其是以Cisco、華為等為代表的網絡設備廠商,開始在網絡產品中更加重視網絡安全,最終改變了互聯網安全的走向。防火墻、ACL技術的興起,使得直接暴露在互聯網上的系統得到了保護。

比如一個網站的數據庫,在沒有保護的情況下,數據庫服務端口是允許任何人隨意連接的;在有了防火墻的保護后,通過ACL可以控制只允許信任來源的訪問。這些措施在很大程度上保證了系統軟件處于信任邊界之內,從而杜絕了大部分的攻擊來源。

2003年的沖擊波蠕蟲是一個里程碑式的事件,這個針對Windows操作系統RPC服務(運行在445端口)的蠕蟲,在很短的時間內席卷了全球,造成了數百萬臺機器被感染,損失難以估量。在此次事件后,網絡運營商們很堅決地在骨干網絡上屏蔽了135、445等端口的連接請求。此次事件之后,整個互聯網對于安全的重視達到了一個空前的高度。

運營商、防火墻對于網絡的封鎖,使得暴露在互聯網上的非Web服務越來越少,且Web技術的成熟使得Web應用的功能越來越強大,最終成為了互聯網的主流。黑客們的目光,也漸漸轉移到了Web這塊大蛋糕上。

實際上,在互聯網安全領域所經歷的這個階段,還有另外一個重要的分支,即桌面軟件安全,或者叫客戶端軟件安全。其代表是瀏覽器攻擊。一個典型的攻擊場景是,黑客構造一個惡意網頁,誘使用戶使用瀏覽器訪問該網頁,利用瀏覽器中存在的某些漏洞,比如一個緩沖區溢出漏洞,執行shellcode,通常是下載一個木馬并在用戶機器里執行。常見的針對桌面軟件的攻擊目標,還包括微軟的Office系列軟件、Adobe Acrobat Reader、多媒體播放軟件、壓縮軟件等裝機量大的流行軟件,都曾經成為黑客們的最愛。但是這種攻擊,和本書要討論的Web安全還是有著本質的區別,所以即使瀏覽器安全是Web安全的重要組成部分,但在本書中,也只會討論瀏覽器和Web安全有關的部分。

1.1.3 Web安全的興起

Web攻擊技術的發展也可以分為幾個階段。在Web 1.0時代,人們更多的是關注服務器端動態腳本的安全問題,比如將一個可執行腳本(俗稱webshell)上傳到服務器上,從而獲得權限。動態腳本語言的普及,以及Web技術發展初期對安全問題認知的不足導致很多“血案”的發生,同時也遺留下很多歷史問題,比如PHP語言至今仍然只能靠較好的代碼規范來保證沒有文件包含漏洞,而無法從語言本身杜絕此類安全問題的發生。

SQL注入的出現是Web安全史上的一個里程碑,它最早出現大概是在1999年,并很快就成為Web安全的頭號大敵。就如同緩沖區溢出出現時一樣,程序員們不得不日以繼夜地去修改程序中存在的漏洞。黑客們發現通過SQL注入攻擊,可以獲取很多重要的、敏感的數據,甚至能夠通過數據庫獲取系統訪問權限,這種效果并不比直接攻擊系統軟件差,Web攻擊一下子就流行起來。SQL注入漏洞至今仍然是Web安全領域中的一個重要組成部分。

XSS(跨站腳本攻擊)的出現則是Web安全史上的另一個里程碑。實際上,XSS的出現時間和SQL注入差不多,但是真正引起人們重視則是在大概2003年以后。在經歷了MySpace的XSS蠕蟲事件后,安全界對XSS的重視程度提高了很多,OWASP 2007 TOP 10威脅甚至把XSS排在榜首。

伴隨著Web 2.0的興起,XSS、CSRF等攻擊已經變得更為強大。Web攻擊的思路也從服務器端轉向了客戶端,轉向了瀏覽器和用戶。黑客們天馬行空的思路,覆蓋了Web的每一個環節,變得更加的多樣化,這些安全問題,在本書后續的章節中會深入地探討。

Web技術發展到今天,構建出了豐富多彩的互聯網。互聯網業務的蓬勃發展,也催生出了許多新興的腳本語言,比如Python、Ruby、NodeJS等,敏捷開發成為互聯網的主旋律。而手機技術、移動互聯網的興起,也給HTML 5帶來了新的機遇和挑戰。與此同時,Web安全技術,也將緊跟著互聯網發展的腳步,不斷地演化出新的變化。

1.2 黑帽子,白帽子

正如一個硬幣有兩面一樣,“黑客”也有好壞之分。在黑客的世界中,往往用帽子的顏色來比喻黑客的好壞。白帽子,則是指那些精通安全技術,但是工作在反黑客領域的專家們;而黑帽子,則是指利用黑客技術造成破壞,甚至進行網絡犯罪的群體。

同樣是研究安全,白帽子和黑帽子在工作時的心態是完全不同的。

對于黑帽子來說,只要能夠找到系統的一個弱點,就可以達到入侵系統的目的;而對于白帽子來說,必須找到系統的所有弱點,不能有遺漏,才能保證系統不會出現問題。這種差異是由于工作環境與工作目標的不同所導致的。白帽子一般為企業或安全公司服務,工作的出發點就是要解決所有的安全問題,因此所看所想必然要求更加的全面、宏觀;黑帽子的主要目的是要入侵系統,找到對他們有價值的數據,因此黑帽子只需要以點突破,找到對他們最有用的一點,以此滲透,因此思考問題的出發點必然是有選擇性的、微觀的。

從對待問題的角度來看,黑帽子為了完成一次入侵,需要利用各種不同漏洞的組合來達到目的,是在不斷地組合問題;而白帽子在設計解決方案時,如果只看到各種問題組合后產生的效果,就會把事情變復雜,難以細致入微地解決根本問題,所以白帽子必然是在不斷地分解問題,再對分解后的問題逐個予以解決。

這種定位的不對稱,也導致了白帽子的安全工作比較難做。“破壞永遠比建設容易”,但凡事都不是絕對的。要如何扭轉這種局面呢?一般來說,白帽子選擇的方法,是克服某種攻擊方法,而并非抵御單次的攻擊。比如設計一個解決方案,在特定環境下能夠抵御所有已知的和未知的SQL Injection問題。假設這個方案的實施周期是3個月,那么執行3個月后,所有的SQL Injection問題都得到了解決,也就意味著黑客再也無法利用SQL Injection這一可能存在的弱點入侵網站了。如果做到了這一點,那么白帽子們就在SQL Injection的局部對抗中化被動為主動了。

但這一切都是理想狀態,在現實世界中,存在著各種各樣不可回避的問題。工程師們很喜歡一句話:“No Patch For Stupid! ”,在安全領域也普遍認為:“最大的漏洞就是人!”。寫得再好的程序,在有人參與的情況下,就可能會出現各種各樣不可預知的情況,比如管理員的密碼有可能泄露,程序員有可能關掉了安全的配置參數,等等。安全問題往往發生在一些意想不到的地方。

另一方面,防御技術在不斷完善的同時,攻擊技術也在不斷地發展。這就像一場軍備競賽,看誰跑在前面。白帽子們剛把某一種漏洞全部堵上,黑帽子們轉眼又會玩出新花樣。誰能在技術上領先,誰就能占據主動。互聯網技術日新月異,在新技術領域的發展中,也存在著同樣的博弈過程。可現狀是,如果新技術不在一開始就考慮安全設計的話,防御技術就必然會落后于攻擊技術,導致歷史不斷地重復。

1.3 返璞歸真,揭秘安全的本質

講了很多題外話,最終回到正題上。這是一本講Web安全的書,在本書中除了講解必要的攻擊技術原理之外,最終重心還是要放在防御的思路和實現的技術上。

在進行具體技術的講解之前,我們需要先清楚地認識到“安全的本質”,或者說,“安全問題的本質”。

安全是什么?什么樣的情況下會產生安全問題?我們要如何看待安全問題?只有搞明白了這些最基本的問題,才能明白一切防御技術的出發點,才能明白為什么我們要這樣做,要那樣做。

在武俠小說中,一個真正的高手,對武功有著最透徹、最本質的理解,達到了返璞歸真的境界。在安全領域,筆者認為搞明白了安全的本質,就好比學會了“獨孤九劍”,天下武功萬變不離其宗,遇到任何復雜的情況都可以輕松應對,設計任何的安全方案也都可以信手拈來了。

那么,一個安全問題是如何產生的呢?我們不妨先從現實世界入手。火車站、機場里,在乘客們開始正式旅程之前,都有一個必要的程序:安全檢查。機場的安全檢查,會掃描乘客的行李箱,檢查乘客身上是否攜帶了打火機、可燃液體等危險物品。抽象地說,這種安全檢查,就是過濾掉有害的、危險的東西。因為在飛行的過程中,飛機遠離地面,如果發生危險,將會直接危害到乘客們的生命安全。因此,飛機是一個高度敏感和重要的區域,任何有危害的物品都不應該進入這一區域。為達到這一目標,登機前的安全檢查就是一個非常有必要的步驟。

從安全的角度來看,我們將不同重要程度的區域劃分出來:

安全檢查的過程按照需要進行過濾

通過一個安全檢查(過濾、凈化)的過程,可以梳理未知的人或物,使其變得可信任。被劃分出來的具有不同信任級別的區域,我們稱為信任域,劃分兩個不同信任域之間的邊界,我們稱為信任邊界。

數據從高等級的信任域流向低等級的信任域,是不需要經過安全檢查的;數據從低等級的信任域流向高等級的信任域,則需要經過信任邊界的安全檢查。

我們在機場通過安檢后,想要從候機廳出來,是不需要做檢查的;但是想要再回到候機廳,則需要再做一次安全檢查,就是這個道理。

筆者認為,安全問題的本質是信任的問題。

一切的安全方案設計的基礎,都是建立在信任關系上的。我們必須相信一些東西,必須有一些最基本的假設,安全方案才能得以建立;如果我們否定一切,安全方案就會如無源之水,無根之木,無法設計,也無法完成。

舉例來說,假設我們有份很重要的文件要好好保管起來,能想到的一個方案是把文件“鎖”到抽屜里。這里就包含了幾個基本的假設,首先,制作這把鎖的工匠是可以信任的,他沒有私自藏一把鑰匙;其次,制作抽屜的工匠沒有私自給抽屜裝一個后門;最后,鑰匙還必須要保管在一個不會出問題的地方,或者交給值得信任的人保管。反之,如果我們一切都不信任,那么也就不可能認為文件放在抽屜里是安全的。

當制鎖的工匠無法打開鎖時,文件才是安全的,這是我們的假設前提之一。但是如果那個工匠私自藏有一把鑰匙,那么這份文件也就不再安全了。這個威脅存在的可能性,依賴于對工匠的信任程度。如果我們信任工匠,那么在這個假設前提下,我們就能確定文件的安全性。這種對條件的信任程度,是確定對象是否安全的基礎。

在現實生活中,我們很少設想最極端的前提條件,因為極端的條件往往意味者小概率以及高成本,因此在成本有限的情況下,我們往往會根據成本來設計安全方案,并將一些可能性較大的條件作為決策的主要依據。

比如在設計物理安全時,根據不同的地理位置、不同的政治環境等,需要考慮臺風、地震、戰爭等因素。但在考慮、設計這些安全方案時,根據其發生的可能性,需要有不同的側重點。比如在大陸深處,考慮臺風的因素則顯得不太實際;同樣的道理,在大陸板塊穩定的地區,考慮地震的因素也會帶來較高的成本。而極端的情況比如“彗星撞擊地球后如何保證機房不受影響”的問題,一般都不在考慮之中,因為發生的可能性太小。

從另一個角度來說,一旦我們作為決策依據的條件被打破、被繞過,那么就會導致安全假設的前提條件不再可靠,變成一個偽命題。因此,把握住信任條件的度,使其恰到好處,正是設計安全方案的難點所在,也是安全這門學問的藝術魅力所在。

1.4 破除迷信,沒有銀彈

在解決安全問題的過程中,不可能一勞永逸,也就是說“沒有銀彈”。

一般來說,人們都會討厭麻煩的事情,在潛意識里希望能夠讓麻煩越遠越好。而安全,正是一件麻煩的事情,而且是無法逃避的麻煩。任何人想要一勞永逸地解決安全問題,都屬于一相情愿,是“自己騙自己”,是不現實的。

安全是一個持續的過程。

自從互聯網有了安全問題以來,攻擊和防御技術就在不斷碰撞和對抗的過程中得到發展。從微觀上來說,在某一時期可能某一方占了上風;但是從宏觀上來看,某一時期的攻擊或防御技術,都不可能永遠有效,永遠用下去。這是因為防御技術在發展的同時,攻擊技術也在不斷發展,兩者是互相促進的辯證關系。以不變的防御手段對抗不斷發展的攻擊技術,就犯了刻舟求劍的錯誤。在安全的領域中,沒有銀彈。

很多安全廠商在推銷自己產品時,會向用戶展示一些很美好的藍圖,似乎他們的產品無所不能,購買之后用戶就可以睡得安穩了。但實際上,安全產品本身也需要不斷地升級,也需要有人來運營。產品本身也需要一個新陳代謝的過程,否則就會被淘汰。在現代的互聯網產品中,自動升級功能已經成為一個標準配置,一個有活力的產品總是會不斷地改進自身。

微軟在發布Vista時,曾信誓旦旦地保證這是有史以來最安全的操作系統。我們看到了微軟的努力,在Vista下的安全問題確實比它的前輩們(Windows XP、Windows 2000、Windows 2003等)少了許多,尤其是高危的漏洞。但即便如此,在2008年的Pwn2own競賽上,Vista也被黑客們攻擊成功。Pwn2own競賽是每年舉行的讓黑客們任意攻擊操作系統的一次盛會,一般黑客們都會提前準備好0day漏洞的攻擊程序,以求在Pwn2own上一舉奪魁。

黑客們在不斷地研究和尋找新的攻擊技術,作為防御的一方,沒有理由不持續跟進。微軟近幾年在產品的安全中做得越來越好,其所推崇的安全開發流程,將安全檢查貫穿于整個軟件生命周期中,經過實踐檢驗,證明這是一條可行的道路。對每一個產品,都要持續地實施嚴格的安全檢查,這是微軟通過自身的教訓傳授給業界的寶貴經驗。而安全檢查本身也需要不斷更新,增加針對新型攻擊方式的檢測與防御方案。

1.5 安全三要素

既然安全方案的設計與實施過程中沒有銀彈,注定是一個持續進行的過程,那么我們該如何開始呢?其實安全方案的設計也有著一定的思路與方法可循,借助這些方法,能夠理清我們的思路,幫助我們設計出合理、優秀的解決方案。

因為信任關系被破壞,從而產生了安全問題。我們可以通過信任域的劃分、信任邊界的確定,來發現問題是在何處產生的。這個過程可以讓我們明確目標,那接下來該怎么做呢?

在設計安全方案之前,要正確、全面地看待安全問題。

要全面地認識一個安全問題,我們有很多種辦法,但首先要理解安全問題的組成屬性。前人通過無數實踐,最后將安全的屬性總結為安全三要素,簡稱CIA

安全三要素是安全的基本組成元素,分別是機密性(Confidentiality)、完整性(Integrity)、可用性(Availability)

機密性要求保護數據內容不能泄露,加密是實現機密性要求的常見手段。

比如在前文的例子中,如果文件不是放在抽屜里,而是放在一個透明的玻璃盒子里,那么雖然外人無法直接取得文件,但因為玻璃盒子是透明的,文件內容可能還是會被人看到,所以不符合機密性要求。但是如果給文件增加一個封面,掩蓋了文件內容,那么也就起到了隱藏的效果,從而滿足了機密性要求。可見,我們在選擇安全方案時,需要靈活變通,因地制宜,沒有一成不變的方案。

完整性則要求保護數據內容是完整、沒有被篡改的。常見的保證一致性的技術手段是數字簽名。

傳說清朝康熙皇帝的遺詔,寫的是“傳位十四子”,被當時還是四阿哥的胤禛篡改了遺詔,變成了“傳位于四子”。姑且不論傳說的真實性,在故事中,對這份遺詔的保護顯然沒有達到完整性要求。如果在當時有數字簽名等技術,遺詔就很難被篡改。從這個故事中也可以看出數據的完整性、一致性的重要意義。

可用性要求保護資源是“隨需而得”。

假設一個停車場里有100個車位,在正常情況下,可以停100輛車。但是在某一天,有個壞人搬了100塊大石頭,把每個車位都占用了,停車場無法再提供正常服務。在安全領域中這種攻擊叫做拒絕服務攻擊,簡稱DoS(Denial of Service)。拒絕服務攻擊破壞的是安全的可用性。

在安全領域中,最基本的要素就是這三個,后來還有人想擴充這些要素,增加了諸如可審計性、不可抵賴性等,但最最重要的還是以上三個要素。在設計安全方案時,也要以這三個要素為基本的出發點,去全面地思考所面對的問題。

1.6 如何實施安全評估

有了前面的基礎,我們就可以正式開始分析并解決安全問題了。一個安全評估的過程,可以簡單地分為4個階段:資產等級劃分、威脅分析、風險分析、確認解決方案。

安全評估的過程

一般來說,按照這個過程來實施安全評估,在結果上不會出現較大的問題。這個實施的過程是層層遞進的,前后之間有因果關系。

如果面對的是一個尚未評估的系統,那么應該從第一個階段開始實施;如果是由專職的安全團隊長期維護的系統,那么有些階段可以只實施一次。在這幾個階段中,上一個階段將決定下一個階段的目標,需要實施到什么程度。

1.6.1 資產等級劃分

資產等級劃分是所有工作的基礎,這項工作能夠幫助我們明確目標是什么,要保護什么。

我們前面提到安全三要素時,機密性和完整性都是與數據相關的,在可用性的定義里,筆者則用到了“資源”一詞。“資源”這個概念描述的范圍比數據要更加廣闊,但很多時候,資源的可用性也可以理解為數據的可用性。

在互聯網的基礎設施已經比較完善的今天,互聯網的核心其實是由用戶數據驅動的——用戶產生業務,業務產生數據。互聯網公司除了擁有一些固定資產,如服務器等死物外,最核心的價值就是其擁有的用戶數據,所以——

互聯網安全的核心問題,是數據安全的問題。

這與我們做資產評估又有什么關系呢?有,因為對互聯網公司擁有的資產進行等級劃分,就是對數據做等級劃分。有的公司最關心的是客戶數據,有的公司最關心的是員工資料信息,根據各自業務的不同,側重點也不同。做資產等級劃分的過程,需要與各個業務部門的負責人一一溝通,了解公司最重要的資產是什么,他們最看重的數據是什么。通過訪談的形式,安全部門才能熟悉、了解公司的業務,公司所擁有的數據,以及不同數據的重要程度,為后續的安全評估過程指明方向。

當完成資產等級劃分后,對要保護的目標已經有了一個大概的了解,接下來就是要劃分信任域和信任邊界了。通常我們用一種最簡單的劃分方式,就是從網絡邏輯上來劃分。比如最重要的數據放在數據庫里,那么把數據庫的服務器圈起來;Web應用可以從數據庫中讀/寫數據,并對外提供服務,那再把Web服務器圈起來;最外面是不可信任的Internet。

簡單網站信任模型

這是最簡單的例子,在實際中會遇到比這復雜許多的情況。比如同樣是兩個應用,互相之間存在數據交互業務,那么就要考慮這里的數據交互對于各自應用來說是否是可信的,是否應該在兩個應用之間劃一個邊界,然后對流經邊界的數據做安全檢查。

1.6.2 威脅分析

信任域劃好之后,我們如何才能確定危險來自哪里呢?在安全領域里,我們把可能造成危害的來源稱為威脅(Threat),而把可能會出現的損失稱為風險(Risk)。風險一定是和損失聯系在一起的,很多專業的安全工程師也經常把這兩個概念弄混,在寫文檔時張冠李戴。現在把這兩個概念區分好,有助于我們接下來要提到的“威脅建模”和“風險分析”兩個階段,這兩個階段的聯系是很緊密的。

什么是威脅分析?威脅分析就是把所有的威脅都找出來。怎么找?一般是采用頭腦風暴法。當然,也有一些比較科學的方法,比如使用一個模型,幫助我們去想,在哪些方面有可能會存在威脅,這個過程能夠避免遺漏,這就是威脅建模。

在本書中介紹一種威脅建模的方法,它最早是由微軟提出的,叫做STRIDE模型。

STRIDE是6個單詞的首字母縮寫,我們在分析威脅時,可以從以下6個方面去考慮。

在進行威脅分析時,要盡可能地不遺漏威脅,頭腦風暴的過程可以確定攻擊面(Attack Surface)。

在維護系統安全時,最讓安全工程師沮喪的事情就是花費很多的時間與精力實施安全方案,但是攻擊者卻利用了事先完全沒有想到的漏洞(漏洞的定義:系統中可能被威脅利用以造成危害的地方。)完成入侵。這往往就是由于在確定攻擊面時,想的不夠全面而導致的。

以前有部老電影叫做《智取華山》,是根據真實事件改編的。1949年5月中旬,打響了“陜中戰役”,國民黨保安第6旅旅長兼第8區專員韓子佩率殘部400余人逃上華山,企圖憑借“自古華山一條道”的天險負隅頑抗。路東總隊決定派參謀劉吉堯帶偵察小分隊前往偵察,劉吉堯率領小分隊,在當地村民的帶領下,找到了第二條路:爬懸崖!克服種種困難,最終順利地完成了任務。戰后,劉吉堯光榮地出席了全國英模代表大會,并被授予“全國特等戰斗英雄”榮譽稱號。

我們用安全眼光來看這次戰斗。國民黨部隊在進行“威脅分析”時,只考慮到“自古華山一條道”,所以在正路上布重兵,而完全忽略了其他的可能。他們“相信”其他道路是不存在的,這是他們實施安全方案的基礎,而一旦這個信任基礎不存在了,所有的安全方案都將化作浮云,從而被共產黨的部隊擊敗。

所以威脅分析是非常重要的一件事情,很多時候還需要經常回顧和更新現有的模型。可能存在很多威脅,但并非每個威脅都會造成難以承受的損失。一個威脅到底能夠造成多大的危害,如何去衡量它?這就要考慮到風險了。我們判斷風險高低的過程,就是風險分析的過程。在“風險分析”這個階段,也有模型可以幫助我們進行科學的思考。

1.6.3 風險分析

風險由以下因素組成:

    Risk = Probability * Damage Potential

影響風險高低的因素,除了造成損失的大小外,還需要考慮到發生的可能性。地震的危害很大,但是地震、火山活動一般是在大陸板塊邊緣頻繁出現,比如日本、印尼就處于這些地理位置,因此地震頻發;而在大陸板塊中心,若是地質結構以整塊的巖石為主,則不太容易發生地震,因此地震的風險就要小很多。我們在考慮安全問題時,要結合具體情況,權衡事件發生的可能性,才能正確地判斷出風險。

如何更科學地衡量風險呢?這里再介紹一個DREAD模型,它也是由微軟提出的。DREAD也是幾個單詞的首字母縮寫,它指導我們應該從哪些方面去判斷一個威脅的風險程度。

在DREAD模型里,每一個因素都可以分為高、中、低三個等級。在上表中,高、中、低三個等級分別以3、2、1的分數代表其權重值,因此,我們可以具體計算出某一個威脅的風險值。

以《智取華山》為例,如果國民黨在威脅建模后發現存在兩個主要威脅:第一個威脅是從正面入口強攻,第二個威脅是從后山小路爬懸崖上來。那么,這兩個威脅對應的風險分別計算如下:

走正面的入口:

    Risk = D(3) + R(3) + E(3) + A(3) + D(3) = 3+3+3+3+3=15

走后山小路:

    Risk = D(3) + R(1) + E(1) + A(3) + D(1) = 3+1+1+3+1=9

如果我們把風險高低定義如下:

    高危:12~15分        中危:8~11分        低危:0~7分

那么,正面入口是最高危的,必然要派重兵把守;而后山小路竟然是中危的,因此也不能忽視。之所以會被這個模型判斷為中危的原因,就在于一旦被突破,造成的損失太大,失敗不起,所以會相應地提高該風險值。

介紹完威脅建模和風險分析的模型后,我們對安全評估的整體過程應該有了一個大致的了解。在任何時候都應該記住——模型是死的,人是活的,再好的模型也是需要人來使用的,在確定攻擊面,以及判斷風險高低時,都需要有一定的經驗,這也是安全工程師的價值所在。類似STRIDE和DREAD的模型可能還有很多,不同的標準會對應不同的模型,只要我們覺得這些模型是科學的,能夠幫到我們,就可以使用。但模型只能起到一個輔助的作用,最終做出決策的還是人。

1.6.4 設計安全方案

安全評估的產出物,就是安全解決方案。解決方案一定要有針對性,這種針對性是由資產等級劃分、威脅分析、風險分析等階段的結果給出的。

設計解決方案不難,難的是如何設計一個好的解決方案。設計一個好的解決方案,是真正考驗安全工程師水平的時候。

很多人認為,安全和業務是沖突的,因為往往為了安全,要犧牲業務的一些易用性或者性能,筆者不太贊同這種觀點。從產品的角度來說,安全也應該是產品的一種屬性。一個從未考慮過安全的產品,至少是不完整的。

比如,我們要評價一個杯子是否好用,除了它能裝水,能裝多少水外,還要思考這個杯子內壁的材料是否會溶解在水里,是否會有毒,在高溫時會不會熔化,在低溫時是否易碎,這些問題都直接影響用戶使用杯子的安全性。

對于互聯網來說,安全是要為產品的發展與成長保駕護航的。我們不能使用“粗暴”的安全方案去阻礙產品的正常發展,所以應該形成這樣一種觀點:沒有不安全的業務,只有不安全的實現方式。產品需求,尤其是商業需求,是用戶真正想要的東西,是業務的意義所在,在設計安全方案時應該盡可能地不要改變商業需求的初衷。

作為安全工程師,要想的就是如何通過簡單而有效的方案,解決遇到的安全問題。安全方案必須能夠有效抵抗威脅,但同時不能過多干涉正常的業務流程,在性能上也不能拖后腿。

好的安全方案對用戶應該是透明的,盡可能地不要改變用戶的使用習慣。

微軟在推出Windows Vista時,有一個新增的功能叫UAC,每當系統里的軟件有什么敏感動作時,UAC就會彈出來詢問用戶是否允許該行為。這個功能在Vista眾多失敗的原因中是被人詬病最多的一個。如果用戶能夠分辨什么樣的行為是安全的,那么還要安全軟件做什么?同樣的問題出現在很多主動防御的桌面安全保護軟件中,它們動輒彈出個對話框詢問用戶是否允許目標的行為,這是非常荒謬的用戶體驗。

好的安全產品或模塊除了要兼顧用戶體驗外,還要易于持續改進。一個好的安全模塊,同時也應該是一個優秀的程序,從設計上也需要做到高聚合、低耦合、易于擴展。比如Nmap的用戶就可以自己根據需要寫插件,實現一些更為復雜的功能,滿足個性化需求。

最終,一個優秀的安全方案應該具備以下特點:

? 能夠有效解決問題;

? 用戶體驗好;

? 高性能;

? 低耦合;

? 易于擴展與升級。

關于產品安全性的問題,在本書的“互聯網業務安全”一章中還會繼續深入闡述。

1.7 白帽子兵法

在上節講述了實施安全評估的基本過程,安全評估最后的產出物就是安全方案,但在具體設計安全方案時有什么樣的技巧呢?本節將講述在實戰中可能用到的方法。

1.7.1 Secure By DefauIt原則

在設計安全方案時,最基本也最重要的原則就是“Secure by Default”。在做任何安全設計時,都要牢牢記住這個原則。一個方案設計得是否足夠安全,與有沒有應用這個原則有很大的關系。實際上,“Secure by Default”原則,也可以歸納為白名單、黑名單的思想。如果更多地使用白名單,那么系統就會變得更安全。

1.7.1.1 黑名單、白名單

比如,在制定防火墻的網絡訪問控制策略時,如果網站只提供Web服務,那么正確的做法是只允許網站服務器的80和443端口對外提供服務,屏蔽除此之外的其他端口。這是一種“白名單”的做法;如果使用“黑名單”,則可能會出現問題。假設黑名單的策略是:不允許SSH端口對Internet開放,那么就要審計SSH的默認端口:22端口是否開放了Internet。但在實際工作過程中,經常會發現有的工程師為了偷懶或圖方便,私自改變了SSH的監聽端口,比如把SSH的端口從22改到了2222,從而繞過了安全策略。

又比如,在網站的生產環境服務器上,應該限制隨意安裝軟件,而需要制定統一的軟件版本規范。這個規范的制定,也可以選擇白名單的思想來實現。按照白名單的思想,應該根據業務需求,列出一個允許使用的軟件以及軟件版本的清單,在此清單外的軟件則禁止使用。如果允許工程師在服務器上隨意安裝軟件的話,則可能會因為安全部門不知道、不熟悉這些軟件而導致一些漏洞,從而擴大攻擊面。

在Web安全中,對白名單思想的運用也比比皆是。比如應用處理用戶提交的富文本時,考慮到XSS的問題,需要做安全檢查。常見的XSS Filter一般是先對用戶輸入的HTML原文作HTML Parse,解析成標簽對象后,再針對標簽匹配XSS的規則。這個規則列表就是一個黑白名單。如果選擇黑名單的思想,則這套規則里可能是禁用諸如<script>、<iframe>等標簽。但是黑名單可能會有遺漏,比如未來瀏覽器如果支持新的HTML標簽,那么此標簽可能就不在黑名單之中了。如果選擇白名單的思想,就能避免這種問題——在規則中,只允許用戶輸入諸如<a>、<img>等需要用到的標簽。對于如何設計一個好的XSS防御方案,在“跨站腳本攻擊”一章中還會詳細講到,不在此贅述了。

然而,并不是用了白名單就一定安全了。有朋友可能會問,作者剛才講到選擇白名單的思想會更安全,現在又說不一定,這不是自相矛盾嗎?我們可以仔細分析一下白名單思想的本質。在前文中提到:“安全問題的本質是信任問題,安全方案也是基于信任來做的”。選擇白名單的思想,基于白名單來設計安全方案,其實就是信任白名單是好的,是安全的。但是一旦這個信任基礎不存在了,那么安全就蕩然無存。

在Flash跨域訪問請求里,是通過檢查目標資源服務器端的crossdomain.xml文件來驗證是否允許客戶端的Flash跨域發起請求的,它使用的是白名單的思想。比如下面這個策略文件:

    <cross-domain-policy>
    <allow-access-from domain="*.taobao.com"/>
    <allow-access-from domain="*.taobao.net"/>
    <allow-access-from domain="*.taobaocdn.com"/>
    <allow-access-from domain="*.tbcdn.cn"/>
    <allow-access-from domain="*.allyes.com"/>
    </cross-domain-policy>

指定了只允許特定域的Flash對本域發起請求。可是如果這個信任列表中的域名變得不可信了,那么問題就會隨之而來。比如:

    <cross-domain-policy>
    <allow-access-from domain="*"/>
    </cross-domain-policy>

通配符“*”,代表來自任意域的Flash都能訪問本域的數據,因此就造成了安全隱患。所以在選擇使用白名單時,需要注意避免出現類似通配符“*”的問題。

1.7.1.2 最小權限原則

Secure By Default的另一層含義就是“最小權限原則”。最小權限原則也是安全設計的基本原則之一。最小權限原則要求系統只授予主體必要的權限,而不要過度授權,這樣能有效地減少系統、網絡、應用、數據庫出錯的機會。

比如在Linux系統中,一種良好的操作習慣是使用普通賬戶登錄,在執行需要root權限的操作時,再通過sudo命令完成。這樣能最大化地降低一些誤操作導致的風險;同時普通賬戶被盜用后,與root帳戶被盜用所導致的后果是完全不同的。

在使用最小權限原則時,需要認真梳理業務所需要的權限,在很多時候,開發者并不會意識到業務授予用戶的權限過高。在通過訪談了解業務時,可以多設置一些反問句,比如:您確定您的程序一定需要訪問Internet嗎?通過此類問題,來確定業務所需的最小權限。

1.7.2 縱深防御原則

與Secure by Default一樣,Defense in Depth(縱深防御)也是設計安全方案時的重要指導思想。

縱深防御包含兩層含義:首先,要在各個不同層面、不同方面實施安全方案,避免出現疏漏,不同安全方案之間需要相互配合,構成一個整體;其次,要在正確的地方做正確的事情,即:在解決根本問題的地方實施針對性的安全方案。

某礦泉水品牌曾經在廣告中展示了一滴水的生產過程:經過十多層的安全過濾,去除有害物質,最終得到一滴飲用水。這種多層過濾的體系,就是一種縱深防御,是有立體層次感的安全方案。

縱深防御并不是同一個安全方案要做兩遍或多遍,而是要從不同的層面、不同的角度對系統做出整體的解決方案。我們常常聽到“木桶理論”這個詞,說的是一個桶能裝多少水,不是取決于最長的那塊板,而是取決于最短的那塊板,也就是短板。設計安全方案時最怕出現短板,木桶的一塊塊板子,就是各種具有不同作用的安全方案,這些板子要緊密地結合在一起,才能組成一個不漏水的木桶。

在常見的入侵案例中,大多數是利用Web應用的漏洞,攻擊者先獲得一個低權限的webshell,然后通過低權限的webshell上傳更多的文件,并嘗試執行更高權限的系統命令,嘗試在服務器上提升權限為root;接下來攻擊者再進一步嘗試滲透內網,比如數據庫服務器所在的網段。

在這類入侵案例中,如果在攻擊過程中的任何一個環節設置有效的防御措施,都有可能導致入侵過程功虧一簣。但是世上沒有萬能靈藥,也沒有哪種解決方案能解決所有問題,因此非常有必要將風險分散到系統的各個層面。就入侵的防御來說,我們需要考慮的可能有Web應用安全、OS系統安全、數據庫安全、網絡環境安全等。在這些不同層面設計的安全方案,將共同組成整個防御體系,這也就是縱深防御的思想。

縱深防御的第二層含義,是要在正確的地方做正確的事情。如何理解呢?它要求我們深入理解威脅的本質,從而做出正確的應對措施。

在XSS防御技術的發展過程中,曾經出現過幾種不同的解決思路,直到最近幾年XSS的防御思路才逐漸成熟和統一。

XSS防御技術的發展過程

在一開始的方案中,主要是過濾一些特殊字符,比如:

<<笑傲江湖>> 會變成 笑傲江湖

尖括號被過濾掉了。

但是這種粗暴的做法常常會改變用戶原本想表達的意思,比如:

1<2 可能會變成 1 2

造成這種“烏龍”的結果就是因為沒有“在正確的地方做正確的事情”。對于XSS防御,對系統取得的用戶輸入進行過濾其實是不太合適的,因為XSS真正產生危害的場景是在用戶的瀏覽器上,或者說服務器端輸出的HTML頁面,被注入了惡意代碼。只有在拼裝HTML時輸出,系統才能獲得HTML上下文的語義,才能判斷出是否存在誤殺等情況。所以“在正確的地方做正確的事情”,也是縱深防御的一種含義——必須把防御方案放到最合適的地方去解決。(XSS防御的更多細節請參考“跨站腳本攻擊”一章。)

近幾年安全廠商為了迎合市場的需要,推出了一種產品叫UTM,全稱是“統一威脅管理”(Unified Threat Management)。UTM幾乎集成了所有主流安全產品的功能,比如防火墻、VPN、反垃圾郵件、IDS、反病毒等。UTM的定位是當中小企業沒有精力自己做安全方案時,可以在一定程度上提高安全門檻。但是UTM并不是萬能藥,很多問題并不應該在網絡層、網關處解決,所以實際使用時效果未必好,它更多的是給用戶買個安心。

對于一個復雜的系統來說,縱深防御是構建安全體系的必要選擇。

1.7.3 數據與代碼分離原則

另一個重要的安全原則是數據與代碼分離原則。這一原則廣泛適用于各種由于“注入”而引發安全問題的場景。

實際上,緩沖區溢出,也可以認為是程序違背了這一原則的后果——程序在棧或者堆中,將用戶數據當做代碼執行,混淆了代碼與數據的邊界,從而導致安全問題的發生。

在Web安全中,由“注入”引起的問題比比皆是,如XSS、SQL Injection、CRLF Injection、X-Path Injection等。此類問題均可以根據“數據與代碼分離原則”設計出真正安全的解決方案,因為這個原則抓住了漏洞形成的本質原因。

以XSS為例,它產生的原因是HTML Injection或JavaScript Injection,如果一個頁面的代碼如下:

    <html>
    <head>test</head>
    <body>
    $var
    </body>
    </html>

其中 $var是用戶能夠控制的變量,那么對于這段代碼來說:

    <html>
    <head>test</head>
    <body>

    </body>
    </html>

就是程序的代碼執行段。

    $var

就是程序的用戶數據片段。

如果把用戶數據片段 $var當成代碼片段來解釋、執行,就會引發安全問題。

比如,當$var的值是:

    <script  src=http://evil></script>

時,用戶數據就被注入到代碼片段中。解析這段腳本并執行的過程,是由瀏覽器來完成的——瀏覽器將用戶數據里的<script>標簽當做代碼來解釋——這顯然不是程序開發者的本意。

根據數據與代碼分離原則,在這里應該對用戶數據片段 $var進行安全處理,可以使用過濾、編碼等手段,把可能造成代碼混淆的用戶數據清理掉,具體到這個案例中,就是針對 <、> 等符號做處理。

有的朋友可能會問了:我這里就是要執行一個<script>標簽,要彈出一段文字,比如:“你好!”,那怎么辦呢?

在這種情況下,數據與代碼的情況就發生了變化,根據數據與代碼分離原則,我們就應該重寫代碼片段:

    <html>
    <head>test</head>
    <body>
    <script>
    alert("$var1");
    </script>
    </body>
    </html>

在這種情況下,<script>標簽也變成了代碼片段的一部分,用戶數據只有 $var1能夠控制,從而杜絕了安全問題的發生。

1.7.4 不可預測性原則

前面介紹的幾條原則:Secure By Default,是時刻要牢記的總則;縱深防御,是要更全面、更正確地看待問題;數據與代碼分離,是從漏洞成因上看問題;接下來要講的“不可預測性”原則,則是從克服攻擊方法的角度看問題。

微軟的Windows系統用戶多年來深受緩沖區溢出之苦,因此微軟在Windows的新版本中增加了許多對抗緩沖區溢出等內存攻擊的功能。微軟無法要求運行在系統中的軟件沒有漏洞,因此它采取的做法是讓漏洞的攻擊方法失效。比如,使用DEP來保證堆棧不可執行,使用ASLR讓進程的棧基址隨機變化,從而使攻擊程序無法準確地猜測到內存地址,大大提高了攻擊的門檻。經過實踐檢驗,證明微軟的這個思路確實是有效的——即使無法修復code,但是如果能夠使得攻擊的方法無效,那么也可以算是成功的防御。

微軟使用的ASLR技術,在較新版本的Linux內核中也支持。在ASLR的控制下,一個程序每次啟動時,其進程的棧基址都不相同,具有一定的隨機性,對于攻擊者來說,這就是“不可預測性”。

不可預測性(Unpredictable),能有效地對抗基于篡改、偽造的攻擊。我們看看如下場景:

假設一個內容管理系統中的文章序號,是按照數字升序排列的,比如id=1000, id=1002, id=1003……

這樣的順序,使得攻擊者能夠很方便地遍歷出系統中的所有文章編號:找到一個整數,依次遞增即可。如果攻擊者想要批量刪除這些文章,寫個簡單的腳本:

    for (i=0; i<100000; i++){
      Delete(url+"? id="+i);
    }

就可以很方便地達到目的。但是如果該內容管理系統使用了“不可預測性”原則,將id的值變得不可預測,會產生什么結果呢?

id=asldfjaefsadlf, id=adsfalkennffxc, id=poerjfweknfd……

id的值變得完全不可預測了,攻擊者再想批量刪除文章,只能通過爬蟲把所有的頁面id全部抓取下來,再一一進行分析,從而提高了攻擊的門檻。

不可預測性原則,可以巧妙地用在一些敏感數據上。比如在CSRF的防御技術中,通常會使用一個token來進行有效防御。這個token能成功防御CSRF,就是因為攻擊者在實施CSRF攻擊的過程中,是無法提前預知這個token值的,因此要求token足夠復雜時,不能被攻擊者猜測到。(具體細節請參考“跨站點請求偽造”一章。)

不可預測性的實現往往需要用到加密算法、隨機數算法、哈希算法,好好使用這條原則,在設計安全方案時往往會事半功倍。

1.8 小結

本章歸納了筆者對于安全世界的認識和思考,從互聯網安全的發展史說起,揭示了安全問題的本質,以及應該如何展開安全工作,最后總結了設計安全方案的幾種思路和原則。在后續的章節中,將繼續揭示Web安全的方方面面,并深入理解攻擊原理和正確的解決之道——我們會面對各種各樣的攻擊,解決方案為什么要這樣設計,為什么這最合適?這一切的出發點,都可以在本章中找到本質的原因。

安全是一門樸素的學問,也是一種平衡的藝術。無論是傳統安全,還是互聯網安全,其內在的原理都是一樣的。我們只需抓住安全問題的本質,之后無論遇到任何安全問題(不僅僅局限于Web安全或互聯網安全),都會無往而不利,因為我們已經真正地懂得了如何用安全的眼光來看待這個世界!

(附)誰來為漏洞買單?http://hi.baidu.com/aullik5/blog/item/d4b8c81270601c3fdd54013e.html

昨天介紹了PHP中is_a()函數功能改變引發的問題http://hi.baidu.com/aullik5/blog/item/60d2b5fc2524c30a09244d0c.html,后來發現很多朋友不認同這是一個漏洞,原因是通過良好的代碼習慣能夠避免該問題,比如寫一個安全的__autoload()函數。

我覺得我有必要講講一些安全方面的哲學問題,但這些想法只代表我個人的觀點,是我的安全世界觀。

互聯網本來是安全的,自從有了研究安全的人,就變得不安全了。

所有的程序本來也沒有漏洞,只有功能,但當一些功能被用于破壞,造成損失時,也就成了漏洞。

我們定義一個功能是否是漏洞,只看后果,而不應該看過程。

計算機用0和1定義了整個世界,但在整個世界中,并非所有事情都能簡單地用“是” 或者“非”來判斷,漏洞也是如此,因為破壞有程度輕重之分,當破壞程度超過某一臨界值時,多數人(注意不是所有人)會接受這是一個漏洞的事實。但事物是變化的,這個臨界值也不是一成不變的,“多數人”也不是一成不變的,所以我們要用變化的觀點去看待變化的事物。

泄露用戶個人信息,比如電話、住址,在以前幾乎稱不上漏洞,因為沒有人利用;但在互聯網越來越關心用戶隱私的今天,這就變成了一個嚴重的問題,因為有無數的壞人時刻在想著利用這些信息搞破壞,非法攫取利益。所以,今天如果發現某網站能夠批量、未經授權獲取到用戶個人信息,這就是一個漏洞。

再舉個例子。用戶登錄的memberID是否屬于機密信息?在以往做信息安全,我們都只知道“密碼”、“安全問題”等傳統意義上的機密信息需要保護。但是在今天,在網站的業務設計中,我們發現loginID也應該屬于需要保護的信息。因為loginID一旦泄露后,可能會導致被暴力破解;甚至有的用戶將loginID當成密碼的一部分,會被黑客猜中用戶的密碼或者是黑客通過攻擊一些第三方站點(比如SNS)后,找到同樣的loginID來嘗試登錄。

正因為攻擊技術在發展,所以我們對漏洞的定義也在不斷變化。可能很多朋友都沒有注意到,一個業務安全設計得好的網站,往往loginID和nickname(昵稱)是分開的。登錄ID是用戶的私有信息,只有用戶本人能夠看到;而nickname不能用于登錄,但可以公開給所有人看。這種設計的細節,是網站積極防御的一種表現。

可能很多朋友仍然不愿意承認這些問題是漏洞,那么什么是漏洞呢?在我看來,漏洞只是對破壞性功能的一個統稱而已。

但是“漏洞”這頂帽子太大,大到我們難以承受,所以我們不妨換一個角度看,看看是否“應該修補”。語言真是很神奇的東西,很多時候換一個稱呼,就能讓人的認可度提高很多。

在PHP的5.3.4版本中,修補了很多年來萬惡的0字節截斷功能http://www.phpweblog.net/GaRY/archive/2010/12/10/PHP_is_geliavable_now.html,這個功能被文件包含漏洞利用,釀造了無數“血案”。

我們知道PHP中include/require一個文件的功能,如果有良好的代碼規范,則是安全的,不會成為漏洞。

這是一個正常的PHP語言的功能,只是“某一群不明真相的小白程序員”在一個錯誤的時間、錯誤的地點寫出了錯誤的代碼,使得“某一小撮狡猾的黑客”發現了這些錯誤的代碼,從而導致漏洞。這是操作系統的問題,誰叫操作系統在遍歷文件路徑時會被0字節截斷,誰叫C語言的string操作是以0字節為結束符,誰叫程序員寫出這么小白的代碼,官方文檔里已經提醒過了,關PHP什么事情,太冤枉了!

我也覺得PHP挺冤枉的,但C語言和操作系統也挺冤的,我們就是這么規定的,如之奈何?

但總得有人來為錯誤買單,誰買單呢?寫出不安全代碼的小白程序員?

No!學習過市場營銷方面知識的同學應該知道,永遠也別指望讓最終用戶來買單,就像老百姓不應該為政府的錯誤買單一樣(當然在某個神奇的國度除外)。所以必須得有人為這些不是漏洞,但造成了既成事實的錯誤負責,我們需要有社會責任感的owner。

很高興的是,PHP官方在經歷這么多年糾結、折磨、發瘋之后,終于勇敢地承擔起了這個責任(我相信這是一個很坎坷的心路歷程),為這場釀成無數慘案的鬧劇畫上了一個句號。但是我們仍然悲觀地看到,cgi.fix_pathinfo的問題http://www.80sec.com/nginx-securit.html仍然沒有修改默認配置,使用fastcgi的PHP應用默認處于風險中。PHP官方仍然堅持認為這是一個正常的功能,誰叫小白程序員不認真學習官方文件精神!是啊,無數網站付出慘痛學費的正常功能!

PHP是當下用戶最多的Web開發語言之一,但是因為種種歷史遺留原因(我認為是歷史原因),導致在安全的“增值”服務上做得遠遠不夠(相對于一些新興的流行語言來說)。在PHP流行起來的時候,當時的互聯網遠遠沒有現在復雜,也遠遠沒有現在這么多的安全問題,在當時的歷史背景下,很多問題都不是“漏洞”,只是功能。

我們可以預見到,在未來互聯網發展的過程中,也必然會有更多、更古怪的攻擊方式出現,也必然會讓更多的原本是“功能”的東西,變成漏洞。

最后,也許你已經看出來了,我并不是要說服誰is_a()是一個漏洞,而是在思考,誰該為這些損失買單?我們未來遇到同樣的問題怎么辦?

對于白帽子來說,我們習慣于分解問題,同一個問題,我們可以在不同層面解決,可以通過良好的代碼規范去保證(事實上,所有的安全問題都能這么修復,只是需要付出的成本過于巨大),但只有PHP在源頭修補了這個問題,才真正是善莫大焉。

BTW:is_a()函數的問題已經申報了CVE,如果不出意外,security@php.net也會接受這個問題,所以它已經是一個既成事實的漏洞了。

主站蜘蛛池模板: 靖宇县| 罗平县| 文山县| 石柱| 兴文县| 周至县| 交口县| 格尔木市| 镇江市| 吉隆县| 汉沽区| 丰都县| 彰化市| 藁城市| 图片| 和静县| 巴马| 广灵县| 武邑县| 桦甸市| 漠河县| 延吉市| 凤城市| 清丰县| 高青县| 四平市| 湟中县| 巫山县| 汤原县| 津南区| 德昌县| 临泉县| 榆林市| 安图县| 神农架林区| 博罗县| 吕梁市| 丹江口市| 平果县| 柳河县| 驻马店市|