Hallo, ich erstelle gerade ein Webprojekt mit Datenbank und da kam die Frage auf, wie man üblicherweise verhindert, dass ein User die Datenbank nicht flutet. Beispielweise könnte jemand ja einfach ein Skript schreiben, dass alle 100ms einen Datensatz von 100kb einträgt und damit die Datenbank sinnlos füllt. Merkt der Admin das 1 Tag nicht, wäre die Datenbank in 24h dann 86GB größer und man hat die Arbeit das wieder aufzuräumen. Das Problem müssten doch viele habe und deshalb muss es da doch einen Standard-Weg geben, um sowas zu verhindern. Bieten Frameworks wie zum Beispiel Laravel bei PHP so etwas schon im Kern? Pepe
Interessante Frage. Das ist eine der Fragen, die sich "normale" Softwareentwickler nicht stellen. Klar ist auch, dass das ein echtes Problem ist, denn eine derart aufgeblähte Datenbank wird langsam. Ich sehe aber rein technisch schon keinen einfachen Weg das zu verhindern. Angenommen, eine Applikation lässt Benutzerregistrierungen oder unregistrierte Postings zu, dann könnte man maximal etwas auf Basis der IP Adresse realisieren. Die ist aber in Zeiten von IPv4 Knappheit alles andere als verlässlich. Wer dagegen seine Benutzer kennt, hat das Problem wahrscheinlich eher nicht. Insgesamt scheint das in der Praxis derzeit kein relevantes Problem zu sein. Möglicherweise auch deshalb, weil DDoS Angriffe viel einfacher und billig zu haben ist. Es gibt Möglichkeiten Rate Limits für Datenbankverbindungen zu implementieren. Da leiden dann aber sofort alle Nutzer drunter. Ist also auch keine echte Lösung.
Wenn ich eine solche Überschrift lese... jemand such eine "Web-Technologie".... von welchem Ministerium bist du? Bestimmt vom Zukunfts-Innovations-Ministerium für Ferndatendirektverarbeitung Deutschlands. Einfach mal Hirn einschalten, dann kommt der Rest von selbst. Sowas banales....
Pepe_Ku schrieb: > Beispielweise könnte jemand ja einfach ein Skript schreiben, dass alle > 100ms einen Datensatz von 100kb einträgt und damit die Datenbank sinnlos > füllt. Merkt der Admin das 1 Tag nicht, wäre die Datenbank in 24h dann > 86GB größer und man hat die Arbeit das wieder aufzuräumen. Warum kann denn da jeder einfach so über das Web in dieser Rate solche Datensätze anlegen?
Pepe_Ku schrieb: > Das Problem müssten doch viele habe und deshalb muss es da doch einen > Standard-Weg geben, um sowas zu verhindern. Der erste Weg liegt in der Überwachung der Systeme und entsprechender Benachrichtigung. Hier also mindestens vom Plattenplatz des Servers, um möglichst rechtzeitig reagieren zu können.
Standard ist Festplatte Kontingentierung (quota} und Überwachung des Dienstes sowie der Limits, auch vor dem Erreichen der Limits. Framework war früher in perl geschrieben, CGI+Cron+smtp. Für Win gibt es einen entsprechenden Service und SMTP exe. Welcher professionelle Hoster betreibt denn eine DB bzw Nas ohne Quotas und ohne Netzwerkdrosselung?
Pepe_Ku schrieb: > Das Problem müssten doch viele habe und deshalb muss es da doch einen > Standard-Weg geben, um sowas zu verhindern. Bieten Frameworks wie zum > Beispiel Laravel bei PHP so etwas schon im Kern? Nein, aber Hirn 1.0 bietet das. Was ist an maximal n Einträge je Benutzer pro /Tag/Stunde/whatever so schwer umzusetzen?
Ideal ist in solchen Fällen ein "Leaky Bucket Filter". Gedankenmodell ist hier ein Eimer (mit einer bestimmten Größe), der mit einer bestimmten festen Rate nachgefüllt wird. Wenn dann ein Datensatz angelegt werden soll entnimmt man ein Token aus dem Eimer bis der leer ist. Man kann sich aussuchen, was der Eimerinhalt repräsentiert. Ein Token im Eimer kann z.B. für einen ganzen Datensatz stehen oder für einzelne Bytes. Leere Eimer sollten ins Log, und darauf basierend kann man dann ggf. Alerting machen. Dann macht man mehrere dieser Limits: z.B. ein Limit pro User, pro IP und allgemein oder pro Anwendungsbereich. In der Implementierung persistiert man natürlich nur nicht-leere Eimer. Wenn Leaky-Bucket zu kompliziert ist kann man auch einfach stumpf zählen und harte Limits vorgeben, und die Zähler zyklisch resetten.
Pepe_Ku schrieb: > Beispielweise könnte jemand ja einfach ein Skript schreiben, dass alle > 100ms einen Datensatz von 100kb einträgt und damit die Datenbank sinnlos > füllt. Das klingt nach dem ersten Problem bei deinem Design, nicht jeder sollte alles in deine Datenbank eintragen dürfen. Wenn ich deine Datenbank mit ein Script massieren darf, wäre meine Intention aber auch nicht der flood, sondern die SQL Injektion. Die meisten Benutzer verwenden den gleichen Datensatz immer wieder, das ist doch viel wertvoller als den Admin zu ärgern und vielleicht, kann man den Server ja auch übernehmen. Außerdem gibt es sowas wie thresholds und ratelimit, das ein Flood verhindern sollte. Pepe_Ku schrieb: > Merkt der Admin das 1 Tag nicht, wäre die Datenbank in 24h dann > 86GB größer und man hat die Arbeit das wieder aufzuräumen. Der Admin sollte seine Systeme Monitoren, es gibt keine Entschuldigung das nicht zu tun! Wenn also die Datenbank so schnell anwächst (und der Traffic, und die Systemload) sollte der Admin eine Benachrichtigung, bekommen und geeignete Gegenmaßnahmen ergreifen. Nagios, Icinga und wie sie alle heißen, können auch SMS verschicken, um angemessen zu reagieren und spätesten, wenn das noch mit einem ELK Stack ergänzt wird oder mit influxdb und Grafana, sollte bei entsprechend gepflegten Monitoring, der Admin in nahezu Echtzeit über den Zustand seines Systems Bescheid wissen und nach ein paar Minuten denn Flood automatisch erkennen.
Pepe_Ku schrieb: > ich erstelle gerade ein Webprojekt mit Datenbank und da kam die Frage > auf, wie man üblicherweise verhindert, dass ein User die Datenbank nicht > flutet. Indem man die DB nicht direkt öffentlich macht.
Hallo Tilo, danke schön für die brauchbare Antwort! Endlich ein User, der nicht verstrahlt ist.
Tilos Ansatz gefällt mir auch gut. Zu den restlichen Schwachmaten hier sage ich jetzt mal lieber nichts. Ich sehe aber, dass dieser Ansatz neue DoS Möglichkeiten einbaut. Ich kann mir trivial für wenige Cent unterschiedlichste IP Adressen zulegen und damit z.B. absurd viele unterschiedliche Benutzer registrieren. Dann ist zwar irgendwann der Eimer für Registrierungen leer, aber dann kann sich eben auch kein anderer mehr Registrieren. Das ist sicher das geringere Übel, aber keine echte Lösung. Ich würde daher eine zusätzliche Stufe in diesem Modell hinzufügen. Sobald der Eimer für unautentifzierte Anfragen aufgebraucht ist, verlangt die Applikation die Eingabe eines Captchas. So sollte sich eine sinnvolle Balance erreichen lassen. Ich muss aber auch sagen, dass es nicht viele Applikationen zu geben scheint, die so etwas implementieren. Ich erinnere mich an einige Fälle wo genau dieses Fluten der Datenbank über eine aktivierte WordPress Registrierungsfunktion passiert ist. Mit allen Seiteneffekten wie unzähligen bouncenden Emails und Abuse Reports.
Nachtrag zur Leaky-Bucket-Implementierung. Tilo R. schrieb: > In der Implementierung persistiert man natürlich nur nicht-leere Eimer. Obige Aussage ist falsch formuliert, ich meinte: man persistiert nur nicht-ganz-volle Eimer. Sonst müsste man alles mögliche initialisieren, das wäre wenig robust.
Meist hat man eher das Problem dass nicht eingeloggte Robots ev. heftig lesend auf die DB hämmern, als dass eingeloggte User Unmengen an Daten in einer DB generieren. Beim eingeloggten User kann man ja easy nur eine maximale Anzahl an Einträgen pro Zeiteinheit erlauben. Im ersten Fall nutzt Caching und Rate Limiting, ggf. Captcha usw. Für eingeloggte User kann man ebenso Captcha und Rate Limiting verwenden. Das kann man dann, wie von Tilo vorgeschlagen, selbst implementieren oder man nutzt bestehende Framework-Funktionen. z.B. gibt es in Laravel diverse Rate-Limiting-Funktionalität auf verschiedenen Ebenen (HTTP/User/Session usw.).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.