2011-01-03 4 views
4

Ich muss ein Formular erstellen, die Aktion bringt Sie zurück auf die exakt gleiche Seite - GET-Parameter enthalten. Ich denke, ich etwas auf die Wirkung der sagen kann:

echo '<form action="'.$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING']. 
    '" method="post">' 

Dies scheint zu funktionieren, und Testen vorbei ein paar XSS-Angriffe scheint erfolgreich zu sein, wie die Ausgabe von QUERY_STRING scheint URL-kodiert zu sein. Die PHP documentation erwähnt dies jedoch nicht, daher bin ich nicht zuversichtlich, dass ich diesem Verhalten vertrauen kann.

Ist es sicher, QUERY_STRING so zu verwenden, wie ich oben bin? Wenn nicht, was kann ich stattdessen tun? Verweise auf die Dokumentation würden geschätzt werden.

Update wechselte zu SCRIPT_NAME, nur gemischt, welche war in Ordnung und was war schlecht in meinem Kopf, danke für mich zu fangen. action="" löst mein spezifisches Problem gut, aber ich bin immer noch neugierig, ob QUERY_STRING vorverarbeitet ist, so dass es sicher zu verwenden ist oder nicht, da es manchmal andere wollen Sie die Abfragezeichenfolge wiederverwenden, vorausgesetzt, es ist sicher zu tun damit.

+0

Nehmen Sie nie an. Du weißt nie, was diese Gauner sich ausdenken können! – BoltClock

+0

Natürlich nicht :) das sind die Rohwerte aus der URI – RobertPitt

+1

Wenn Sie Benutzer zurück zur gleichen Seite senden möchten, müssen Sie nicht einmal angeben, welche Aktion ... – ajreal

Antwort

7

Sie sollten niemals $ _SERVER ['QUERY_STRING'] vertrauen, da es für XSS-Angriffe verwendet werden kann.

In Ihrem Fall könnte man die Verwundbarkeit mit Exploit:

http://your.server.com/your_script.php?"><script>alert(111);</script> 

Beachten Sie, dass der Code oben auf IE arbeitet; FireFox und Chrome codieren die Abfragezeichenfolge effizient, bevor sie an den Webserver gesendet werden.

Ich würde es immer mit htmlentities (beachten Sie den Parameter double_encode) wie bei jeder Benutzereingabe umbrechen.

Viel Glück!

+0

Danke,/das/ist, was ich gefragt habe. Wir können der Variablen nicht trauen, da ihre Inhalte vom Browser abhängig sind, also ausgezeichnet. – dimo414

+1

+1 Bitte beachten Sie die wichtigen Informationen. Es ist nicht so, dass du die Daten nicht * benutzen * kannst; es ist nur, dass du es nicht * vertrauen * kannst :) –

1

Als Erstes können Sie $ _SERVER ['PHP_SELF'] nicht vertrauen (1) - verwenden Sie stattdessen $ _SERVER ['SCRIPT_NAME'].

Wie für $ _SERVER ['QUERY_STRING'], sollten Sie es wie jede andere Benutzereingabe behandeln. Filtern Sie es, bevor Sie es in Ihrer Ausgabe verwenden. Ich würde in diesem Fall keine Art von allgemeinem Filter empfehlen. Es wäre besser, die Abfragezeichenfolge aus bestimmten Stücken zusammenzusetzen, die Sie dort erwarten.

1

Wenn es von XSS ausgenutzt werden kann, müssen Sie zuerst wissen, welcher Angriff. In dem Code, der hier gepostet wird, gibt es nur einen simple attack, der PHP_SELF verwendet.

Aber, um jedes Problem zu vermeiden, könnten Sie einfach die Formularaktion in leer lassen. Dadurch wird das Formular an die gleiche Seite einschließlich der Abfragezeichenfolge gesendet.

0

Ich kann nicht an irgendwelche Angriffe denken, die off-hand arbeiten würden, aber PHP_SELF selbst ist anfällig und Sie verwenden QUERY_STRING ohne jegliche Filterung, was seltsam scheint.

Warum lassen Sie nicht einfach den action Parameter leer und lassen Sie den Browser entscheiden? Sie können Javascript verwenden, um dieses Verhalten auf der Clientseite ordnungsgemäß zu erzwingen, wenn Sie doppelt sicher sein möchten.

0

Dies ist ein weiterer dieser Fälle, wo PHPs filter_input ist der Weg zu gehen. Meine IDE NetBeans (hasse es oder liebe es) beschwert sich immer, wenn ich Code öffne, der auf $_POST, $_GET, $_SERVER und $_COOKIE direkt zugreift, ohne filter_input durchzugehen.

Dies ist aus den oben genannten Gründen - Sie sagen, dass Sie externe Daten vertrauen, wenn, wenn es von Benutzern eingegeben oder manipuliert werden kann, können Sie nicht. Lesen

filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT); 
filter_input(INPUT_SERVER, 'QUERY_STRING', FILTER_SANITIZE_STRING); 
filter_input(INPUT_POST, 'another_field'); 

mehr here

Verwandte Themen