5、檔案上傳
php的檔案上傳機制是把使用者上傳的檔案保留在php.ini的upload_tmp_dir定義的臨時目錄(預設是系統的臨時目錄,如:/tmp)裡的乙個類似phpxxuoxg的隨機臨時檔案,程式履行結束,該臨時檔案也被刪除。php給上傳的檔案定義了四個變數:(如form變數名是file,而且register_globals開啟)
$file #就是保留到伺服器真個臨時檔案(如/tmp/phpxxuoxg )
$file_size #上傳檔案的大小
$file_name #上傳檔案的原始名稱
$file_type #上傳檔案的型別
推薦應用:
這是乙個最簡略的檔案上傳**:
//test_5.php
if(isset($upload) && $file != 'none')
?>
content='text/html; charset=gb2312'>
這樣的上傳**存在讀取任意檔案和履行命令的重大標題。
下面的懇求可以把/etc/passwd文件拷貝到web目錄/usr/local/apache/htdocs/test(留心:這個目錄必需nobody可寫)下的attack.txt檔案裡:
然後可以用如下懇求讀取口令檔案:
攻擊者可以把php檔案拷貝成其它擴大名,洩漏指令碼源**。
攻擊者可以自定義form裡file_name變數的值,上傳籠罩任意有寫許可權的檔案。
攻擊者還可以上傳php指令碼履行主機的命令。
解決方法:
php-4.0.3以後供給了is_uploaded_file和move_uploaded_file函式,可以檢查把持的檔案是否是使用者上傳的檔案,從而避免把系統檔案拷貝到web目錄。
應用$http_post_files陣列來讀取使用者上傳的檔案變數。
嚴格檢查上傳變數。比如不答應是php指令碼檔案。
把php指令碼把持限制在web目錄可以避免程式設計師應用copy函式把系統檔案拷貝到web目錄。move_uploaded_file不受open_basedir的限制,所以不必修正php.ini裡upload_tmp_dir的值。
把php指令碼用phpencode進行加密,避免由於copy把持洩漏原始碼。
嚴格配置檔案和目錄的許可權,只答應上傳的目錄能夠讓nobody使用者可寫。
對於上傳目錄往掉php說明功效,可以通過修正httpd.conf實現:
php_flag engine off
#假如是php3換成php3_engine off
重啟apache,upload目錄的php檔案就不能被apache說明了,即使上傳了php檔案也沒有標題,只能直接顯示原始碼。
6、命令履行
下面的**片段是從phpnettoolpack摘出,具體的描寫見:
//test_6.php
system('traceroute $a_query',$ret_strs);
?>
由於程式沒有過濾$a_query變數,所以攻擊者可以用分號來追加履行命令。
攻擊者輸進如下懇求可以履行cat /etc/passwd命令:
php的命令履行函式還有system(), passthru(), popen()和``等。命令履行函式非常危險,慎用。假如要應用必定要嚴格檢查使用者輸進。
解決方法:
請求程式設計師應用escapeshellcmd()函式過濾使用者輸進的shell命令。
啟用safe_mode可以杜盡很多履行命令的標題,不過要留心php的版本必定要是最新的,小於php-4.2.2的都可能繞過safe_mode的限制往履行命令。
7、sql_inject
如下的sql語句假如未對變數進行處理就會存在標題:
select * from login where user='$user' and pass='$pass'
攻擊者可以使用者名稱和口令都輸進1' or 1='1繞過驗證。
不過幸虧php有乙個預設的選項magic_quotes_gpc = on,該選項使得從get, post, cookie來的變數主動加了addslashes()把持。上面sql語句變成了:
select * from login where user='1\' or
1=\'1' and pass='1\' or 1=\'1'
從而避免了此類sql_inject攻擊。
對於數字型別的字段,很多程式設計師會這樣寫:
select * from test where id=$id
由於變數沒有用單引號擴起來,就會造成sql_inject攻擊。幸虧mysql功效簡略,沒有sqlserver等資料庫有履行命令的sql語句,而且php的mysql_query()函式也只答應履行一條sql語句,所以用分號隔開多條sql語句的攻擊也不能奏效。但是攻擊者最少還可以讓查詢語句出錯,洩漏系統的一些資訊,或者一些意想不到的情況。
解決方法:
請求程式設計師對所有使用者提交的要放到sql語句的變數進行過濾。
即使是數字型別的字段,變數也要用單引號擴起來,mysql自己會把字串處理成數字。
在mysql裡不要給php程式高階別許可權的使用者,只答應對自己的庫進行把持,這也避免了程式呈現標題被 select into outfile ... 這種攻擊。
8、警告及錯誤資訊
php預設顯示所有的警告及錯誤資訊:
error_reporting = e_all & ~e_notice
display_errors = on
在平時開發除錯時這非常有用,可以根據警告資訊馬上找到程式錯誤所在。
正式利用時,警告及錯誤資訊讓使用者不知所措,而且給攻擊者洩漏了指令碼所在的物理路徑,為攻擊者的進一步攻擊供給了有利的資訊。而且由於自己沒有拜訪到錯誤的處所,反而不能及時修正程式的錯誤。所以把php的所有警告及錯誤資訊記錄到乙個日誌檔案是非常明智的,即不給攻擊者洩漏物理路徑,又能讓自己知道程式錯誤所在。
修正php.ini中關於error handling and logging部分內容:
error_reporting = e_all
display_errors = off
log_errors = on
error_log = /usr/local/apache/logs/php_error.log
然後重啟apache,留心檔案/usr/local/apache/logs/php_error.log必需可以讓nobody使用者可寫。
9、disable_functions
假如感到有些函式還有要挾,可以設定php.ini裡的disable_functions(這個選項不能在httpd.conf裡設定),比如:
disable_functions = phpinfo, get_cfg_var
可以指定多個函式,用逗號離開。重啟apache後,phpinfo, get_cfg_var函式都被禁止了。建議封閉函式phpinfo, get_cfg_var,這兩個函式輕易洩漏伺服器資訊,而且沒有實際用處。
10、disable_classes
這個選項是從php-4.3.2開端才有的,它可以禁用某些類,假如有多個用逗號分隔類名。disable_classes也不能在httpd.conf裡設定,只能在php.ini配置檔案裡修正。
11、open_basedir
前面分析例程的時候也多次提到用open_basedir對指令碼把持路徑進行限制,這裡再先容一下它的特徵。用open_basedir指定的限制實際上是字首,不是目錄名。也就是說 'open_basedir = /dir/incl' 也會答應拜訪 '/dir/include' 和 '/dir/incls',假如它們存在的話。假如要將拜訪限制在僅為指定的目錄,用斜線結束路徑名。例如:'open_basedir = /dir/incl/'。
可以設定多個目錄,在windows中,用分號分隔目錄。在任何其它系統中用冒號分隔目錄。作為apache模組時,父目錄中的open_basedir路徑主動被持續。
PHP安全配置
繼續上傳 exit 這樣的上傳 存在讀取任意檔案和執行命令的重大問題。下面的請求可以把 etc passwd文件拷貝到web目錄 usr local apache htdocs test 注意 這個目錄必須nobody可寫 下的attack.txt檔案裡 然後可以用如下請求讀取口令檔案 攻擊者可以把...
php 配置安全設定!
安全 php 編寫是一方面,php的配置更是非常關鍵。我們php手手工安裝 的,php的預設配置檔案在 usr local apache2 conf php.ini,我們最主要就是要配置php.ini中的內容,讓我們執行 php能夠更安全。整個php中的安全設定主要是為了防止phpshell和sql...
PHP安全配置 1
一 web伺服器安全 php其實不過是web伺服器的乙個模組功能,所以首先要保證web伺服器的安全。當然web伺服器要安全又必須是先保證系統安全,這樣就扯遠了,無窮無盡。php可以和各種web伺服器結合,這裡也只討論apache。非常建議以chroot方式安裝啟動apache,這樣即使apache和...