- 1、php配置文件是什麼?
- 2、php的類怎麼讀取到配置文件裏面的配置項?
- 3、在php.ini中如何配置安全的PHP環境參數
- 4、如何配置php服務器
- 5、php有什麼安全規則,有哪些?
PHP 的配置文件一般是 php.ini 文件
php.ini 文件必須命名為’php.ini’並放置在httpd.conf中的PHPIniDir指令指定的目錄中,使用phpinfo()函數可以查看。如果未作修改,windows平台下一般放在php安裝目錄中。
PHP還是一個不斷發展的工具,其功能還在不斷地刪減
而php.ini的設置更改可以反映出相當的變化,
在使用新的PHP版本前,研究一下php.ini會有好處的
下面簡單的介紹一下基本配置:
directive = value
; 指示標識符 是 *大小寫敏感的* – foo=bar 不同於 FOO = bar。
engine = On
; 使 PHP scripting language engine(PHP 腳本語言引擎)在 Apache下有效。
short_open_tag = On
; 允許 tags 將被識別。
asp_tags = Off
; 允許ASP-style tags
precision = 14
; 浮點類型數顯示時的有效位數
上面只是一個例子,其他詳細的配置說明,可以參考一些資料。
1、新建一個PHP文檔,該文檔的目的是檢測PHP的環境配置,示例:?php phpinfo()。
2、保存以上內容,在瀏覽器查看輸出信息。
3、以上信息便是PHP的配置信息了,在該頁面查找:Loaded Configuration File,紅色方框中便是php.ini的具體路徑了。
4、打開CMD窗口,並輸入:php -i | findstr php.ini。
5、按下回車鍵執行後,同樣可以得到php.ini配置文件的路徑。
(1)
打開php的安全模式
php的安全模式是個非常重要的內嵌的安全機制,能夠控制一些php中的函數,比如system(),
同時把很多文件操作函數進行了權限控制,也不允許對某些關鍵文件的文件,比如/etc/passwd,
但是默認的php.ini是沒有打開安全模式的,我們把它打開:
safe_mode
=
on
(2)
用戶組安全
當safe_mode打開時,safe_mode_gid被關閉,那麼php腳本能夠對文件進行訪問,而且相同
組的用戶也能夠對文件進行訪問。
建議設置為:
safe_mode_gid
=
off
如果不進行設置,可能我們無法對我們服務器網站目錄下的文件進行操作了,比如我們需要
對文件進行操作的時候。
1. 安裝IIS
IIS是windows平台下比較成熟的web服務,安裝方法也非常簡單。
打開「開始」菜單,點擊「管理您的服務器」,點擊「添加或刪除角色」(如圖所示)。
2
進入預備步驟後直接點下一步。到達了選擇角色的地方,選擇「應用程序服務(IIS,ASP.net)」
3
之後點擊下一步,出現附加組件的選擇,一個是FrontPage Server Extentions,另外一個是ASP.net,這兩項我們的環境中都不需要,不必選擇,如果有需要,可以選擇性安裝。進入下一步,是選項總結,再下一步,進入安裝過程,此時提示需要插入windows 2003(R2)的安裝光盤,插入光盤後,選擇光驅所在驅動器下的I386,點擊確定,安裝過程將會繼續一直到結束,並且出現成功提示
4
完成後對IIS進行測試,打開「開始」菜單,點擊「所有程序」,進入「管理工具」,點擊「internet信息服務(IIS)管理器」
展開「網站」樹型節點,刪除默認網站,然後新建一個網站
5
進入嚮導後,進入下一步,為網站添加描述,也就是IIS中顯示的網站標示,可以隨便填寫,再進入下一步,為網站配置主機頭,我們是用來配置本地測試環境,所以把主機頭配置為127.0.0.1
6
進入下一步,選擇目錄,目錄需要提前建立好,然後選擇即可。繼續下一步,需要選擇網站權限,這裡只選擇讀取即可。之後便可完成網站新建嚮導了。
需要正常的瀏覽網站,還需要給網站的根目錄文件夾指定相應的權限,首先在網站屬性中查看網站的匿名訪問賬戶是什麼,然後將這個賬戶設置到網站的根目錄文件夾,並設置相應的訪問權限
7
網站的匿名訪問賬戶是:IUSR_CBLH-DDEF00B671,為文件夾設置用戶訪問權限
8
權限配置好後,在目錄中新建一個index.html文件,隨意輸入一些文字或者html代碼即可。
在網站名稱上右鍵,點擊屬性,進入「屬性」後點擊「文檔」選項卡,在此添加一個index.html和index.php(index.php添加好是為了待會不必再做配置),然後點擊「確定」或者「應用」保存配置。
然後在瀏覽器中的地址欄中輸入「」或者「」,即可看到剛才我們建立的index.html中的內容。
9
安裝fastcgi
IIS調試好後,就可以安裝fastcgi了,首先需要下載IISfastcgi,下載地址是(),安裝fastcgi非常簡單,只需要同意協議後連續點擊下一步即可,沒有任何選項。
10
安裝php
首先下載php在windows的安裝包,下載地址,這裡選用php-5.3.4-nts-Win32-VC9-x86.msi做例子。下載好php-5.3.4-nts-Win32-VC9-x86.msi後,雙擊文件安裝,接受使用協議後,為php填寫安裝目錄,這個目錄是可以更換的,指向需要放置它的位置即可。之後需要選擇web服務器的安裝,這裡選擇我們先前安裝的IIS fastcgi
11
下一步需要配置安裝選項,這裡我們除了默認的選項之外增加了pear install(如圖所示)
12
再進入下一步,就可以確認安裝了。
完成安裝後,還需要測試一下php是否可用。
首先打開IIS管理器,然後在先前測試IIS的網站上右鍵,進入「屬性」,點擊主目錄選項卡,然後將「執行權限」配置為「純腳本」
13
然後點擊旁邊的「配置」,查看是否有.php擴展名,如果沒有的話,需要添加一個新項,將可執行文件指向「C:WINDOWSsystem32inetsrvfcgiext.dll」,擴展名為「.php」(注意有個點),動作限制為「GET,HEAD,POST,TRACE」,點擊確定即可
步驟閱讀
14
做好了這些,就可以寫個小腳本來測試了,在網站的目錄中新建一個test.php文件,打開後輸入,保存後退出。在瀏覽器地址欄中輸入,即可看到php信息了。
4. 安裝isapi_urlwriter ISAPI擴展組件
isapi_urlwriter ISAPI擴展組件主要用來做地址重寫,重寫後的虛擬靜態地址對搜索引擎更友好。先將ISAPI_Rewrite3安裝包解壓到指定的文件目錄中,然後進入網站屬性窗口,選擇窗口中的ISAPI篩選器選項卡,點擊添加按鈕,在彈出的窗口中選擇ISAPI_Rewrite3解壓目錄中的ISAPI_Rewrite.dll文件為可執行文件並確定。
END
iis7.5 PHP環境配置
1
windows server 2008是基於NT6 平台的新型操作系統,其對硬件性能的發揮比起其它NT平台來說有了質的飛躍,已經開始普及到了廣大用戶中,而且操作較2003來說更為直觀和簡單,受到越來越多的好評。在這裡我們要介紹windows server 2008中的php環境搭建。
安裝IIS
windows server 2008的IIS版本為7.0,包括fastcgi,安裝十分方便。
打開「開始」菜單→「服務器管理」,出現服務器管理界面
2
在圖中黃色框中填入服務器ip,點擊打開,之後提示輸入用戶名和密碼,驗證成功後完成登錄服務器。
3
點擊「下一步」之後,需要選擇功能,這裡需要比默認選項多增加一個「cgi」
4
點擊「下一步」,將會需要確認一下安裝的內容,此時點擊安裝,即可將IIS安裝在操作系統中。
安裝好IIS之後,需要進行一個測試,在瀏覽器地址欄中輸入「」,如果出現IIS7的歡迎頁則說明正常。接下來需要配置一個新網站,首先打開IIS管理器(「開始」→「所有程序」→「管理工具」→「internet 信息服務(IIS)管理器」)。
然後刪除默認網站,在主菜單中,展開網站菜單,然後再網站名稱上右鍵,點擊刪除即可
5
再新建一個網站,在「網站」上右擊,點擊添加網站,會出現信息網站添加的表單,首先輸入網站名稱,例如「stourwebcms」,路徑選擇為網站存放的路徑,單IP的服務器可以不必選擇IP,主機頭填寫為localhost,然後點擊確定。
6
添加好網站後,需要為網站設置用戶訪問權限。在iis管理器左邊的網站列表中選中網站,在右邊的操作列表中點擊「基本設置」,在彈出窗口中點擊「連接為」,彈出的窗口中會出現網站的默認用戶賬戶,也可以更改為其它的用戶。確定網站的用戶賬戶後,將此賬戶的訪問權限設置到網站的根目錄文件夾上
打開網站目錄,新建一個index.html,然後用記事本打開,輸入「hello stourweb」後保存,並訪問本地地址「」進行測試,網頁上顯示出了「hello stourweb」,說明配置成功。
7
安裝php
在前面已經提過,IIS7中不必單獨安裝fastcgi,所以,我們只需要下載php安裝包進行安裝即可,下載地址: 下載好後,打開安裝程序,經過引導,配置好路徑,來到選擇「web server setup」的地方,在這裡我們選擇「IIS fastcgi」
8
然後點擊「next」按鈕,到了選擇安裝選項的步驟,一般安裝默認的就可以了,如果要添加的話需要點擊一下前面的磁盤小圖標,然後選擇安裝,第一項是只安裝選中的項目,第二項是安裝所有該項目的子項目。配置好後進入下一步
9
配置好後,點擊「next」然後點擊「install」即可安裝php。
當php安裝完成後會自動在iis的處理程序映射中增加一條fastcgi到php的映射關係
安裝完成後,我們還是需要測試一下,打開剛才新建的網站目錄,新建一個test.php文件,用記事本打開,輸入
?php
echo phpinfo();
?
保存退出,再從瀏覽器中訪問
顯示出php信息,說明php環境安裝成功。
10
安裝isapi_urlwriter ISAPI擴展組件
isapi_urlwriter ISAPI擴展組件主要用來做地址重寫,重寫後的虛擬靜態地址對搜索引擎更友好。先將ISAPI_Rewrite3安裝包解壓到指定的文件目錄中,然後雙擊iis的ISAPI篩選器配置項,進入網站ISAPI組件配置窗口,點擊添加按鈕,在彈出的窗口中選擇ISAPI_Rewrite3解壓目錄中的ISAPI_Rewrite.dll文件為可執行文件並確定。
11
ISAPI_Rewrite3組件是一個32位的程序,因此在64位操作系統應用池進程下默認不工作,因此需要在網站所屬應用進程池的高級設置中將進程池設置為32位兼容
END
Mysql數據庫安裝
1
下載mysql(),安裝過程比較簡單,首先配置路徑,然後選擇安裝選項,一般採用默認安裝的方式,之後會進入一個配置嚮導界面
步驟閱讀
2
連續下一步,需要選擇配置方式,這裡選擇配置方式,我們需要手動配置,所以選擇detailed configuration,然後點擊「下一步」
3
這裡需要選擇服務器類型,如果是開發用的測試環境,選擇developer Machine ,如果是服務器用,則選擇Server Machine,當然單一用途的服務器還可以選擇dedicated mysql server machine。選擇好後進入下一步
4
接下來是選擇服務器使用,第一個是多功能數據庫,可以使用 InnoDB engine和MyISAM engine。第二個選項,它的性能偏向於InnoDB,但是同時支持MyISAM engine。第三個選項是偏向於分析功能的MyISAM。至於這三個選項有什麼區別,其實只要知道,MyISAM類型的數據庫引擎可以為php提供強大的檢索和分析功能。InnoDB的性能則偏重於存儲。
所以如果只做web服務器的話選擇第三項即可,如果是有其它用途,建議選擇第一項。
5
下一步需要選擇服務器上的連接數量,這裡如果是測試用的小服務器可以選擇最少的第一項,如果是流量巨大的網站,需要選擇第二項,或者第三項自行填寫。
之後是網絡連接的選項,「enable TCP/IP Networking」可以按照需求來選擇,如果不做集群的話可以把勾去掉,如果是在內網環境,不為mysql做路由規則是完全可以打開此項的。可以直接添加一個防火牆例外給3306端口。端口號可以選擇,但是推薦默認的3306。還有一項是是否開啟嚴謹模式,此項推薦勾選
6
點擊下一步,選擇默認字符集,這裡選擇自定義的utf8字符集
7
進入下一步,需要設定windows選項,這裡推薦安裝windows服務,並且自動啟動。第二個選項,如果有必要,可以選擇添加一個環境變量,可以方便命令行指向。
配置好後,進入下一步,需要為root用戶設定密碼,請設置一個比較複雜的密碼以增加安全性,另外請牢記自己設置的密碼,否則遺忘了後需要重置密碼十分麻煩。還有一個是否允許root用戶從遠程登錄的選項,此處最好不勾選,否則安全性將會降低。
到此配置就全部結束了,點擊下一步,會出現安裝總結,點擊「execute」執行安裝即可。
安裝成功後,我們依然需要對此進行測試。
在網站中新建一個測試php文件test.php,我們使用pdo鏈接mysql作為測試。
輸入
?php
$db=new PDO(“mysql:host=localhost;dbname=test”,”root”,”剛才設置的密碼”);
if ($db)
{
echo “ok”;
}
?
訪問,如果屏幕上打印出了ok,表示mysql安裝成功。
END
安全配置建議
1
安全軟件
一款好的安全軟件能有效防禦來自計算機病毒、惡意軟件和木馬的威脅,但能用於服務器的安全軟件並不多,其中大部分都是收費的,平常個人所用的金山毒霸和360等不能安裝到windows server系列的服務器操作系統上,但他們都有相應的服務器版本並且提供免費升級,在他們的官網上面都能夠找到。
2
防火牆
合理的配置好防火牆能有效的阻止各種惡意入侵,因為各種網絡入侵都是通過相應的網絡端口完成的。網絡端口是服務器上的各種網絡服務開啟的,他們對外提供各種網絡服務,如http、ftp、smtp等。自己的服務器上需要提供哪些網絡服務就只開啟這些服務的相應端口,如服務器上提供網站服務,就需要開啟http的80端口,如需要提供ftp服務就要開啟21端口;有些網絡服務不需要對外提供服務就不應該開啟,如sql server數據庫不需要對外提供服務,就應該在防火牆中關閉掉1433端口。
Windows sever 2003和2008都自帶防火牆,其實能簡單有效的利用這些自帶的防火牆就能有效的完成端口的開閉管理。
l Windows server 2003服務器防火牆配置
1) 鼠標右鍵單擊「網上鄰居」,選擇「屬性」。
2) 然後鼠標右鍵單擊「本地連接」,選擇「屬性」。如圖選擇「高級」選項,選中「Internet連接防火牆」,確定後防火牆即起了作用。
點擊「設置(G)…」按鈕可進行高級設置。其中列出了可用的網絡服務,選中後允許其打開網絡端口並通信,反之則關閉其網絡通信;單擊「添加」則可以增加網絡服務或打開指定的網絡端口
3
Windows server 2008服務器防火牆配置
1) 在控制面板中打開網絡和共享中心
2) 點擊「windows防火牆」彈出防火牆配置窗口,在此窗口中要確認防火牆服務已經開啟
3) 單擊「允許程序或功能通過Windows防火牆」彈出網絡服務端口配置窗口,在此窗口中可以選擇允許打開端口並通信的網絡服務,單擊「允許運行另一程序」來自定義開啟某一網絡服務或端口
4
用戶管理
系統中用戶的數量能越少越好,並且每個用戶都被用於特定的功能,如可以新建一個專門用於對網站進行匿名授權的賬戶(如條件允許,可以為每個網站新建一個獨立的賬戶進行分別授權,這些能夠隔離開各網站的授權,提高各網站的安全性,不至於一個網站被入侵後能夠有權限訪問到其它網站的文件目錄)。另外最重要的一點是要為每個賬戶設置一個獨立且複雜的密碼,防止賬戶密碼被猜解和窮舉。
5
文件系統權限管理
l C盤只給administrators 和system權限,其他的權限不給,其他的盤也可以這樣設置,這裡給的system權限也不一定需要給,只是由於某些第三方應用程序是以服務形式啟動的,需要加上這個用戶,否則造成啟動不了。
l Windows目錄要加上給users的默認權限,否則ASP和ASPX等應用程序就無法運行。其實沒有必要單獨設置Instsrv和temp等目錄權限。
l 另外在c:/Documents and Settings/這裡相當重要,後面的目錄里的權限根本不會繼承從前的設置,如果僅僅只是設置了C盤給administrators權限,而在All Users/Application Data目錄下會 出現everyone用戶有完全控制權限,這樣入侵這可以跳轉到這個目錄,寫入腳本或只文件,再結合其他漏洞來提升權限;
譬如利用serv-u的本地溢出提升權限,或系統遺漏有補丁,數據庫的弱點,甚至社會工程學等等N多方法,在用做web/ftp服務器的系統里,建議是將這些目錄都設置的鎖死。其他每個盤的目錄都按照這樣設置,每個盤都只給adinistrators權限。
另外,還將:
net.exe
cmd.exe
t
netstat.exe
regedit.exe
at.exe
attrib.exe
cacls.exe
format.exe
這些文件都設置只允許administrators訪問。
l 網站的目錄最好獨立到一個磁盤中,新建一個為網站匿名訪問而獨立授權的賬戶,讓此賬戶可以訪問和編輯此目錄,移除其它不必要的賬戶對此目錄的訪問權限,能有效防止網站被入侵後從而涉及到整個系統被控制
日常維護建議
1
定期運行安全軟件進行快速掃描
定期運行一下安全軟件,可以看到安全軟件的引擎或病毒庫是否已經更新到了最新版本,如果沒有可以即時查找原因,看是否是安全軟件未運行、升級端口被禁用或其它原因,雖然安全軟件可以在後台即時掃描各種文件操作,以防止病毒入侵,但有些惡意軟件、流氓軟件或插件則不是實時防護的,雖然這些軟件不會造成服務器宕機,但也會影響服務器性能。
2
定期檢查防火牆端口配置
隨着服務器上的網絡服務越來越多,需要打開的網絡端口也越來越多,但有些端口是不需要開放的,例如你安裝了一個數據庫軟件(mysql、oracle等),這些數據庫服務很可能只需要在你服務器的內部訪問,就完全沒有必要讓其通過防火牆,這樣能夠提高服務器的安全,服務器對外提供的端口越少越好;
雖然在安裝網絡服務的過程中,防火牆會提示你有網絡端口正在打開,是否允許通過防火牆,但有些管理員沒有細心看提示,直接就同意了,造成了大量沒有必要打開的網絡端口被打開了,特別是一些木馬或惡意軟件會混水摸魚,偽裝提示信息來誘騙管理員打開網絡端口,造成大量的安全隱患。進入防火牆配置界面,選擇相應的端口或網絡服務,點擊「詳細信息」則可以看到此項應用的詳細信息,根據這些信息來判斷其是否應該開啟這個端口。
3
任務管理器中觀察有無可疑進程,了解系統資源使用情況
任務管理器可以簡單並快速的了解服務系統資源的使用情況,並即時查看系統運行的進程和他們佔用的系統資源,根據服務器上已開啟的各種應用的服務來判斷哪些進程是非法的,哪些進程佔用的系統資源過多。了解到這些信息後就可以即時的對服務器進行調整,特別是佔用資源過多的進程進行分析,看是否有什麼異常並即時進行調整。
l 觀察系統進程,並自定義進程屬性
4
查看網絡使用情況
查看系統資源使用情況
檢查IIS,了解網站安裝情況
隨時了解服務器上網站的安裝狀況,並做以下檢查:
1、看各個網站定義的主機頭是否異常
2、 綁定的域名是否完整
3、 主目錄設置是正確
4、用戶權限設置是否合理
5、 查看IIS的應用程序池設置是否合理,每個池下面託管的網站是否過多,是否需要設置新的應用池,是否有多餘的應用池可以刪除。
查看系統日誌,仔細檢查錯誤、警告日誌發生的原因,並急時修復相應的問題。
檢查系統用戶,查看有無多餘,可疑用戶賬戶,查看每個賬戶所屬的用戶組,特別是administrators組下面的用戶。服務器被入侵時會出現一些欺騙性的賬戶並被加入到administrators組中,特別留心新建的多餘賬戶,弄清這些賬戶的用途,如果發現是入侵者建立的賬戶,要即時查找賬戶是被創建的原因,並修復相應的漏洞。
檢查文件系統,確保磁盤被合理分區,各個分區應該有各自的功能,如系統、數據庫、網站、備份等。各個分區的用戶授權是不相同的,如系統、備份等不需要網站的專門授權賬戶訪問,數據庫分區需要對數據庫賬戶進行單獨的授權等。既然規劃好了文件分區和功能,並進行了相應的授權,就要防止文件被亂放,以免造成安全隱患。
還要經常檢查各種新建的文件夾和文件(特別是來歷不明,名稱畸形的隱藏文件夾和文件)這些都有可能是入侵者留下的入侵痕迹。
清除垃圾文件,隨時系統運行時間的增加,會產生很多的臨時文件和日誌文件,佔用寶貴的磁盤資源,如果磁盤的可用空間過小(特別是系統盤)還會影響服務器性能。
1、臨時文件(安裝程序、系統升級、應用程序等產生的)產生的,主要在系統盤,可以看哪些文件夾的體積異常大,可分析其內部文件,確認是臨時文件後將其刪除
2、 日誌文件,主要是IIS產生的,這些日誌文件對於查看網站運行狀態、訪問歷史很有用,但日誌有時效性,如果超過其三個月就沒有什麼用處了,但它會佔用大量的磁盤空間,所以需要定期將其刪除。
定期檢查磁盤狀態並進行碎片整理,隨着系統運行時間的增長,特別是大量的IO操作後,磁盤上會產生大量的文件碎片,這些碎片過多則會嚴重影響服務器性能,所以定期(建議一個月)進行磁盤碎片檢查,如果系統提醒需要進行碎片整理,則進行整理。
及時升級操作系統補丁,操作系統有各種大量的補丁,特別是一些重要的安全補丁需要即時升級,這樣會有效防止黑客和病毒入侵。
及時備份重要的文件、應用、數據庫。備份分為本地備份和異地備份,有條件的可以進行異地備份,備份是為了以防萬一,當數據丟失或應用損壞時,備份就是救命稻草,因此合理的備份計劃是非常有必要的。
不要隨意下載安裝來歷不明的軟件,特別是需要連接網絡或需要打開端口的。現在網上許多的程序都內置有木馬或惡意程序,所以不要下載和安裝網上的不明軟件,特別是一些小網站的。
END
php安全篇值過濾用戶輸入的人蔘數
規則 1:絕不要信任外部數據或輸入
關於Web應用程序安全性,必須認識到的第一件事是不應該信任外部數據。外部數據(outside data) 包括不是由程序員在PHP代碼中直接輸入的任何數據。在採取措施確保安全之前,來自任何其他來源(比如 GET 變量、表單 POST、數據庫、配置文件、會話變量或 cookie)的任何數據都是不可信任的。
例如,下面的數據元素可以被認為是安全的,因為它們是在PHP中設置的。
複製代碼 代碼如下:
?php
$myUsername = ‘tmyer’;
$arrayUsers = array(‘tmyer’, ‘tom’, ‘tommy’);define(」GREETING」, ‘hello there’ . $myUsername);?
但是,下面的數據元素都是有瑕疵的。
清單 2. 不安全、有瑕疵的代碼
複製代碼 代碼如下:
?php
$myUsername = $_POST[‘username’]; //tainted!
$arrayUsers = array($myUsername, ‘tom’, ‘tommy’); //tainted!
define(」GREETING」, ‘hello there’ . $myUsername); //tainted!
?
為 什麼第一個變量 $myUsername 是有瑕疵的?因為它直接來自表單 POST。用戶可以在這個輸入域中輸入任何字符串,包括用來清除文件或運行以前上傳的文件的惡意命令。您可能會問,「難道不能使用只接受字母 A-Z 的客戶端(Javascrīpt)表單檢驗腳本來避免這種危險嗎?」是的,這總是一個有好處的步驟,但是正如在後面會看到的,任何人都可以將任何錶單下載 到自己的機器上,修改它,然後重新提交他們需要的任何內容。
解決方案很簡單:必須對 $_POST[‘username’] 運行清理代碼。如果不這麼做,那麼在使用 $myUsername 的任何其他時候(比如在數組或常量中),就可能污染這些對象。
對用戶輸入進行清理的一個簡單方法是,使用正則表達式來處理它。在這個示例中,只希望接受字母。將字符串限制為特定數量的字符,或者要求所有字母都是小寫的,這可能也是個好主意。
清單 3. 使用戶輸入變得安全
複製代碼 代碼如下:
?php
$myUsername = cleanInput($_POST[‘username’]); //clean!
$arrayUsers = array($myUsername, ‘tom’, ‘tommy’); //clean!
define(」GREETING」, ‘hello there’ . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace(」/[^a-z]/」, 「」, $clean);$clean = substr($clean,0,12);
return $clean;
}
?
規則 2:禁用那些使安全性難以實施的 PHP 設置已經知道了不能信任用戶輸入,還應該知道不應該信任機器上配置 PHP 的方式。例如,要確保禁用 register_globals。如果啟用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替換同名的 GET 或 POST 字符串。通過禁用這個設置,PHP 強迫您在正確的名稱空間中引用正確的變量。要使用來自表單 POST 的變量,應該引用 $_POST[‘variable’]。這樣就不會將這個特定變量誤會成 cookie、會話或 GET 變量。
規則 3:如果不能理解它,就不能保護它
一些開發人員使用奇怪的語法,或者將語句組織得很緊湊,形成簡短但是含義模糊的代碼。這種方式可能效率高,但是如果您不理解代碼正在做什麼,那麼就無法決定如何保護它。
例如,您喜歡下面兩段代碼中的哪一段?
清單 4. 使代碼容易得到保護
複製代碼 代碼如下:
?php
//obfuscated code
$input = (isset($_POST[‘username’]) ? $_POST[‘username’]:」);//unobfuscated code
$input = 」;
if (isset($_POST[‘username’])){
$input = $_POST[‘username’];
}else{
$input = 」;
}
?
在第二個比較清晰的代碼段中,很容易看出 $input 是有瑕疵的,需要進行清理,然後才能安全地處理。
規則 4:「縱深防禦」 是新的法寶
本教程將用示例來說明如何保護在線表單,同時在處理表單的 PHP 代碼中採用必要的措施。同樣,即使使用 PHP regex 來確保 GET 變量完全是數字的,仍然可以採取措施確保 SQL 查詢使用轉義的用戶輸入。
縱深防禦不只是一種好思想,它可以確保您不會陷入嚴重的麻煩。
既然已經討論了基本規則,現在就來研究第一種威脅:SQL 注入攻擊。
防止 SQL 注入攻擊
在 SQL 注入攻擊 中,用戶通過操縱表單或 GET 查詢字符串,將信息添加到數據庫查詢中。例如,假設有一個簡單的登錄數據庫。這個數據庫中的每個記錄都有一個用戶名字段和一個密碼字段。構建一個登錄表單,讓用戶能夠登錄。
清單 5. 簡單的登錄表單
複製代碼 代碼如下:
html
head
titleLogin/title
/head
body
form action=」verify.php」 method=」post」
plabel for=’user’Username/label
input type=’text’ name=’user’ id=’user’/
/p
plabel for=’pw’Password/label
input type=’password’ name=’pw’ id=’pw’/
/p
pinput type=’submit’ value=’login’//p
/form
/body
/html
這個表單接受用戶輸入的用戶名和密碼,並將用戶輸入提交給名為 verify.php 的文件。在這個文件中,PHP 處理來自登錄表單的數據,如下所示:
清單 6. 不安全的 PHP 表單處理代碼
複製代碼 代碼如下:
?php
$okay = 0;
$username = $_POST[‘user’];
$pw = $_POST[‘pw’];
$sql = 「select count(*) as ctr from users where username=’」.$username.」’ and password=’」. $pw.」’ limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data-ctr == 1){
//they’re okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION[‘loginokay’] = true;
header(」index.php」);
}else{
header(」login.php」);
}
?
這 段代碼看起來沒問題,對嗎?世界各地成百(甚至成千)的 PHP/MySQL 站點都在使用這樣的代碼。它錯在哪裡?好,記住 「不能信任用戶輸入」。這裡沒有對來自用戶的任何信息進行轉義,因此使應用程序容易受到攻擊。具體來說,可能會出現任何類型的 SQL 注入攻擊。
例如,如果用戶輸入 foo 作為用戶名,輸入 ‘ or ‘1′=’1 作為密碼,那麼實際上會將以下字符串傳遞給 PHP,然後將查詢傳遞給 MySQL:
複製代碼 代碼如下:
?php
$sql = 「select count(*) as ctr from users where username=’foo’ and password=」 or ‘1′=’1′ limit 1″;?
這個查詢總是返回計數值 1,因此 PHP 會允許進行訪問。通過在密碼字符串的末尾注入某些惡意 SQL,黑客就能裝扮成合法的用戶。
解 決這個問題的辦法是,將 PHP 的內置 mysql_real_escape_string() 函數用作任何用戶輸入的包裝器。這個函數對字符串中的字符進行轉義,使字符串不可能傳遞撇號等特殊字符並讓 MySQL 根據特殊字符進行操作。清單 7 展示了帶轉義處理的代碼。
清單 7. 安全的 PHP 表單處理代碼
複製代碼 代碼如下:
?php
$okay = 0;
$username = $_POST[‘user’];
$pw = $_POST[‘pw’];
$sql = 「select count(*) as ctr from users where username=’」.mysql_real_escape_string($username).」’ and password=’」. mysql_real_escape_string($pw).」’ limit 1″;$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){if ($data-ctr == 1){
//they’re okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION[‘loginokay’] = true;
header(」index.php」);
}else{
header(」login.php」);
}
?
使用 mysql_real_escape_string() 作為用戶輸入的包裝器,就可以避免用戶輸入中的任何惡意 SQL 注入。如果用戶嘗試通過 SQL 注入傳遞畸形的密碼,那麼會將以下查詢傳遞給數據庫:
select count(*) as ctr from users where username=’foo’ and password=’\’ or \’1\’=\’1′ limit 1″數據庫中沒有任何東西與這樣的密碼匹配。僅僅採用一個簡單的步驟,就堵住了 Web 應用程序中的一個大漏洞。這裡得出的經驗是,總是應該對 SQL 查詢的用戶輸入進行轉義。
但是,還有幾個安全漏洞需要堵住。下一項是操縱 GET 變量。
防止用戶操縱 GET 變量
在前一節中,防止了用戶使用畸形的密碼進行登錄。如果您很聰明,應該應用您學到的方法,確保對 SQL 語句的所有用戶輸入進行轉義。
但 是,用戶現在已經安全地登錄了。用戶擁有有效的密碼,並不意味着他將按照規則行事 —— 他有很多機會能夠造成損害。例如,應用程序可能允許用戶查看特殊的內容。所有鏈接指向 template.php?pid=33 或 template.php?pid=321 這樣的位置。URL 中問號後面的部分稱為查詢字符串。因為查詢字符串直接放在 URL 中,所以也稱為 GET 查詢字符串。
在 PHP 中,如果禁用了 register_globals,那麼可以用 $_GET[‘pid’] 訪問這個字符串。在 template.php 頁面中,可能會執行與清單 8 相似的操作。
清單 8. 示例 template.php
複製代碼 代碼如下:
?php
$pid = $_GET[‘pid’];
//we create an object of a fictional class Page$obj = new Page;
$content = $obj-fetchPage($pid);
//and now we have a bunch of PHP that displays the page?
這 里有什麼錯嗎?首先,這裡隱含地相信來自瀏覽器的 GET 變量 pid 是安全的。這會怎麼樣呢?大多數用戶沒那麼聰明,無法構造出語義攻擊。但是,如果他們注意到瀏覽器的 URL 位置域中的 pid=33,就可能開始搗亂。如果他們輸入另一個數字,那麼可能沒問題;但是如果輸入別的東西,比如輸入 SQL 命令或某個文件的名稱(比如 /etc/passwd),或者搞別的惡作劇,比如輸入長達 3,000 個字符的數值,那麼會發生什麼呢?
在這種情況下,要記住基本規則,不要信任用戶輸入。應用程序開發人員知道 template.php 接受的個人標識符(PID)應該是數字,所以可以使用 PHP 的 is_numeric()函數確保不接受非數字的 PID,如下所示:
清單 9. 使用 is_numeric() 來限制 GET 變量複製代碼 代碼如下:
?php
$pid = $_GET[‘pid’];
if (is_numeric($pid)){
//we create an object of a fictional class Page$obj = new Page;
$content = $obj-fetchPage($pid);
//and now we have a bunch of PHP that displays the page}else{
//didn’t pass the is_numeric() test, do something else!
}
?
這個方法似乎是有效的,但是以下這些輸入都能夠輕鬆地通過 is_numeric() 的檢查:
100 (有效)
100.1 (不應該有小數位)
+0123.45e6 (科學計數法 —— 不好)
0xff33669f (十六進制 —— 危險!危險!)那麼,有安全意識的 PHP 開發人員應該怎麼做呢?多年的經驗表明,最好的做法是使用正則表達式來確保整個 GET 變量由數字組成,如下所示:
清單 10. 使用正則表達式限制 GET 變量
複製代碼 代碼如下:
?php
$pid = $_GET[‘pid’];
if (strlen($pid)){
if (!ereg(」^[0-9]+$」,$pid)){
//do something appropriate, like maybe logging them out or sending them back to home page}
}else{
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//moderately protected from evil user input$obj = new Page;
$content = $obj-fetchPage($pid);
//and now we have a bunch of PHP that displays the page?
需 要做的只是使用 strlen() 檢查變量的長度是否非零;如果是,就使用一個全數字正則表達式來確保數據元素是有效的。如果 PID 包含字母、斜線、點號或任何與十六進制相似的內容,那麼這個例程捕獲它並將頁面從用戶活動中屏蔽。如果看一下 Page 類幕後的情況,就會看到有安全意識的 PHP 開發人員已經對用戶輸入 $pid 進行了轉義,從而保護了 fetchPage() 方法,如下所示:
清單 11. 對 fetchPage() 方法進行轉義
複製代碼 代碼如下:
?php
class Page{
function fetchPage($pid){
$sql = 「select pid,title,desc,kw,content,status from page where pid=’」.mysql_real_escape_string($pid).」’」;}
}
?
您可能會問,「既然已經確保 PID 是數字,那麼為什麼還要進行轉義?」 因為不知道在多少不同的上下文和情況中會使用 fetchPage() 方法。必須在調用這個方法的所有地方進行保護,而方法中的轉義體現了縱深防禦的意義。
如 果用戶嘗試輸入非常長的數值,比如長達 1000 個字符,試圖發起緩衝區溢出攻擊,那麼會發生什麼呢?下一節更詳細地討論這個問題,但是目前可以添加另一個檢查,確保輸入的 PID 具有正確的長度。您知道數據庫的 pid 字段的最大長度是 5 位,所以可以添加下面的檢查。
清單 12. 使用正則表達式和長度檢查來限制 GET 變量複製代碼 代碼如下:
?php
$pid = $_GET[‘pid’];
if (strlen($pid)){
if (!ereg(」^[0-9]+$」,$pid) strlen($pid) 5){//do something appropriate, like maybe logging them out or sending them back to home page}
} else {
//empty $pid, so send them back to the home page}
//we create an object of a fictional class Page, which is now//even more protected from evil user input$obj = new Page;
$content = $obj-fetchPage($pid);
//and now we have a bunch of PHP that displays the page?
現在,任何人都無法在數據庫應用程序中塞進一個 5,000 位的數值 —— 至少在涉及 GET 字符串的地方不會有這種情況。想像一下黑客在試圖突破您的應用程序而遭到挫折時咬牙切齒的樣子吧!而且因為關閉了錯誤報告,黑客更難進行偵察。
緩衝區溢出攻擊
緩衝區溢出攻擊 試圖使 PHP 應用程序中(或者更精確地說,在 Apache 或底層操作系統中)的內存分配緩衝區發生溢出。請記住,您可能是使用 PHP 這樣的高級語言來編寫 Web 應用程序,但是最終還是要調用 C(在 Apache 的情況下)。與大多數低級語言一樣,C 對於內存分配有嚴格的規則。
緩衝區溢出攻擊向緩衝區發送大量數據,使部分數據溢出到相鄰的內存緩衝區,從而破壞緩衝區或者重寫邏輯。這樣就能夠造成拒絕服務、破壞數據或者在遠程服務器上執行惡意代碼。
防止緩衝區溢出攻擊的惟一方法是檢查所有用戶輸入的長度。例如,如果有一個表單元素要求輸入用戶的名字,那麼在這個域上添加值為 40 的 maxlength 屬性,並在後端使用 substr() 進行檢查。清單 13 給出表單和 PHP 代碼的簡短示例。
原創文章,作者:JK1H7,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/126523.html