Quelles variables $ _SERVER sont sûres?

97

Toute variable qu'un utilisateur peut contrôler, un attaquant peut également contrôler et est donc une source d'attaque. Cela s'appelle une variable «corrompue» et n'est pas sûre.

Lors de l'utilisation $_SERVER, de nombreuses variables peuvent être contrôlées. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEEt bien d' autres font partie de l' en- tête de requête HTTP envoyé par le client.

Est-ce que quelqu'un connaît une «liste sûre» ou une liste intacte de $_SERVERvariables?

tour
la source
8
Dépend de la façon dont vous définissez «sûr». Les valeurs sont toutes sûres telles quelles, cela dépend uniquement de l'utilisation que vous en faites.
deceze
6
Je pense que dans ce contexte, Rook dit "Quelles variables de serveur ne peuvent pas être usurpées par l'utilisateur", comme REMOTE_ADDR.
vcsjones
6
Tout ce qui HTTP_est précédé de est un en-tête de demande et peut être défini par le navigateur ou le proxy entre les deux. Je les considérerais comme n'importe quelle autre entrée d'utilisateur.
datage du
3
@ bob-the-destroyer REMOTE_ADDR est extrait directement du socket TCP d'Apache, cette valeur ne peut pas être usurpée sur Internet en raison de la négociation à trois.
Tour du
2
@Rook: bon point. J'imagine qu'avec la mention de "spoofing", j'étais plus penché vers le vieil acte de spoofing ip lui-même, plutôt que de truquer la valeur réelle de REMOTE_ADDR. Et ce serait hors de portée de cette question. C'est bien d'avoir un aperçu de la façon dont cette valeur est définie, alors merci.
bob-the-destroyer

Réponses:

147

Il n'existe pas de valeurs «sûres» ou «non sûres» en tant que telles. Il n'y a que les valeurs que le serveur contrôle et les valeurs que l'utilisateur contrôle et vous devez savoir d'où vient une valeur et donc si elle peut être approuvée dans un certain but. $_SERVER['HTTP_FOOBAR']par exemple, il est tout à fait sûr de stocker dans une base de données, mais je ne le ferais certainement pas eval.

En tant que tel, divisons ces valeurs en trois catégories:

Contrôlé par le serveur

Ces variables sont définies par l'environnement du serveur et dépendent entièrement de la configuration du serveur.

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

Contrôlé en partie par le serveur

Ces variables dépendent de la demande spécifique envoyée par le client, mais ne peuvent accepter qu'un nombre limité de valeurs valides, car toutes les valeurs non valides doivent être rejetées par le serveur Web et ne pas déclencher l'appel du script. Par conséquent, ils peuvent être considérés comme fiables .

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* Les REMOTE_valeurs sont garanties comme étant l'adresse valide du client, comme vérifié par une poignée de main TCP / IP. Il s'agit de l'adresse à laquelle toute réponse sera envoyée. REMOTE_HOSTrepose sur des recherches DNS inversées et peut donc être usurpé par des attaques DNS contre votre serveur (auquel cas vous avez de toute façon de plus gros problèmes). Cette valeur peut être un proxy, ce qui est une simple réalité du protocole TCP / IP et vous ne pouvez rien faire.

† Si votre serveur Web répond à une demande quel que soit l'en- HOSTtête, cela doit également être considéré comme dangereux. Voir Dans quelle mesure $ _SERVER ["HTTP_HOST"] est-il sûr? .
Voir également http://shiflett.org/blog/2006/mar/server-name-versus-http-host .

‡ Voir https://bugs.php.net/bug.php?id=64457 , http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport , http: //httpd.apache. org / docs / 2.4 / mod / core.html # comment_999

Valeurs contrôlées par l'utilisateur entièrement arbitraires

Ces valeurs ne sont pas du tout vérifiées et ne dépendent d'aucune configuration de serveur, ce sont des informations entièrement arbitraires envoyées par le client.

  • 'argv', 'argc'(applicable uniquement à l'invocation CLI, ne concerne généralement pas les serveurs Web)
  • 'REQUEST_METHOD' §
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE'
  • 'PHP_AUTH_DIGEST'
  • 'PHP_AUTH_USER'
  • 'PHP_AUTH_PW'
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI' (peut contenir des données corrompues)
  • 'PHP_SELF' (peut contenir des données corrompues)
  • 'PATH_TRANSLATED'
  • toute autre 'HTTP_'valeur

§ Peut être considéré comme fiable tant que le serveur Web n'autorise que certaines méthodes de demande.

‖ Peut être considéré comme fiable si l'authentification est entièrement gérée par le serveur Web.

Le superglobal $_SERVERcomprend également plusieurs variables d'environnement. Le fait qu'ils soient «sûrs» ou non dépend de la manière (et du lieu) qu'ils sont définis. Ils peuvent aller de complètement contrôlés par le serveur à complètement contrôlés par l'utilisateur.

déceler
la source
3
@Rook Mais comme je l'ai dit, cela dépend absolument de la façon dont vous l'utilisez . Les valeurs seules ne sont ni sûres ni dangereuses, cela dépend de l' utilisation que vous en faites . Même les données envoyées par un utilisateur malveillant sont parfaitement sécurisées tant que vous ne faites rien avec elles qui puisse compromettre votre sécurité.
deceze
2
@Rook: votre idée de "sûr" fait paraître cette question un peu arbitraire, d'autant plus qu'elle est entièrement liée à une extension obscure ou à une version personnalisée de PHP. Alors que vous dites "ne devrait pas avoir une" approche "shootée de la hanche", toute réponse semble en fait exiger au minimum une familiarité avec le code source PHP pour savoir comment ces valeurs sont définies. Envoyer des e-mails aux développeurs PHP ne serait-il pas une meilleure approche pour trouver une réponse?
bob-the-destroyer
2
@Rook: Mauvaise communication. Comme deceze l'a laissé entendre, "sans danger dans quel but". Comme je l'ai laissé entendre, votre objectif est inconnu, et en outre, il existe plusieurs autres $_SERVERvaleurs non documentées en fonction de la façon dont le fichier est servi. À mon avis, les documents documentés ne clarifient pas la vraie source. Sinon, je pense que vous ne poseriez pas cette question. Heureux que vous ayez une liste que vous pouvez utiliser. Mais je suggérerais toujours de soumettre un rapport de bogue (lorsque leur site de bogue est corrigé), d'envoyer un e-mail aux responsables de la documentation ou de mettre à jour les documents vous-même (si vous êtes au courant du lien). Il serait avantageux pour la communauté de connaître ces informations.
bob-the-destroyer
3
SERVER_NAMEn'est pas nécessairement contrôlé par le serveur. En fonction de la passerelle et des paramètres, il peut être dupliqué HTTP_HOSTet donc soumis à la même mise en garde.
bobince
1
@deceze @Rook Avez-vous SERVER_PORTbesoin de cette petite croix? bugs.php.net/bug.php?id=64457
Dejan Marjanović
12

En PHP, chaque $_SERVERvariable commençant par HTTP_peut être influencée par l'utilisateur. Par exemple, la variable $_SERVER['HTTP_REINERS']peut être contaminée en définissant l'en-tête HTTP REINERSsur une valeur arbitraire dans la requête HTTP.

Reiners
la source
re "arbitraire"; Pas entièrement arbitraire car ils se conforment à un format. Par exemple, $_SERVER['HTTP_REINERS'] ne peut pas contenir de caractères de nouvelle ligne sous la plupart des sapis.
Pacerier