Moin Moin!
Umfeld: Konsole. Wenn ich es dort "beherrsche" wird es umgebaut auf den CGI-Betrieb.
Das sind zwei durchaus unterschiedliche Umgebungen. Das fängt schon damit an, dass Dein CGI nur exakt eine einzige Eingabe zu sehen bekommt, danach gibt es eine Antwort aus, und danach wird der Prozess beendet. Sämtliche Status-Informationen, die Du im CGI-Prozess hattest, sind WEG. Außerdem kann es durchaus vorkommen, dass zwei oder mehr Instanzen des CGIs teilweise parallel laufen und sich im schlimmsten Fall gegenseitig sabotieren.
Ich kann nur HTML und CSS und damit lassen sich solche Probleme nicht lösen.
Mehr nicht? Kein Basic, C, Javascript?
Aber ich habe es mir in Perl in etwa so gedacht.
Aufgabe: Ich möchte eine Eingabe machen, die Eingabe führt einen Befehl aus (bspw. etwas in eine Datei schreiben). Nach der Eingabe darf für 30 sekunden keine weitere Eingabe mehr einen Befehl ausführen. Nach den 30 Sekunden wiederholt sich das.
Für ein dummes Konsolenprogramm:
1. Eingabe lesen
2. Eingabe verarbeiten
3. Ergebnis ausgeben
4. 30 Sekunden warten, ohne auf Eingaben zu reagieren oder etwas auszugeben
5. Weiter mit Schritt 1.
Für ein CGI FUNKTIONIERT DAS NICHT, jedenfalls nicht auf diese Art.
Das was ich will haben viele Gästebuch/Foren als Spamschutz eingebaut.
Die Beschränkung ist unsinnig, denn sie läßt sich trivial umgehen. Es sei denn, Du blockierst das gesamte Script für 30 Sekunden. Dann läßt sich noch viel trivialer ein Denial of Service auf das Script starten: Einfach alle 30 Sekunden eine minimale Eingabe vortäuschen und schon kann NIEMAND mehr das Script benutzen.
Meine momentane Lösung sieht folgendermaßen aus:
Eingabe wird erstellt. Zeit wird mittels if-Abfrage verglichen ($time) mit der zeit in 30 sekunden($time+30). Die Eingabe wird getätigt und $time+30 als Zahl in einer externen Datei ($dateizeit) gespeichert.
Welchen Locking-Mechanismus benutzt Du, um zu verhindern, dass ein paralleler Prozess die Datei überschreibt?
Danach sollte geprüft werden ob $time < $dateizeit ist. Ist $time kleiner als $dateizeit dürfen zwar Eingaben getätigt werden, jedoch nichts ausgeführt werden (else-Antwort).
Eingabe, Verarbeitung und Ausgabe sind in einem CGI zwingend eine Einheit. Du mußt das komplette CGI im Falle eines Falles sperren, sprich: Es muß eine Fehlermeldung ausgeben.
Nach 30 Sekunden ist logischerweise $time größer als $dateizeit und es kann wieder von neu beginnen wobei $time+30 bei jeder erneuten Eingabe den Wert in $dateizeit überschreibt/speichert.
Du beschreibst die DoS-anfällige Variante.
Meine gewünschte Lösung:
$time+30 sollte lokal gespeichert werden. Also meine bisherige Lösung so umschreiben das ich dazu keine externe Datei brauche.
Was meinst Du mit "lokal"?
Im Browser? Lächerlich, den kontrolliert der Angreifer. Benutzt Du Cookies, werden Cookies ausgeschaltet oder gefiltert. Benutzt Du Javascript, wird Javascript ausgeschaltet, gefiltert oder schlicht simuliert. Benutzt Du ein Plugin (Flash, Java, ...), wird es ausgeschaltet, seine Ein- und Ausgaben gefiltert oder sein Verhalten simuliert. Benutzt Du versteckte Formular-Elemente, werden die gefälscht, gefiltert oder blockiert.
Deine einzige Chance ist, auf dem Server zu arbeiten. Wenn Du nicht direkt in eine Datei schreiben willst, schreib in eine Datenbank. Andere Möglichkeiten hast Du nicht.
Deine 30-Sekunden-Sperre scheitert an der Realität. Du willst einen bestimmten Benutzer daran hindern, im Abstand von weniger als 30 Sekunden Daten an Dein CGI zu schicken. Dein Problem ist, dass es mit HTTP absolut unmöglich ist, einen Benutzer sicher zu identifizieren. Du kannst bestenfalls auf Kooperation seitens des Browsers hoffen, für jeden Benutzer eine Session einrichten, und verhindern, dass innerhalb von 30 Sekunden zwei Requests von einer Session abgearbeitet werden.
Aber nichts und niemand hindert einen Angreifer, mehrere Sessions parallel zu benutzen oder die Session sofort nach dem ersten Request zu beenden.
Alexander
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".