很多 web 開發(fā)者沒有註意到 SQL 查詢是可以被竄改的,因而把 SQL 查詢當(dāng)作可信賴的指令。殊不知道,SQL 查詢可以繞過存取控制,從而繞過身份驗(yàn)證和權(quán)限檢查。更有甚者,有可能透過 SQL 查詢?nèi)?zhí)行主機(jī)作業(yè)系統(tǒng)層級的命令。
直接 SQL 指令注入就是攻擊者常用的一種創(chuàng)建或修改已有 SQL 語句的技術(shù),從而達(dá)到取得隱藏數(shù)據(jù),或覆蓋關(guān)鍵的值,甚至執(zhí)行資料庫主機(jī)作業(yè)系統(tǒng)命令的目的。這是透過應(yīng)用程式取得使用者輸入並與靜態(tài)參數(shù)組合成 SQL 查詢來實(shí)現(xiàn)的。下面將會給出一些真實(shí)的例子。
由於在缺乏對輸入的資料進(jìn)行驗(yàn)證,並且使用了超級用戶或其它有權(quán)創(chuàng)建新用戶的資料庫帳號來連接,攻擊者可以在資料庫中新建一個超級用戶。
Example #1 一段實(shí)現(xiàn)資料分頁顯示的程式碼…也可以被用來作為建立一個超級使用者(PostgreSQL系統(tǒng))。
<?php $offset = $argv[0]; // 注意,沒有輸入驗(yàn)證! $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; $result = pg_query($conn, $query); ?>
一般的使用者會點(diǎn)選?$offset?已被斌值的「上一頁」、「下一頁」的連結(jié)。原本程式碼只會認(rèn)為?$offset?是一個數(shù)值。然而,如果有人嘗試把以下語句先經(jīng)過?urlencode()?處理,然後再加入URL中的話:
0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select 'crack', usesysid, 't','t','crack' from pg_shadow where usename='postgres'; --
那麼他就可以創(chuàng)建一個超級用戶了。注意那個?0;?只不過是為了提供一個正確的偏移量以便補(bǔ)充完整原來的查詢,使它不要出錯而已。
Note:
--?是 SQL 的註解標(biāo)記,一般可以用來它告訴 SQL 解譯器忽略後面的語句。
對顯示搜尋結(jié)果的頁面下手是一個能得到密碼的可行辦法。攻擊者所要做的只不過是找出哪些提交上去的變數(shù)是用於 SQL 語句並且處理不當(dāng)?shù)?。而這類的變數(shù)通常都被用於SELECT?查詢中的條件語句,如?WHERE, ORDER BY, LIMIT?和?OFFSET。如果資料庫支援?UNION?建構(gòu)的話,攻擊者也可能會把一個完整的 SQL 查詢附加到原來的語句上以便從任何資料表中得到密碼。因此,對密碼欄位加密是很重要的。
Example #2 顯示文章…以及一些密碼(任何資料庫系統(tǒng))
<?php $query = "SELECT id, name, inserted, size FROM products WHERE size = '$size' ORDER BY $order LIMIT $limit, $offset;"; $result = odbc_exec($conn, $query); ?>
可以在原來的查詢的基礎(chǔ)上添加另一個?SELECT?查詢來獲得密碼:
' union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable; --
假如上述語句(使用假?'?和?--?和?--?被加入?$query?中的任一個變數(shù)的話,那就麻煩了。
SQL 中的 UPDATE 也會受到攻擊。這種查詢也可能像上面的例子一樣被插入或附加上另一個完整的請求。但是攻擊者更願意對?SET?子句下手,這樣他們就可以更改資料表中的一些資料。這種情況必須要知道資料庫的結(jié)構(gòu)才能修改查詢成功進(jìn)行。可以透過表單上的變數(shù)名稱對欄位進(jìn)行猜測,或是進(jìn)行暴力破解。對於存放使用者名稱和密碼的字段,命名的方法並不多。
Example #3 從重置密碼…到獲得更多權(quán)限(任何資料庫系統(tǒng))
<?php $query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';"; ?>
但是惡意的使用者會把?' or uid like'%admin%'; --?作為變數(shù)的值提交給?$uid?來改變admin 的密碼,或把?$pwd?的值提交為?"hehehe', admin='yes', trusted=100 "(後面有個空格)去獲得更多的權(quán)限。這樣做的話,查詢語句其實(shí)變成了:
<?php // $uid == ' or uid like'%admin%'; -- $query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --"; // $pwd == "hehehe', admin='yes', trusted=100 " $query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE ...;"; ?>
下面這個可怕的例子將會示範(fàn)如何在某些資料庫上執(zhí)行系統(tǒng)指令。
Example #4 攻擊資料庫所在主機(jī)的作業(yè)系統(tǒng)(MSSQL Server)
<?php $query = "SELECT * FROM products WHERE id LIKE '%$prod%'"; $result = mssql_query($query); ?>
如果攻擊提交?a%' exec master..xp_cmdshell 'net user test testpass /ADD' --?作為變數(shù)$prod的值,那麼?query將會變成
<?php $query = "SELECT * FROM products WHERE id LIKE '%a%' exec master..xp_cmdshell 'net user test testpass /ADD'--"; $result = mssql_query($query); ?>
MSSQL 伺服器會執(zhí)行這條SQL 語句,包括它後面那個用來新增使用者給系統(tǒng)的指令。如果這個程式是以?sa?運(yùn)作而 MSSQLSERVER 服務(wù)又有足夠的權(quán)限的話,攻擊者就可以獲得一個系統(tǒng)帳號來存取主機(jī)了。
Note:
雖然以上的例子是針對某一特定的資料庫系統(tǒng)的,但是這並不代表不能對其它資料庫系統(tǒng)實(shí)施類似的攻擊。使用不同的方法,各種資料庫都有可能遭殃。
預(yù)防措施
也許有人會自我安慰,說攻擊者要知道資料庫結(jié)構(gòu)的資訊才能實(shí)施上面的攻擊。沒錯,確實(shí)如此。但沒人能保證攻擊者一定得不到這些訊息,一但他們得到了,資料庫有外洩的危險。如果你在用開放原始碼的軟體包來存取資料庫,例如論壇程序,攻擊者就很容地得到相關(guān)的程式碼。如果這些程式碼設(shè)計(jì)不良的話,風(fēng)險就更大了。
這些攻擊總是建立在發(fā)掘安全意識不強(qiáng)的代碼上的。所以,永遠(yuǎn)不要信任外界輸入的數(shù)據(jù),特別是來自于客戶端的,包括選擇框、表單隱藏域和 cookie。就如上面的第一個例子那樣,就算是正常的查詢也有可能造成災(zāi)難。
永遠(yuǎn)不要使用超級用戶或所有者帳號去連接數(shù)據(jù)庫。要用權(quán)限被嚴(yán)格限制的帳號。
檢查輸入的數(shù)據(jù)是否具有所期望的數(shù)據(jù)格式。PHP 有很多可以用于檢查輸入的函數(shù),從簡單的變量函數(shù)和字符類型函數(shù)(比如 is_numeric(), ctype_digit())到復(fù)雜的Perl 兼容正則表達(dá)式函數(shù)都可以完成這個工作。
如果程序等待輸入一個數(shù)字,可以考慮使用 is_numeric() 來檢查,或者直接使用 settype() 來轉(zhuǎn)換它的類型,也可以用 sprintf() 把它格式化為數(shù)字。
Example #5 一個實(shí)現(xiàn)分頁更安全的方法
<?php settype($offset, 'integer'); $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; // 請注意格式字符串中的 %d,如果用 %s 就毫無意義了 $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;", $offset); ?>
使用數(shù)據(jù)庫特定的敏感字符轉(zhuǎn)義函數(shù)(比如?mysql_escape_string()?和?sql_escape_string())把用戶提交上來的非數(shù)字?jǐn)?shù)據(jù)進(jìn)行轉(zhuǎn)義。如果數(shù)據(jù)庫沒有專門的敏感字符轉(zhuǎn)義功能的話?addslashes()?和?str_replace()?可以代替完成這個工作。看看第一個例子,此例顯示僅在查詢的靜態(tài)部分加上引號是不夠的,查詢很容易被攻破。
要不擇手段避免顯示出任何有關(guān)數(shù)據(jù)庫的信心,尤其是數(shù)據(jù)庫結(jié)構(gòu)。
也可以選擇使用數(shù)據(jù)庫的存儲過程和預(yù)定義指針等特性來抽象數(shù)庫訪問,使用戶不能直接訪問數(shù)據(jù)表和視圖。但這個辦法又有別的影響。
除此之外,在允許的情況下,使用代碼或數(shù)據(jù)庫系統(tǒng)保存查詢?nèi)罩疽彩且粋€好辦法。顯然,日志并不能防止任何攻擊,但利用它可以跟蹤到哪個程序曾經(jīng)被嘗試攻擊過。日志本身沒用,要查閱其中包含的信息才行。畢竟,更多的信息總比沒有要好。

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP設(shè)置的關(guān)鍵在於明確安裝方式、配置php.ini、連接Web服務(wù)器及啟用必要擴(kuò)展。 1.安裝PHP:Linux用apt、Mac用Homebrew、Windows推薦XAMPP;2.配置php.ini:調(diào)整錯誤報告、上傳限制等並重啟服務(wù)器;3.搭配Web服務(wù)器:Apache通過mod_php,Nginx使用PHP-FPM;4.安裝常用擴(kuò)展:如mysqli、json、mbstring等以支持完整功能。

PHP註釋代碼常用方法有三種:1.單行註釋用//或#屏蔽一行代碼,推薦使用//;2.多行註釋用/.../包裹代碼塊,不可嵌套但可跨行;3.組合技巧註釋如用/if(){}/控制邏輯塊,或配合編輯器快捷鍵提升效率,使用時需注意閉合符號和避免嵌套。

寫好PHP註釋的關(guān)鍵在於明確目的與規(guī)範(fàn),註釋應(yīng)解釋“為什麼”而非“做了什麼”,避免冗餘或過於簡單。 1.使用統(tǒng)一格式,如docblock(/*/)用於類、方法說明,提升可讀性與工具兼容性;2.強(qiáng)調(diào)邏輯背後的原因,如說明為何需手動輸出JS跳轉(zhuǎn);3.在復(fù)雜代碼前添加總覽性說明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標(biāo)記待辦事項(xiàng)與問題,便於後續(xù)追蹤與協(xié)作。好的註釋能降低溝通成本,提升代碼維護(hù)效率。

寫好註釋的關(guān)鍵在於說明“為什麼”而非僅“做了什麼”,提升代碼可讀性。 1.註釋應(yīng)解釋邏輯原因,例如值選擇或處理方式背後的考量;2.對複雜邏輯使用段落式註釋,概括函數(shù)或算法的整體思路;3.定期維護(hù)註釋確保與代碼一致,避免誤導(dǎo),必要時刪除過時內(nèi)容;4.在審查代碼時同步檢查註釋,並通過文檔記錄公共邏輯以減少代碼註釋負(fù)擔(dān)。

註釋不能馬虎是因?yàn)樗忉尨a存在的原因而非功能,例如兼容老接口或第三方限制,否則看代碼的人只能靠猜。必須加註釋的地方包括複雜的條件判斷、特殊的錯誤處理邏輯、臨時繞過的限制。寫註釋更實(shí)用的方法是根據(jù)場景選擇單行註釋或塊註釋,函數(shù)、類、文件開頭用文檔塊註釋說明參數(shù)與返回值,並保持註釋更新,對複雜邏輯可在前面加一行概括整體意圖,同時不要用註釋封存代碼而應(yīng)使用版本控制工具。

ToinstallPHPquickly,useXAMPPonWindowsorHomebrewonmacOS.1.OnWindows,downloadandinstallXAMPP,selectcomponents,startApache,andplacefilesinhtdocs.2.Alternatively,manuallyinstallPHPfromphp.netandsetupaserverlikeApache.3.OnmacOS,installHomebrew,thenrun'bre

易於效率,啟動啟動tingupalocalserverenverenvirestoolslikexamppandacodeeditorlikevscode.1)installxamppforapache,mysql,andphp.2)uscodeeditorforsyntaxssupport.3)

PHPblockcommentsareusefulforwritingmulti-lineexplanations,temporarilydisablingcode,andgeneratingdocumentation.Theyshouldnotbenestedorleftunclosed.BlockcommentshelpindocumentingfunctionswithPHPDoc,whichtoolslikePhpStormuseforauto-completionanderrorche
