php安全之一的PHP防注入是我們程序員必須了解與撐握的一項技術了,下面我來給各位同學介紹對於我們程序裡的敏感信息的一些安全做法。
簡單點來說就是你不想讓別人知道的信息,比如說數據庫的地址,用戶名,密碼等等,此類信息往往知道的人越少越好。
通常,PHP程序裡的配置文件大致如下所示:
代碼如下 復制代碼<?php
return array(
'database' => array(
'host' => '192.168.0.1',
'user' => 'administrator',
'password' => 'e1bfd762321e409cee4ac0b6e841963c',
),
);
?>
有時候出於某些原因,比如說代碼審查,亦或者合作開發等等,第三方需要獲取代碼版本倉庫的讀權限,一旦授權,數據庫的地址,用戶名,密碼等敏感信息就暴露了。當然也可以不在代碼版本倉庫裡保存配置文件,取而代之是撰寫文檔進行說明,但我不喜歡這樣的方法,因為如此一來,代碼本身是不完整的。
如何解決此類問題呢?最直接的方法是把敏感信息從代碼中拿掉,換個地方保存。具體保存到哪裡呢?有很多選擇,比如說通過nginx的fastcgi_param來設置:
代碼如下 復制代碼fastcgi_param DATABASE_HOST 192.168.0.1;
fastcgi_param DATABASE_USER administrator;
fastcgi_param DATABASE_PASSWORD e1bfd762321e409cee4ac0b6e841963c;
經過這樣的映射後,我們的代碼就不會直接包含敏感信息了:
<?php
return array(
'database' => array(
'host' => $_SERVER['DATABASE_HOST'],
'user' => $_SERVER['DATABASE_USERNAME'],
'password' => $_SERVER['DATABASE_PASSWORD'],
),
);
?>
此外,還可以通過php-fpm的env指令來設置:
代碼如下 復制代碼env[DATABASE_HOST] = 192.168.0.1
env[DATABASE_USERNAME] = administrator
env[DATABASE_PASSWORD] = e1bfd762321e409cee4ac0b6e841963c
需要說明的一點是,這個設置必須放在主配置文件php-fpm.conf裡,不能放到include指令設置的子配置文件裡,否則會報錯:「Array are not allowed in the global section」;另外一點,雖然是通過env設置的,但結果還是在$_SERVER裡,而不是$_ENV。
說明: @Laruence 提醒了我,如果配置信息通過nginx的fastcgi_param來設置的話,當nginx和php交互時,會帶來大量的數據傳輸(如此看來通過php-fpm的env來設置相對更有優勢),鳥哥建議使用獨立的擴展來搞定,比如「hidef」。
通過nginx和php-fpm配置文件來解決問題的話,有一個缺點,僅對Web有效,如果通過命令行來運行,那麼無法在$_SERVER裡獲取相關信息,不過這不算什麼難事兒,只要寫個公共的腳本正則匹配一下nginx或者php-fpm的配置文件,就可以動態的把這些信息映射到命令行環境,具體怎麼搞就留給大家自己操作吧。
代碼干淨了,剩下的工作就是如何確保nginx或php-fpm配置文件的安全了,不過和代碼比起來,nginx或php-fpm配置文件並不需要很多人有權限,所以相對更容易管理
還有一個重要的函數phpinfo()這個大家一定要注意了,如能正常顯示phpinfo函數我們可
詳情
PHPInfo提供了以下一些信息:
*PHP 版本 (包括build版本在內的精確版本信息)
*系統版本信息(包括build版本在內的精確版本信息)
*擴展目錄(PHP所在目錄)
*SMTP服務器信息
*Sendmail路徑(如果Sendmail安裝了的話)
*Posix版本信息
*數據庫
*ODBC 設置(包括的路徑,數據庫名,默認的密碼等等)
*MySQL 客戶端的版本信息(包括build版本在內的精確版本信息)
*Oracle版本信息和庫的路徑
*所在位置的實際路徑
*Web 服務器
*IIS 版本信息
*Apache 版本信息
*如果在Win32下運行:
*計算機名
*Windows目錄的位置
*路徑(能用來洩漏已安裝的軟件信息)
例子:
訪問一個類似於下面的URL:
http://www.example.com/PHP/phpinfo.php