Insécurité de configuration PHP courante?

10

Je travaille avec l'administration des systèmes dans une université et je suis juste tombé sur quelque chose qui est probablement commun, mais qui a été un choc pour moi.

Tous les répertoires public_html et les zones Web sont stockés sur afs, avec des autorisations de lecture pour les serveurs Web. Étant donné que les utilisateurs sont autorisés à avoir des scripts php dans leur public_html, cela signifie qu'ils peuvent accéder aux fichiers des autres depuis php (et les principaux fichiers Web!).

Non seulement cela rend toute protection par mot de passe .htaccess complètement inutile, mais cela permet également aux utilisateurs de lire des fichiers source php contenant des mots de passe de base de données mysql et des informations sensibles similaires. Ou s'ils découvrent que d'autres personnes ont des répertoires où les serveurs Web ont un accès en écriture (par exemple pour les journaux personnels ou pour enregistrer les données de formulaire soumises), ils peuvent stocker des fichiers dans ces comptes.

Un exemple simple:

<?
  header("Content-type: text/plain");
  print file_get_contents("/afs/example.com/home/smith/public_html/.htpasswd"); 
?>

Est-ce un problème courant? Et comment le résolvez-vous généralement?

METTRE À JOUR:

Merci pour la contribution. Malheureusement, il semble qu'il n'y ait pas de réponse simple. Dans un grand environnement partagé comme celui-ci, les utilisateurs ne devraient probablement pas avoir autant de choix. La meilleure approche à laquelle je peux penser est de définir "open_basedir" dans la configuration principale pour tous les répertoires "public_html", d'exécuter suphp et de n'autoriser que le php propre (pas de scripts cgi, exécution de commandes externes avec des astuces, etc.).

Changer la politique comme ça casserait beaucoup de choses cependant, et inciterait très probablement les utilisateurs à saisir leur fourche et à nous poursuivre ... J'en discuterai avec mes collègues et je mettrai à jour ici si nous décidons comment changer la configuration.

Pontus
la source
C'est une question intéressante. Je suis sûr que sur les principaux fournisseurs d'hébergement partagé (par exemple DreamHost), ce n'est pas possible. Mais j'aimerais savoir comment ils se protègent de cela. suphp, comme mentionné cstamas, ressemble à une bonne solution, mais est-ce ce que la plupart des hébergeurs utilisent?
Lèse majesté
1
J'ai utilisé la open_basedirsolution ci-dessous sur les systèmes d'hébergement partagé de production, mais nous avons divisé tout le monde en leur propre vhost - Je ne sais pas si cela fonctionne pour les répertoires uniques ...
voretaq7

Réponses:

8

On peut utiliser suphp qui exécute le script php avec l'uid de son propriétaire.

http://www.suphp.org

cstamas
la source
Cela ne résoudra probablement pas le problème ci-dessus (au moins dans un environnement d'hébergement partagé. donc même avec suphp ils pourraient lire ces fichiers)
voretaq7
@ voretaq7: plusieurs autres restrictions peuvent être appliquées. Autant que je me souvienne, vous pouvez même refuser l'accès à des fichiers que vous ne possédez pas. Donc, cela exclut l'attaque ci-dessus.
cstamas
Je sais que vous pouvez restreindre les autorisations sur les fichiers ("ne peut pas être accessible en écriture par un groupe / autre / n'importe qui"), mais je ne connais pas de moyen de bloquer les lectures au-delà des autorisations FS. Ils l'ont fait check_vhost_docroot, mais AFAIK qui ne s'applique qu'au script en cours d'exécution (? Je pourrais me tromper à ce sujet)
voretaq7
1
Je ne sais pas si suphp est une bonne solution dans un environnement comme celui-ci. Un utilisateur peut avoir toutes sortes d'autorisations que l'utilisateur www n'a pas. Un attaquant qui aurait trouvé un moyen d'utiliser php pourrait trouver des clés ssh ou des keytabs, ou modifier les scripts de connexion d'un utilisateur pour créer des backdoors. Et les paramètres "vhosts" ne sont pas très utiles car les répertoires public_html sont disponibles via "/ ~ username" sur l'hôte virtuel principal. Je pense que les scripts dans public_html devraient être complètement désactivés.
Pontus
4

Ma suggestion serait de limiter l'accès de PHP aux fichiers (via open_basedirdes directives similaires, sur une base par hôte): vous voulez que les utilisateurs puissent ouvrir / lire / écrire des fichiers sous leur racine Web, et peut-être un niveau au-dessus (pour zéro espace), mais pas un répertoire où ils seraient par exemple stocker des htpasswdfichiers.

Une structure de répertoires comme:

/Client
    /auth
    /site
        /www_root
        /www_tmp

Répondrait à cette exigence: open_basedirpourrait être pointé en /Client/sitetoute sécurité et les htpasswdfichiers stockés dans /Client/auth(avec des .htaccessfichiers ou httpd.confmodifiés pour pointer à l'emplacement approprié à la place).
Cela empêche vos clients d'ouvrir les fichiers de quelqu'un d'autre ET, comme avantage, les utilisateurs malveillants ne peuvent pas lire le contenu /Client/auth(ou quoi que ce soit d'autre sur votre système, comme /etc/passwd:-)

Voir http://php.net/manual/en/ini.core.php pour plus de détails sur l'implémentation open_basedir et per-vhost.

voretaq7
la source
1
suphpcomme indiqué par cstamas est également une très bonne idée dans un environnement d'hébergement partagé - Il y a un peu de temps pour le configurer, mais je dirais que le gain de sécurité en vaut la peine. À moins de sandboxer tous vos sites PHP dans quelque chose comme une prison FreeBSD ou une machine virtuelle dédiée qui est l'une des plus grandes victoires en matière de sécurité.
voretaq7
"open_basedir" semble être un moyen simple de séparer les fichiers Web principaux de ceux des utilisateurs, à condition que "public_html" soit servi via son propre hôte virtuel. Mais cela ne protège pas les utilisateurs les uns des autres, car ils n'ont pas leurs propres hôtes virtuels. Droite?
Pontus
Je n'ai pas essayé de mettre à l' open_basedirintérieur d'une directive <Directory>, mais je pense que cela devrait être permis ("essayez-le et voyez" - le pire qu'il puisse faire ne fonctionne pas :)
voretaq7
1
Jusqu'à présent, il semble que open_basedir soit ce que la plupart des hébergeurs commerciaux utilisent (généralement les abonnés ont leurs propres domaines payants ou reçoivent un sous-domaine gratuit), mais pour les pages d'accueil basées sur un annuaire comme dans un établissement universitaire, suphp semble être la meilleure réponse.
Lèse majesté
1

Non, ce n'est pas un problème commun car la plupart des hôtes partagés définiraient une configuration open_basedir dans le fichier htaccess du répertoire public_html de chaque utilisateur (ou dans le vhost si chaque utilisateur a son propre vhost).

par exemple du fichier .htaccess:

# Assuming these are not set globally - its good practice to limit:
  php_flag magic_quotes_gpc off
  php_flag magic_quotes_runtime off
  php_flag register_globals off
  php_flag short_open_tag off
  php_value max_execution_time 60

# These set the user-specific paths
  php_value open_basedir /afs/example.com/home/smith:/usr/share/php/include
  php_value session.save_path /afs/example.com/home/smith/tmp
  php_value upload_tmp_dir /afs/example.com/home/smith/tmp

Mais assurez-vous de définir les bonnes autorisations sur le fichier .htaccess pour empêcher l'utilisateur de modifier l'open_basedir (s'il essaie de le remplacer dans subdir / .htaccess, cela ne devrait pas fonctionner - mais vous devriez probablement le tester pour vous en assurer) .

HTH

C.

symcbean
la source
2
Cela pourrait aider à offrir une protection initiale des nouveaux comptes. Mais le fait qu'un utilisateur ne puisse pas le modifier peut rendre tentant de supprimer le fichier .htaccess (ce qu'ils peuvent faire car il ne nécessite qu'un accès en écriture au répertoire public_html) et de créer le leur. L'ajout d'un bloc "<Directory>" dans la configuration principale pour chaque utilisateur fonctionnerait, mais ici, ils sont toujours autorisés à ajouter des commandes externes à partir de php, ce qui signifie que open_basedir est facilement contourné.
Pontus
@Pontus: bon point sur la suppression du fichier (je ne sais pas si afs prend en charge l'attribut de fichier immuable). J'aurais donné +1 si vous aviez dit que l'exécution du serveur Web en prison chroot protégerait contre toutes sortes de vulnérabilités d'exécution de programme.
symcbean
1

AFS ignore les autorisations utilisateur Unix simples. suPHP exécute un setuid avant d'exécuter le programme php, mais cela ne donne pas au processus les jetons Kerberos nécessaires pour accéder à AFS et être limité à ses autorisations. suPHP devrait être modifié d'une manière ou d'une autre pour obtenir ces jetons avant de pouvoir se présenter au système AFS en tant qu'utilisateur. Pour autant que je sache, cela n'a pas été fait. (En fait, j'ai trouvé cette question en cherchant à voir si quelqu'un d'autre l'avait fait.)

Charles B
la source