在PHP中全面禁止SQL注進式攻擊之一
一、 注進式攻擊的類型
可能存在許多不同類型的攻擊動機,但是乍看上往,似乎存在更多的類型。這是非常真實的-假如惡意用戶發明了一個能夠履行多個查詢的措施的話。本文後面,我們會對此作具體討論。
假如你的腳本正在履行一個SELECT指令,那麼,攻擊者可以逼迫顯示一個表格中的每一行記錄-通過把一個例如'1=1'這樣的條件注進到WHERE子句中,如下所示(其中,注進部分以粗體顯示):
SELECT * FROM wines WHERE variety = 'lagrein' OR 1=1;'
『正如我們在前面所討論的,這本身可能很有用的信息,由於它揭示了該表格的一般結構(這是一條普通的記錄所不能實現的),以及埋伏地顯示包含機密信息的記錄。
一條更新指令埋伏地具有更直接的要挾。透過把其它屬性放到SET子句中,一名攻擊者可以修正目前被更新的記錄中的任何字段,例如下面的例子(其中,注進部分以粗體顯示):
UPDATE wines SET type= 'red','vintage'='9999' WHERE variety = 'lagrein'
藉由把一個例如1=1這樣的恆真條件加到一條更新指令的WHERE子句中,這種修正範疇可以擴大到每一筆記錄,例如下面的例子(其中,注進部分以粗體顯示):
UPDATE wines SET type='red','vintage'='9999 WHERE variety = 'lagrein' OR 1=1 ;'
最危險的指令可能是DELETE-這是不難想像的。其註進技巧與我們已經看到的雷同-透過修正WHERE子句來擴大受影響的記錄的範疇,例如下面的例子(其中,注進部分以粗體顯示):
DELETE FROM wines WHERE variety = 'lagrein' OR 1=1;'
二、 多個查詢注進
多個查詢注進將加劇一個攻擊者可能引起的埋伏的損壞-通過答埋多條指令包含在一個查詢中。在應用MySQL資料庫時,攻擊者透過把一個出乎意料之外的終止符插進到查詢中即可很輕易實現這一點-此時一個注進的引號(單引號或雙引號)標記期看變量的結尾;然後應用一個分號終止指令。現在,一個另外的攻擊指令可能被加入到現在終止的原始指令的結尾。終極的損壞性查詢可能看起來如下所示:
SELECT * FROM wines WHERE variety = 'lagrein';
GRANT ALL ON *.* TO 'BadGuy@%' IDENTIFIED BY 'gotcha';'
這個注進將創立一個新的用戶BadGuy並賦予其網路特權(在所有的表格上具有所有的特權);其中,還有一個'不祥'的口令被參加到這個簡略的SELECT語句中。假如你遵守我們在先前文章中的建議-嚴格限制該過程使用者的特權,那麼,這應該無法運作,由於web伺服器守護程式不再擁有你撤回的GRANT特權。但是從理論上講,這樣的一個攻擊可能給予BadGuy自由權利來實現他對你的資料庫的任何把持。
至於這樣的一個多查詢是否會被MySQL伺服器處理,結論並不唯一。這其中的一些原因可能是由於不同版本的MySQL所致,但大多數情況卻是由於多查詢存在的方法所致。 MySQL的監督程序完整答應這樣的一個查詢。常用的MySQL GUI-phpMyAdmin,在終極查詢之前會複製出以前所有的內容,並且只這樣做。
但是,大多數的在一個注進高低文中的多查詢都是由PHP的mysql擴大負責治理的。幸好,預設情況下,它是不答應在一個查詢中履行多個指令的;試圖履行兩個指令(例如上面所示的注進)將會簡略地導致失敗-不設定任何錯誤,並且沒有天生任何輸出訊息。在這種情況下,儘管PHP也只是'規行矩步'地實現其缺省行動,但是確實能夠保護你免於大多數簡略的注進式攻擊。
PHP5中的新的mysqli擴大(參考http://php.net/mysqli),就像mysql一樣,內在地也不支撐多個查詢,不過卻供給了一個mysqli_multi_query()函數以支撐你實現多查詢-假如你確實想這樣做的話。
然而,對於SQLite-與PHP5綁定到一起的可嵌進的SQL資料庫引擎(參考http://sqlite.org/和http://php.net/sqlite)情況更為可怕,由於其易於應用而吸引了大批用戶的注意。在某些情況下,SQLite缺省地答應這樣的多指令查詢,由於這個資料庫可以最佳化批次查詢,特別是非常有效的批INSERT語句處理。然而,如果查詢的成果為你的腳本所應用的話(例如在應用一個SELECT語句檢索記錄的情況下),sqlite_query()函數卻不會答應履行多個查詢。
三、 INVISION Power BOARD SQL注進脆弱性
Invision Power Board是個著名的論壇系統。 2005年五月6號,在登入碼中發明了一處SQL注進脆弱性。其發明者為GulfTech Security Research的James Bercegay。
這個登入查詢如下所示:
$DB->query('SELECT * FROM ibf_members WHERE id=$mid AND password='$pid'');
其中,成員ID變數$mid和口令變數pid被應用下面兩行程式碼從my_cookie()函式擷取:
$mid = intval($std->my_getcookie('member_id'));
$pid = $std->my_getcookie('pass_hash');
在此,my_cookie()函數應用下列語句從cookie中檢索請求的變數:
return urldecode($_COOKIE[$ibforums->vars['cookie_id'].$name]);傳回的值基本上沒有被處理。雖然$mid在應用於查詢之前被強迫轉換成一個整數,但$pid卻保持不變。因此,它很輕易地遭遇我們前面所討論的注進類型的攻擊。
因此,透過以下列方法修正my_cookie()函數,這種脆弱性就會***露出來:
if ( ! in_array( $name,array('topicsread', 'forum_read','collapseprefs') ) )
{
return $this->
clean_value(urldecode($_COOKIE[$ibforums->vars['cookie_id'].$name]));
}
else
{
return codefor ->vars['cookie_id'].$name]);
}
經過這樣的改正之後,其中的要害變數在'通過'全局clean_value()函數後被返回,而其它變數卻未進行檢查。
現在,既然我們大致懂得了什麼是SQL注進,它的注進原理以及這種注進的脆弱程度,那麼接下來,讓我們探討如何有效地預防它。幸好,PHP為我們供給了豐富的資源,因此我們有充分的信心預言,一個經仔細地徹底地應用我們所推薦的技巧構建的利用程序將會從你的腳本中基本上打消任何可能性的SQL注進-透過在它可能造成任何損壞之前'清算'你的用戶的資料來實現。
四、 界定你的查詢中的每一個值
我們推薦,你確保界定了你的查詢中的每一個值。字串值首當其衝,以及那些你通常期看應當應用'單'(而不是'雙')引號的內容。一方面,假如你應用雙引號來答應PHP在字串內的變數調換,這樣可以使得輸進查詢更為輕易些;另一方面,這(無可否定,只是極少量地)也會減少以後PHP代碼的分析工作。
下面,讓我們應用我們一開端應用的那個非注進式查詢來闡明這個標題:
SELECT * FROM wines WHERE variety = 'lagrein'
或以PHP語句表達為:
〜) * FROM wines WHERE variety = '$variety'';
從技巧上講,引號對於數字值來說是不需要應用的。但是,假如你並不介意用引號把例如葡萄酒這樣的一個域相應的一個值括起來並且假如你的用戶把一個空值輸進到你的表單中的話,那麼,你會看到一個類似下面的查詢:
SELECT * FROM wines WHERE vintage =
當然,這個查詢從語法上講是無效的;但是,下面的語法卻是有效的:
SELECT * FROM wines WHERE vintage = ''
㟎〜第二個第二個查詢。將(大概)不會回傳任何果,但是至少它不會回傳一個錯誤訊息。
從前面的討論中我們看到,迄今為止,SQL注進的重要起源往往出在一個意料之外的表單進口上。然而,當你經過一個表單向用戶供給機會提交某些值時,你應該有相當的上風來斷定你想取得什麼樣的輸進內容-這可以使得我們比擬輕易地檢查用戶進口的有效性。在先前的文章中,我們已經討論過這樣的校驗標題;所以,在此,我們僅簡略地總結當時我們討論的要點。假如你正在期看一個數字,那麼你可以應用下面這些技巧之一來確保你得到的真正是一個數字類型:
· 應用is_int()函數(或is_integer()或is_long())。
· 套用gettype()函數。
· 應用intval()函數。
· 套用settype()函數。
為了檢查使用者輸進內容的長度,你可以套用strlen()函數。為了檢查一個期看的時間或日期是否有效,你可以套用strtotime()函數。它幾乎必定能夠確保一位使用者的進口中沒有包含分號字元(除非標點符號可以被正當地包含在內)。你可以藉助strpos()函數輕易地實現這一點,如下所示:
if( strpos( $variety, ';' ) ) exit ( '$variety is an invalid value for variety!' );
如正如我們在前面所提到的,只要你仔細分析你的用戶輸進期看,那麼,你應該能夠很輕易地檢查出其中存在的許多標題。
六、 從你的查詢中濾往每一個可疑字符
儘管在以前的文章中,我們已經討論過如何過濾掉危險字符的標題;但是在此,還是讓我們再次簡略地誇張並回納一下這個標題:
· 不要應用magic_quotes_gpc指令或它的'幕後搭擋'-addslashes()函數,此函數在利用程式開發中是被限制應用的,並且此函數還請求應用額外的步驟-應用stripslashes ()函數。
· 相較之下,mysql_real_escape_string()函數較為常用,但是也有它自己的毛病。

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

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

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。