Zur Navigation

Formulare absichern

zum zweiten

1 Ranma (Gast)

Um nur schnell etwas bei einem Webhoster hochladen zu können, habe ich ein Skript mit kaum mehr als einer Suchmaske erstellt. Weil nur gesucht und noch nichts eingetragen werden soll, sind nichtmal die Ansprüche an die Sicherheit besonders hoch. Wobei ein Formular aber immer Angriffsmöglichkeiten eröffnet. Deshalb habe ich ein verstecktes Eingabefeld eingebaut. Erstmal nur mit einem festem Wert:

<input type="hidden" name="AntiCSRF" value="Token"/><input type="text" name="search" maxlength="42"/>

Diese beiden INPUT-Felder folgen tatsächlich direkt aufeinander!

Dann frage ich natürlich ab:
if(isset($_POST['search'])and isset($_POST['AntiCSRF'])){...}

Natürlich ist die zweite Variable noch auf ihren Inhalt zu prüfen, aber der Teil ist im Moment auskommentiert, weil es hier schon nicht mehr klappt. Kommentiere ich das zweite isset() auch noch aus, dann funktioniert das Skript bereits. isset($_POST['AntiCSRF']) liefert also aus irgendeinem Grund FALSE. Aber ich sehe keinen Grund. Welcher Grund kann das sein?
Ranma

31.12.2015 06:35

2 Jörg Kruse

Aber ich sehe keinen Grund. Welcher Grund kann das sein?

Der Fehler liegt wohl außerhalb der angegebenen Codeabschnitte, denn damit allein lässt sich das Problem nicht reproduzieren.

Zum Debuggen kann man den Gesamt-Code nach und nach solange auf einen Kern zurechtstutzen, bis der Fehler verschwindet - dann hat man meist auch schon die Ursache. Andernfalls kann dann hier der Code gepostet werden, mit dem der Fehler noch reproduziert werden kann.

31.12.2015 18:12

3 Ranma (Gast)

Ich muß nur isset($_POST['AntiCSRF']) auskommentieren, damit es funktioniert. Also das Formular wird gezeigt und dann auch ein Ergebnis der Query ausgegeben und dann ist nur noch der HEAD-Teil der HTML-Ausgabe vorhanden und das war es auch schon. Weil die andere POST-Variable so oder so geliefert wird, kann es eigentlich weder am HTML noch am PHP liegen. CSS ist noch nicht eingebaut. Ich kann mir eigentlich nur noch obskure Konfigurationseinstellungen vorstellen. In dem Fall habe ich keinen Plan, wie ich so etwas finde....
Ranma

01.01.2016 03:07

4 Jörg Kruse

Mit den beiden Code-Zeilen, die du oben geliefert hast, kann man die angesprochenen Probleme nicht nachvollziehen. Die Fehler liegen also außerhalb. Um diese ausfindig machen zu können, braucht es entweder den Gesamt-Code, oder einen Beispiel-Code, der nur soweit reduziert ist, dass die Fehler damit noch reproduzierbar sind.

02.01.2016 15:11

5 Ranma (Gast)

Ja, ist seltsam. Aber mir ist inzwischen aufgefallen, daß ich den Teil eigentlich garnicht brauche? Jedenfalls nicht, so lange nur eine Datenbankabfrage gemacht werden soll. Eigentlich macht es keinen Unterschied, ob $_POST['search'] über mein Formular oder auf irgendeinem anderem Weg befüllt wird. Wenn ich weiter darüber nachdenke, dann hat ein Formular so ziemlich garnichts mit der Absicherung gegenüber Angriffen zu tun. Es ist eher eine Art Vorschlag, wie ein Benutzer die POST-Variablen befüllen könnte.

Wegen der Sicherheit muß ich etwas ganz anderes machen. Nur Eingaben wie '; oder "> müssen entschärft werden? Also htmlentities() und dann ist es nur noch fraglich, ob sich die nicht damit behandelten Datensätze so überhaupt noch finden lassen. Theoretisch dürften sich '; oder "> in der Datenbank befinden. Das könnte dann nie gefunden werden?
Ranma

04.01.2016 01:49

6 Jörg Kruse

$_POST['AntiCSRF']

CSRF wird von Angreifern genutzt, um Aktionen unter einem bestimmten Account ausführen zu lassen, die mit besondern Rechten ausgestattet sind. Zur Abwehr kann ein Token als hidden Value übermittelt werden, welches vom Angreifer nicht reproduziert werden kann, und welches z.B. in einer Session gespeichert wird, wo es vom überprüfenden Script ausgelesen werden kann.

Aber mir ist inzwischen aufgefallen, daß ich den Teil eigentlich garnicht brauche? Jedenfalls nicht, so lange nur eine Datenbankabfrage gemacht werden soll.

Wenn mit dem Formular nur gesucht werden soll, und jeder suchen darf, braucht man das nicht, ja.

Wegen der Sicherheit muß ich etwas ganz anderes machen. Nur Eingaben wie '; oder "> müssen entschärft werden?

Ich würde, wie an anderer Stelle bereits geschrieben, htmlspecialchars() nur in den HTML-Ausgaben anwenden (und dort natürlich konsequent)! bei der Such-Query kommst du dann ohne diese Funktion aus, da die Wörter in der Datenbank unmaskiert stehen.

04.01.2016 20:25 | geändert: 04.01.2016 20:38

7 Ranma (Gast)

Das heißt ich muß in punkto Sicherheit noch garnichts machen, solange nur gesucht werden kann?
Ranma

05.01.2016 02:20

8 Jörg Kruse

Die SQL-Queries müssen gegen SQL-Injection gesichert werden.

Und die Strings, die auf der Suchergebnisseite ausgegeben werden, müssen mit htmlspecialchars() behandelt werden. Das gilt dann sowohl für Strings, die aus der Datenbank geholt werden, als auch für Strings, die aus $_GET bzw. $_POST übernommen wurden (um z.B. den letzten Suchbegriff in die Überschrift oder als Vorausfüllung in das Eingabefeld zu schreiben)

Bei einer Suche würde ich übrigens method="get" verwenden, dann können Ergebnisseiten auch gebookmarkt werden und dann lässt sich ggf. auch eine Pagination einbauen (so wie auch bei Suche hier im Forum)

05.01.2016 17:30 | geändert: 05.01.2016 17:31

9 Ranma (Gast)

Also doch noch einiges zu tun. Solange eine Variable nicht ausgegeben wird, kann nichts passieren? Ich finde die Vorstellung etwas schwierig, daß man erst so ziemlich alles mit einer Variablen machen kann, sie sogar in einer Datenbank speichern, aber beim ausgeben, und wenn es nur auf einem Bildschirm ist, muß man plötzlich sehr vorsichtig sein...

Die SQL-Queries müssen gegen SQL-Injection gesichert werden.

Sämtliche Prepared Statements sollen doch immun gegen SQL-Injections sein, so daß diese Angriffsart der Vergangenheit angehört?

Bei einer Suche würde ich übrigens method="get" verwenden, dann können Ergebnisseiten auch gebookmarkt werden und dann lässt sich ggf. auch eine Pagination einbauen (so wie auch bei Suche hier im Forum)

Zwar würde ich nicht auf die Idee kommen, eine Wörterbuchabfrage zu bookmarken, aber das will ich auch niemandem verbieten. Also sollte ich es schon möglich machen. Das wirft allerdings ein Problem auf, von dem ich meinte, mich erst viel später damit beschäftigen zu müssen. Nämlich SEO. Wegen der Suchmaschinen soll man dynamische URLs vermeiden, also keine GET-Variablen einbauen.

Nun habe ich das versteckte Formularfeld aus meinem Formular herausgenommen. Seitdem wird das Eingabefeld nicht mehr angezeigt. Um das zu beheben, brauche ich wahrscheinlich nur das versteckte Feld wieder einzubauen. Erfreulich ist es nicht, wenn man das Verhalten seines eigenen Skriptes nicht vorhersagen kann. Anscheinend wird immer mindestens ein INPUT-Feld irgendwie verschluckt...
Ranma

06.01.2016 02:06

10 Jörg Kruse

Ich finde die Vorstellung etwas schwierig, daß man erst so ziemlich alles mit einer Variablen machen kann, sie sogar in einer Datenbank speichern, aber beim ausgeben, und wenn es nur auf einem Bildschirm ist, muß man plötzlich sehr vorsichtig sein...

htmlspecialchars() sichert eben nur die HTML-Ausgabe ab, also ist es sinnvoll, es auch nur dort anzuwenden.

Die SQL-Queries müssen gegen SQL-Injection gesichert werden.

Sämtliche Prepared Statements sollen doch immun gegen SQL-Injections sein, so daß diese Angriffsart der Vergangenheit angehört?

Wenn du durchgehend Prepared Statements verwendest, sicherst du die Queries damit gegen SQL-Injections ab. Es gibt etliche Webseiten, die nicht durchgehend gesichert sind, so dass es auch weiterhin Angriffsversuche gegen diesen Vektor geben wird.

06.01.2016 16:53 | geändert: 06.01.2016 16:53