Ich habe viel gesucht und auch die PHP $ _SERVER-Dokumente gelesen . Habe ich dieses Recht, was ich für meine PHP-Skripte für einfache Linkdefinitionen verwenden soll, die auf meiner Website verwendet werden?
$_SERVER['SERVER_NAME']
basiert auf der Konfigurationsdatei Ihres Webservers (in meinem Fall Apache2) und hängt von einigen Anweisungen ab: (1) VirtualHost, (2) Servername, (3) UseCanonicalName usw.
$_SERVER['HTTP_HOST']
basiert auf der Anfrage des Kunden.
Daher scheint es mir die richtige zu sein, um meine Skripte so kompatibel wie möglich zu machen $_SERVER['HTTP_HOST']
. Ist diese Annahme richtig?
Follow-up-Kommentare:
Ich glaube, ich wurde ein wenig paranoid, nachdem ich diesen Artikel gelesen und festgestellt hatte, dass einige Leute sagten "sie würden keinem der $_SERVER
Vars vertrauen ":
http://markjaquith.wordpress.com/2009/09/21/php-server-vars-not-safe-in-forms-or-links/
http://php.net/manual/en/reserved.variables.server.php#89567 (Kommentar: Vladimir Kornea 14-Mar-2009 01:06)
Anscheinend geht es in der Diskussion hauptsächlich darum, $_SERVER['PHP_SELF']
warum Sie es nicht im Formularaktionsattribut verwenden sollten, ohne ordnungsgemäß zu entkommen, um XSS-Angriffe zu verhindern.
Meine Schlussfolgerung zu meiner ursprünglichen Frage oben lautet, dass die Verwendung $_SERVER['HTTP_HOST']
für alle Links auf einer Website "sicher" ist, ohne dass Sie sich über XSS-Angriffe Gedanken machen müssen, selbst wenn diese in Formularen verwendet werden.
Bitte korrigieren Sie mich, wenn ich falsch liege.
$_SERVER['SERVER_NAME']
und$_SERVER['HTTP_HOST']
(abgesehen von der Implementierung eines anderen benutzerdefinierten Handshakes basierend auf der Benutzeranforderung). Pro-Entwickler vertrauen den Dingen nicht, die sie nicht vollständig verstehen. So sie entweder ihre SAPI haben Setup richtig perfekt (in diesem Fall die Möglichkeit , sie verwenden wird das richtige Ergebnis geben), oder sie werden so tun , dass Whitelisting es egal, was die SAPI Versorgungswerte.array_key_exists
ist skalierbarer Vergleich zuin_array
diesem hat O (n) Leistung.Nur ein zusätzlicher Hinweis: Wenn der Server auf einem anderen Port als 80 ausgeführt wird (wie dies auf einem Entwicklungs- / Intranetcomputer üblich ist),
HTTP_HOST
enthält er den Port, währendSERVER_NAME
dies nicht der Fall ist.(Zumindest ist mir das bei Apache-Port-basierten virtuellen Hosts aufgefallen.)
Wie Mike unten bemerkt hat,
HTTP_HOST
ist nicht enthalten ,:443
wenn auf HTTPS läuft (es sei denn , Sie auf einem Nicht-Standard - Port laufen lassen , die ich nicht getestet).quelle
HTTP_HOST
ist nicht genau derHost:
Parameter, den der Benutzer angegeben hat. Es basiert lediglich darauf.Benutze das eine oder das andere. Sie sind beide gleich (in) sicher, da SERVER_NAME in vielen Fällen ohnehin nur aus HTTP_HOST ausgefüllt wird. Normalerweise gehe ich zu HTTP_HOST, damit der Benutzer auf dem genauen Hostnamen bleibt, auf dem er begonnen hat. Wenn ich beispielsweise dieselbe Site auf einer .com- und .org-Domain habe, möchte ich niemanden von .org an .com senden, insbesondere wenn er möglicherweise Login-Token auf .org hat, die er verlieren würde, wenn er an gesendet wird die andere Domain.
In jedem Fall müssen Sie nur sicherstellen, dass Ihre Webanwendung immer nur für bekanntermaßen gute Domains reagiert. Dies kann entweder (a) mit einer anwendungsseitigen Prüfung wie der von Gumbo oder (b) mit einem virtuellen Host für die gewünschten Domänennamen erfolgen, der nicht auf Anforderungen reagiert , die einen unbekannten Host-Header enthalten.
Der Grund dafür ist, dass Sie, wenn Sie zulassen, dass auf Ihre Site unter einem alten Namen zugegriffen wird, DNS-Rebinding-Angriffen ausgesetzt sind (wenn der Hostname einer anderen Site auf Ihre IP verweist, greift ein Benutzer mit dem Hostnamen des Angreifers und dann mit dem Hostnamen auf Ihre Site zu wird auf die IP des Angreifers verschoben, wobei Ihre Cookies / Authentifizierung mitgenommen werden) und Suchmaschinen-Hijacking (wobei ein Angreifer seinen eigenen Hostnamen auf Ihre Site verweist und versucht, Suchmaschinen dazu zu bringen, ihn als den "besten" primären Hostnamen zu betrachten).
Pfft. Nun, Sie sollten in keinem Attribut etwas verwenden , ohne damit zu entkommen , daher sind Servervariablen dort nichts Besonderes.
htmlspecialchars($string, ENT_QUOTES)
quelle
attacker.com
als die beste primäre Quelle für die IP Ihres Servers ansehen kann " bedeutet? Für Suchmaschinen scheint das nichts zu bedeuten. Was wird das überhaupt tun?http://example.com/
isthttp://www.example.com/
undhttp://93.184.216.34/
diese zu einer Website kombiniert, wählen Sie die beliebteste der Adressen aus und geben Sie nur Links zu dieser zurück Ausführung. Wenn Sieevil-example.com
auf dieselbe Adresse zeigen und Google kurz darauf hinweisen könnten, dass Sie als beliebteste Adresse den Saft der Website stehlen könnten. Ich weiß nicht, wie praktisch das heute ist, aber ich habe in der Vergangenheit russische Angreifer von Linkfarmen gesehen, die versucht haben, dies zu tun.Dies ist eine ausführliche Übersetzung dessen, was Symfony verwendet, um den Hostnamen zu erhalten ( eine wörtlichere Übersetzung finden Sie im zweiten Beispiel ):
Veraltet:
Dies ist meine Übersetzung einer im Symfony-Framework verwendeten Methode in nacktes PHP, die versucht, den Hostnamen in der Reihenfolge der besten Vorgehensweisen auf jede mögliche Weise abzurufen:
quelle
if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
oder zu lesenx = a == 1 ? True : False
. Als ich es zum ersten Mal sah, suchte mein Gehirn nach einer $ Host-Instanziierung und einer Antwort für "Warum ist nur ein" = "Zeichen?". Ich fange an, schwache Schreibprogrammiersprachen nicht zu mögen. Alles ist anders geschrieben. Sie sparen keine Zeit und sind nichts Besonderes. Ich schreibe keinen Code auf diese Weise, weil ich nach Ablauf der Zeit derjenige bin, der ihn debuggen muss. Sieht für ein müdes Gehirn wirklich chaotisch aus! Ich weiß, dass mein Englisch Englisch ist, aber zumindest versuche ich es.Ja, es ist sicher zu verwenden
$_SERVER['HTTP_HOST']
(und sogar$_GET
und$_POST
) , solange Sie sie überprüfen, bevor Sie sie akzeptieren. Folgendes mache ich für sichere Produktionsserver:Der Vorteil von
$_SERVER['HTTP_HOST']
ist, dass sein Verhalten klarer definiert ist als$_SERVER['SERVER_NAME']
. Kontrast ➫➫ :mit:
Die Verwendung einer besser definierten Schnittstelle wie
$_SERVER['HTTP_HOST']
bedeutet, dass mehr SAPIs diese mithilfe eines zuverlässigen, genau definierten Verhaltens implementieren . (Im Gegensatz zu den anderen .) Es ist jedoch immer noch vollständig SAPI-abhängig ➫➫ :Um zu verstehen, wie der Hostname ordnungsgemäß abgerufen wird, müssen Sie in erster Linie verstehen, dass ein Server, der nur Code enthält, keine Möglichkeit hat, seinen eigenen Namen im Netzwerk zu kennen (Voraussetzung für die Überprüfung) . Es muss mit einer Komponente verbunden sein, die ihm einen eigenen Namen gibt. Dies kann erfolgen über:
lokale Konfigurationsdatei
lokale Datenbank
fest codierter Quellcode
externe Anfrage ( Curl )
Client / Angreifer-
Host:
Anfrageetc
Normalerweise erfolgt dies über die lokale Konfigurationsdatei (SAPI). Beachten Sie, dass Sie es richtig konfiguriert haben, z. B. in Apache ➫➫ :
quelle
Der Hauptunterschied zwischen beiden besteht darin, dass
$_SERVER['SERVER_NAME']
es sich um eine servergesteuerte Variable und$_SERVER['HTTP_HOST']
einen benutzergesteuerten Wert handelt.Die Faustregel lautet, niemals den Werten des Benutzers zu vertrauen, daher
$_SERVER['SERVER_NAME']
ist dies die bessere Wahl.Wie Gumbo betonte, erstellt Apache SERVER_NAME aus vom Benutzer angegebenen Werten, wenn Sie dies nicht festlegen
UseCanonicalName On
.Bearbeiten: Wenn die Site einen namenbasierten virtuellen Host verwendet, ist der HTTP-Host-Header der einzige Weg, um Sites zu erreichen, die nicht die Standard-Site sind.
quelle
Host:
Wert vertrauen , es sei denn, Sie haben ihn bereits manuell oder über das Setup Ihres SAPI überprüft .Ich bin mir nicht sicher und vertraue nicht wirklich,
$_SERVER['HTTP_HOST']
da dies vom Header des Clients abhängt. Auf andere Weise, wenn eine vom Client angeforderte Domäne nicht meine ist, werden sie nicht auf meine Site gelangen, da das DNS- und das TCP / IP-Protokoll sie auf das richtige Ziel verweisen. Ich weiß jedoch nicht, ob es möglich ist, den DNS-, Netzwerk- oder sogar Apache-Server zu entführen. Um sicher zu gehen, definiere ich den Hostnamen in der Umgebung und vergleiche ihn mit$_SERVER['HTTP_HOST']
.Fügen Sie die
SetEnv MyHost domain.com
.htaccess-Datei im Stammverzeichnis hinzu und fügen Sie diesen Code in Common.php hinzuIch füge diese Common.php-Datei in jede PHP-Seite ein. Diese Seite führt alles aus, was für jede Anforderung erforderlich ist, z. B.
session_start()
Sitzungscookie ändern und ablehnen, wenn die Post-Methode aus einer anderen Domäne stammt.quelle
Host:
Wert direkt an die IP Ihres Servers ausgeben .XSS
wird immer da sein, auch wenn Sie verwenden$_SERVER['HTTP_HOST']
,$_SERVER['SERVER_NAME']
ODER$_SERVER['PHP_SELF']
quelle
Zunächst möchte ich mich bei Ihnen für all die guten Antworten und Erklärungen bedanken. Dies ist die Methode, die ich basierend auf all Ihren Antworten erstellt habe, um die Basis-URL zu erhalten. Ich benutze es nur in sehr seltenen Situationen. Daher liegt der Schwerpunkt NICHT auf Sicherheitsproblemen wie XSS-Angriffen. Vielleicht braucht es jemand.
quelle