2010-04-05 6 views
5

Ich habe ein PHP-Skript, das den HTTP-Referer überprüft.

if ($_SERVER['HTTP_REFERER'] == 'http://www.example.com/') {...} 

Dies scheint jedoch inherintly unsicher ... weil das, was passiert, wenn der Benutzer zu 'http://example.com/' oder 'http://www.ExaMple.com' geht (die beide nicht den Gleichheitstest entsprechen).

Frage: Was ist ein besserer Gleichheitstest, um sicherzustellen, dass der HTTP Referer von 'example.com' kommt?

+0

Sind Sie es für die Verteidigung mit? Wie kann es helfen? –

+0

Es ist nur eine erste Verteidigungslinie (vor allem, wenn ich weiß, dass der Referer gefälscht werden kann). Es schützt zwar nichts Sicheres, aber gleichzeitig möchte ich nicht, dass Leute meinen Webservice missbrauchen, indem sie ihn direkt anrufen. Es ist mehr dazu gedacht, die Leute halbwegs ehrlich zu halten. – Hank

+0

Ein Benutzer kann den http_referer mithilfe von Manipulationsdaten steuern. Der Referer kann jedoch nicht "gefälscht" werden, um in einem CSRF-Angriff verwendet zu werden. – rook

Antwort

1

Obligatorische Antwort: HTTP_REFERER kann gefälscht werden, daher gibt es keine Möglichkeit, 100% sicher zu sein, dass jemand von einer bestimmten Website kommt.

Wenn Sie sich jedoch darauf verlassen möchten, können Sie eine Regex verwenden, um im HTTP_REFERER nach "example.com" zu suchen. stristr() würde auch funktionieren, und würde wahrscheinlich empfohlen werden, da es schneller als eine Regex wäre. Es ist auch hier unempfindlich so wäre es „ExaMple.com“ sowie ‚example.com“.

+0

Ich weiß, danke. Aber das ist nicht die Frage. – Hank

+0

(Es ist immer noch eine anständige erste Verteidigungslinie, aber danke dafür, es unabhängig zu erwähnen) – Hank

+1

aber würde nicht * stristr * auch auf "notmyExample.com" übereinstimmen, was unerwünscht wäre? – Hank

1

Hoffe es wichtig für alles, was nicht überprüfen lassen.

Sie können parse_url() Funktion verwenden, erhalten Teil Host-Name und überprüfen, ob HTTP_REFERER tatsächlich eine uRL enthalten.
Sie auch www nur substr können. von Hostnamen.
Groß- und Kleinschreibung ist nicht wichtig, wie es immer klein ist

oder einen regulären Ausdruck verwenden.

0
if (strtolower($_SERVER['HTTP_REFERER']) == 'http://www.example.com/') {...} 

Wie wäre es ...

$parts = explode('/',$_SERVER['HTTP_REFERER']); 
if (in_array('example.com',$parts) || in_array('www.example.com',$parts)) {...} 
+1

Nicht sicher, dass dies die ganze Zeit funktioniert, weil das 1) einen Schrägstrich, 2) das "www" annimmt. anstelle des Benutzers vorhanden ist, der direkt zu http://example.com geht – Hank

+0

URLs sollten immer kanonisiert werden, d. h. sekundäre Domäne zu primäre Domäne umleiten (wenn mehrere Domänen verwendet werden). http://en.wikipedia.org/wiki/Canonicalization – jholster

+0

@Hank - Überprüfen Sie meine Antwort noch einmal ... –

3

parse_url() mit etwas Schnur Jonglieren kombiniert sollte das tun, was Sie wollen. Versuchen Sie folgendes:

$url = parse_url($_SERVER['HTTP_REFERER']); 
//take the last two 'dot segments' of the host 
$hostOnly = implode('.',array_slice(explode('.',$url['host']),-2)); 
if (strtolower($hostOnly) == 'example.com') { 
    //stuff 
} 

Beachten Sie, dass parse_url() kann auf schlecht gebildet URLs ausfallen, so dass Sie sicher sein möchten vielleicht die Überprüfung einige Fehler hinzufügen. HTTP_REFERER könnte leicht mit Müll gefüllt werden.

0

einen regulären Ausdruck verwenden, würde dies

werden
if(preg_match("%(http://)?(www\.)?example\.com(/)?%i",$_SERVER['HTTP_REFERER'])) { ... } 
Verwandte Themen