it-swarm.com.de

Ist $ _SERVER [] eine sichere Datenquelle in PHP?

Kann ich mich zu 100% darauf verlassen, dass $_SERVER[] Eine sichere Datenquelle ist, die ich nicht wie $_GET[] Und $_POST[] Bereinigen muss?

29
user2079272

Dies geht aus einer meiner Fragen zum Stapelüberlauf hervor: Welche $ _SERVER-Variablen sind sicher?

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'

* Das REMOTE_ Werte sind garantiert die gültige Adresse des Clients, wie durch einen TCP/IP-Handshake überprüft. Dies ist die Adresse, an die eine Antwort gesendet wird. REMOTE_Host stü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 auf eine Anfrage unabhängig vom Header Host antwortet, 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 .

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 fehlerhafte Daten enthalten, d. h. /index.php/evilstring)
  • 'PATH_TRANSLATED'
  • jedes 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.

Der Superglobale $_SERVER enthä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.

44
rook

Kann ich mich zu 100% darauf verlassen, dass $ _SERVER [] eine sichere Datenquelle ist, die ich nicht wie $ _GET [] und $ _POST [] bereinigen muss?

Ihre Frage zeigt sofort einen Fehler an. Alle Eingabequellen müssen bereinigt werden. Eingaben werden nicht nur als Kanäle betrachtet, die der Benutzer direkt steuern kann, sondern als alle Datenquellen außerhalb Ihrer Anwendung.

Stellen Sie sich das so vor: Ihre Anwendung bietet zwei Möglichkeiten, Daten abzurufen: Informationen, die in Ihrer Anwendung fest codiert sind, und Eingaben. Selbst wenn es von einem anderen Programm auf demselben System generiert wird, wird es dennoch in Ihr Programm eingegeben.

Die allgemeine Redewendung Filter-In, Escape-Out Gilt nicht nur für Benutzereingaben, sondern für alles, was in Ihre Anwendung eintritt und diese verlässt.

Wenn es also in $_SERVER Ist, muss es gefiltert/bereinigt werden. Sie sollten sich niemals auf etwas verlassen, das in Ihrer Anwendung nicht fest codiert ist.

Warum ist das wichtig? Stellen Sie sich vor, Sie filtern alle Eingaben des Benutzers, vertrauen dann aber den Daten, die aus Ihrer Datenbank stammen. Wenn ich eine Lücke in Ihrer Filterung ausnutzen kann, kann ich Daten einfügen, die dann vertrauenswürdig werden. Dies kann zu XSS oder SQLi zweiter Ordnung führen. Wenn Sie jedoch alles filtern, was in Ihre Anwendung eingeht, unabhängig davon, woher es kommt, sind Sie in Sicherheit!

Also nein, Sie können sich niemals zu 100% auf irgendetwas in $_SERVER, $_GET, $_POST, $_COOKIE, $_REQUEST, $_ENV, $argc, $argv, Aus Ihrer Datenbank, aus dem Dateisystem (abgesehen von Ihrem versionierten Code) usw.

14
ircmaxell

Überhaupt keine dumme Frage!

Viele (aber nicht alle) der $ SERVER-Variablen werden vom Benutzerbrowser übergeben (oder können vom Benutzer beeinflusst werden), z. B. QUERY_STRING, REQUEST_URI und alle HTTP_ * -Variablen.

Sogar die Variable REMOTE_ADDR kann mit Raw-Sockets gefälscht werden (allerdings nur mit gültigen IPs, soweit mir bekannt ist).

Ich würde ihnen allen aus guten politischen Gründen entkommen.

http://php.net/manual/en/reserved.variables.server.php

6
GBC

Es gibt keine "sichere Datenquelle". Sie sollten immer sicherstellen, dass die Daten das richtige Format haben, wenn Sie sie an etwas anderes weitergeben.

Wenn Sie in einer durch Apostroph (') getrennten Zeichenfolge [1] in SQL ausgeben, sollten Sie Apostrophe (oder alles andere, was die Zeichenfolge möglicherweise ausbricht) maskieren. Wenn Sie eine durch Javascript-Apostroph getrennte Zeichenfolge [2] ausgeben, sollten Sie sowohl HTML als auch Apostrophe maskieren. Es hängt alles davon ab, auf was Sie ausgeben. Eine absolut sichere Zeichenfolge kann das Zielskript beschädigen, auch wenn dies nicht böswillig ist. (Wenn es jedoch kaputt gehen kann, kann es oft auch ausgenutzt werden.)

[1] Beispiel: $db->query("SELECT * FROM users WHERE name = '$username'");
[2] Beispiel: <script>alert('Hi <?php echo $username;?>');</script>

Ich habe in meinem Blog darüber gesprochen, obwohl es in meinem Beitrag speziell um XSS geht. Ich denke, dass das gleiche Prinzip auch hier gilt: Was ist XSS und wie schützt man Ihre Website .

Wenn Sie nicht wissen, dass PHP selbst bereits ein bestimmtes Format erzwingt und Sie sich dessen fast nie sicher sein können, können Sie alles als unsicher betrachten. IP-Adressen haben normalerweise das Format xxxx, können es aber auch x: x: x: x: x: x: x: x für IPv6 oder sogar 0: 0: 0: 0: 0: ffff: xxxx für IPv4-Ziele in IPv6-Paketen. Wenn Sie sich dessen nicht bewusst sind, es kann zu einigen sehr interessanten Fehlern führen.

Jetzt wird eine IP-Adresse niemals ein Apostroph enthalten, oder? Nun, es gibt Leute, die nach dem Header $ _SERVER ["HTTP_X_FORWARDED_FOR"] suchen, bevor sie die Remote-Adresse verwenden. Dies ist großartig, solange der Header korrekt gesetzt ist (wie auch von @Ladadadada in einem Kommentar zur Antwort von @ GBC hervorgehoben), aber das kann auch eine Parodie sein. Wenn Sie dann die Daten verwenden, die andere in der Datenbank gespeichert haben, erhalten Sie möglicherweise böswilliges Material zurück ... Vertrauen Sie also am Ende niemals der Eingabe. Sichern Sie es besser zu sehr, als es einmal zu vergessen.

3
Luc