在 Windows Security Push at Microsoft(Microsoft Windows? 安全推動(dòng)活動(dòng))中,我們?yōu)?C 程序員創(chuàng)建了一個(gè)安全字符串處理函數(shù)列表。您可以在 Strsafe.h: SaferString Handling in C(英文)中找到它們。
3. 防止跨站點(diǎn)腳本
跨站點(diǎn)腳本攻擊是 Web 特有的問(wèn)題,它能通過(guò)單個(gè) Web 頁(yè)中的一點(diǎn)隱患危害客戶端的數(shù)據(jù)。想像一下,下面的 asp.net 代碼片段會(huì)造成什么后果:
HTML 或腳本不可能蒙混過(guò)此正則表達(dá)式!不要使用正則表達(dá)式尋找無(wú)效字符并在發(fā)現(xiàn)這種無(wú)效字符后拒絕請(qǐng)求,因?yàn)檩p易出現(xiàn)漏掉的情況。第二種防范措施是對(duì)所有作為輸出的輸入進(jìn)行 HTML 編碼。這會(huì)減少危險(xiǎn)的 HTML 標(biāo)記,使之變成更安全的轉(zhuǎn)義符。您可以在 ASP.NET 中使用 HttpServerUtility.HtmlEncode,或者在 ASP 中使用Server.HTMLEncode 轉(zhuǎn)義任何可能出現(xiàn)問(wèn)題的字符串。
4. 不要請(qǐng)求 sa 權(quán)限
我們要討論的最后一種輸入信任攻擊是 SQL 插入代碼。許多開(kāi)發(fā)人員編寫(xiě)這樣的代碼,即獲取輸入并使用該輸入來(lái)建立 SQL 查詢,進(jìn)而與后臺(tái)數(shù)據(jù)存儲(chǔ)(如 Microsoft SQL Server 或 Oracle)進(jìn)行通信。
請(qǐng)看以下代碼片段:
void DoQuery(string Id) { SqlConnection sql=new SqlConnection(@"data source=localhost;" + "user id=sa;password=password;"); sql.Open(); sqlstring= "SELECT hasshipped" + " FROM shipping WHERE id='" + Id + "'"; SqlCommand cmd = new SqlCommand(sqlstring,sql); ... }
這段代碼有三個(gè)嚴(yán)重缺陷。首先,它是以系統(tǒng)治理員帳戶 sa 建立從 Web 服務(wù)到SQL Server的連接的。不久您就會(huì)看到這樣做的缺陷所在。第二點(diǎn),注重使用“password”作為 sa帳戶密碼的聰明做法!但真正值得關(guān)注的是構(gòu)造 SQL 語(yǔ)句的字符串連接。假如用戶為 ID 輸入 1001,您會(huì)得到如下 SQL 語(yǔ)句,它是完全有效的。
SELECT hasshipped FROM shipping WHERE id = '1001'
但攻擊者比這要有創(chuàng)意得多。他們會(huì)為 ID 輸入一個(gè)“'1001' DROP table shipping --”,它將執(zhí)行如下查詢:
SELECT hasshipped FROM shipping WHERE id = '1001' DROP table shipping -- ';
這時(shí)您也許會(huì)覺(jué)得希奇,怎么任何一個(gè)用戶都能刪除 SQL Server 數(shù)據(jù)庫(kù)中的表呢。當(dāng)然,您是對(duì)的,只有治理員才能做這樣的工作。但這里您是作為 sa 連接到數(shù)據(jù)庫(kù)的,而 sa 能在 SQL Server 數(shù)據(jù)庫(kù)上做他想做的任何事。永遠(yuǎn)不要在任何應(yīng)用程序中以 sa連接 SQL Server;正確的做法是,假如合適,使用 Windows 集成的身份驗(yàn)證,或者以一個(gè)預(yù)先定義的具有適當(dāng)權(quán)限的帳戶連接。