Welche $ _SERVER-Variablen sind sicher?

97

Jede Variable, die ein Benutzer steuern kann, kann auch ein Angreifer steuern und ist daher eine Angriffsquelle. Dies wird als "verdorbene" Variable bezeichnet und ist unsicher.

Bei der Verwendung $_SERVERkönnen viele der Variablen gesteuert werden. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEUnd viele andere sind ein Teil der HTTP - Request - Header durch den Client gesendet.

Kennt jemand eine "sichere Liste" oder eine unbefleckte Liste von $_SERVERVariablen?

Turm
quelle
8
Kommt darauf an, wie du "sicher" definierst. Die Werte sind alle sicher , es kommt nur darauf an, wofür Sie sie verwenden.
Täuschung
6
Ich denke in diesem Zusammenhang sagt Rook "Welche Servervariablen können vom Benutzer nicht gefälscht werden", wie z REMOTE_ADDR.
vcsjones
6
Alles, was vorangestellt HTTP_ist , ist ein Anforderungsheader und kann vom Browser oder Proxy dazwischen festgelegt werden. Ich würde diese als jede andere Benutzereingabe betrachten.
Datensatz
3
@ bob-the-destroyyer REMOTE_ADDR wird direkt aus dem TCP-Socket von Apache gezogen. Dieser Wert kann aufgrund des Drei-Wege-Handshakes nicht über das Internet gefälscht werden .
Turm
2
@Rook: guter Punkt. Ich denke, mit der Erwähnung von "Spoofing" neigte ich eher zum alten Akt des IP-Spoofings selbst als zu irgendeiner Art, den tatsächlichen Wert von zu fälschen REMOTE_ADDR. Und das wäre nicht Gegenstand dieser Frage. Gut, um einen Einblick zu bekommen, wie dieser Wert eingestellt wird, also danke.
Bob-the-Zerstörer

Antworten:

147

Es gibt keine "sicheren" oder "unsicheren" Werte als solche. Es gibt nur Werte, die der Server steuert, und Werte, die der Benutzer steuert. Sie müssen wissen, woher ein Wert stammt und ob er für einen bestimmten Zweck vertrauenswürdig ist. $_SERVER['HTTP_FOOBAR']Zum Beispiel ist es völlig sicher, in einer Datenbank zu speichern, aber ich würde evales mit Sicherheit nicht tun.

Teilen wir diese Werte daher in drei Kategorien ein:

Servergesteuert

Diese Variablen werden von der Serverumgebung festgelegt und hängen vollständig von der Serverkonfiguration ab.

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

Teilweise servergesteuert

Diese Variablen hängen von der spezifischen Anforderung ab, die der Client gesendet hat, können jedoch nur eine begrenzte Anzahl gültiger Werte annehmen, da alle ungültigen Werte vom Webserver zurückgewiesen werden sollten und nicht dazu führen, dass der Aufruf des Skripts beginnt. Daher können sie als zuverlässig angesehen werden .

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

* Die REMOTE_Werte sind garantiert die gültige Adresse des Clients, die durch einen TCP / IP-Handshake überprüft wurde. Dies ist die Adresse, an die eine Antwort gesendet wird. REMOTE_HOSTstützt sich jedoch auf Reverse-DNS-Lookups und kann daher durch DNS-Angriffe auf Ihren Server gefälscht werden (in diesem Fall haben Sie ohnehin größere Probleme). Dieser Wert kann ein Proxy sein, was eine einfache Realität des TCP / IP-Protokolls ist und nichts, gegen das Sie etwas tun können.

† Wenn Ihr Webserver unabhängig vom Header auf eine Anfrage reagiert HOST, sollte dies ebenfalls als unsicher angesehen werden. Siehe Wie sicher ist $ _SERVER ["HTTP_HOST"]? .
Siehe auch http://shiflett.org/blog/2006/mar/server-name-versus-http-host .

‡ Siehe 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

Völlig beliebige benutzerdefinierte Werte

Diese Werte werden überhaupt nicht überprüft und hängen nicht von einer Serverkonfiguration ab. Es handelt sich um völlig willkürliche Informationen, die vom Client gesendet werden.

  • 'argv', 'argc'(gilt nur für CLI-Aufrufe, normalerweise nicht für Webserver)
  • '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' (kann verdorbene Daten enthalten)
  • 'PHP_SELF' (kann verdorbene Daten enthalten)
  • 'PATH_TRANSLATED'
  • jeder andere 'HTTP_'Wert

§ Kann als zuverlässig angesehen werden, solange der Webserver nur bestimmte Anforderungsmethoden zulässt.

‖ Kann als zuverlässig angesehen werden, wenn die Authentifizierung vollständig vom Webserver durchgeführt wird.

Das Superglobal $_SERVERenthält auch mehrere Umgebungsvariablen. Ob diese "sicher" sind oder nicht, hängt davon ab, wie (und wo) sie definiert sind. Sie können von vollständig servergesteuert bis vollständig benutzergesteuert reichen.

täuschen
quelle
3
@Rook Aber wie gesagt, es kommt absolut darauf an, wie man es benutzt . Werte allein sind weder sicher noch unsicher, es hängt davon ab, wofür Sie sie verwenden . Selbst Daten, die von einem schändlichen Benutzer gesendet werden, sind absolut sicher, solange Sie nichts damit tun, was Ihre Sicherheit gefährden könnte.
Täuschung
2
@Rook: Ihre Vorstellung von "sicher" lässt diese Frage etwas willkürlich erscheinen, zumal sie vollständig an eine obskure Erweiterung oder benutzerdefinierte Version von PHP gebunden ist. Während Sie sagen, "sollte keinen" Shoot from the Hip "-Ansatz haben", scheint jede Antwort tatsächlich mindestens eine Vertrautheit mit dem PHP-Quellcode zu erfordern, um herauszufinden, wie diese Werte eingestellt werden. Wäre es nicht besser, PHP-Entwickler per E-Mail zu kontaktieren, um eine Antwort zu finden?
Bob-the-Zerstörer
2
@Rook: Missverständnisse. Wie Täuschung andeutete, "sicher für welchen Zweck". Wie ich bereits angedeutet habe, ist Ihr Zweck unbekannt, und außerdem gibt es mehrere andere undokumentierte $_SERVERWerte, je nachdem, wie die Datei bereitgestellt wird. Meiner Meinung nach klären die dokumentierten nicht die wahre Quelle. Sonst würden Sie diese Frage wohl nicht stellen. Ich bin froh, dass du eine Liste hast, die du verwenden kannst. Ich würde dennoch empfehlen, einen Fehlerbericht einzureichen (wenn die Fehler-Site behoben ist), den Dokumentbetreuern eine E-Mail zu senden oder die Dokumente selbst zu aktualisieren (wenn Sie mit dem Link vertraut sind). Es wäre für die Community von Vorteil, diese Informationen zu kennen.
Bob-the-Zerstörer
3
SERVER_NAMEwird nicht unbedingt vom Server gesteuert. Abhängig vom Gateway und den Einstellungen kann es dupliziert werden HTTP_HOSTund unterliegt daher derselben Einschränkung.
Bobince
1
@deceze @Rook Braucht SERVER_PORTdas kleine Kreuz? bugs.php.net/bug.php?id=64457
Dejan Marjanović
12

In PHP kann jede $_SERVERVariable, die mit beginnt HTTP_, vom Benutzer beeinflusst werden. Zum Beispiel kann die Variable $_SERVER['HTTP_REINERS']beschädigt werden, indem der HTTP-Header REINERSin der HTTP-Anforderung auf einen beliebigen Wert gesetzt wird.

Reiners
quelle
re "willkürlich"; Nicht ganz willkürlich, da sie einem Format entsprechen. Zum Beispiel $_SERVER['HTTP_REINERS'] enthalten , können nicht Zeilenumbrüche unter den meisten SAPIs.
Pacerier