Zum Inhalt springen

Spamversuche durch Gästebuch-Bots unterbinden


Empfohlene Beiträge

Hallo ich habe auf einer von mir betreuten Internetseite ein kleines Problem mit versuchtem Spam.

Da ist also irgendein Bot unterwegs, der alle Links mit Variablen durchprobiert und die richtigen Werte durch irgendwelche URLs ersetzt.

Das gibt dann im access.log vom Apachen solche Einträge:

wktag.php?kid=2&waid=1&wkdat=http://www.xyz.com/bla/blub/

Meiner Meinung nach ist da einer auf der Suche nach Gästebüchern. Die gibt es da aber nicht. Der einzige "Schaden" der dadurch verursacht wird ist also die Serverlast durch falsche SQLs und ein ziemlich dickes access.log. Das würde ich aber gerne vermeiden.

Mit den Parametern werden SQLs gefüttert, solche wie im Beispiel oben ergeben dann halt Murks, weil ein Datum erwartet wird.

Habe das jetzt teilweise so gelöst, dass eine Funktion in PHP jeder Seite vorgeschaltet ist und die übergebenen Parameter erst mal prüft, bei Fehlschlag wird eine leere Seite ausgegeben und die SQLs werden gar nicht erst zusammengesetzt und an die DB geschickt. Ist aber umständlich, da für jede Seite und jeden Parametertyp immer die Funktion angepasst werden muss.

Welche Möglichkeiten gibt es, solche Spamversuche generisch zu unterbinden?

FORM und POST sind doch auch durch Bots auslesbar, oder ist das "sicher" genug?

Oder muss ich damit leben?

Die Last für den Server ist sicher erstmal vernachlässigbar, aber wenn die zunehmen wirds irgendwann störend. Momentan sind es so um die 20 Versuche pro Sekunde und dann ist wieder ein paar Stunden ruhe und dann gehts wieder los.

In die DB wird aber nirgens was geschrieben, ist immer nur lesender Zugriff.

Link zu diesem Kommentar
Auf anderen Seiten teilen

äh,

was du da scheinbar hast, nennt man SQL injection.

du "musst" jeden Parameter prüfen der gesendet / empfangen wird. Mit SQL-Injection wäre es sonst auch möglich dein Gästebuch zu löschen oder Kontrolle über die Datenbank zu übernehmen.

Die einfachste art einer solchen Parameterprüfung ist "alle" auf normale Bustaben und Zahlen zu beschränken. Volltextfelder die ja solche sachen enthalten 'dürften', dann im Code manuell davon auszunehmen.

Die serverlast wirst du kaum los. Was prinzipiell möglich ist, wäre bestimmte Clients / Browser inklusiv oder exclusiv zu sperren. (also if client == firefox || IE ok else error 404 )

Aber so wirklich schön ist auch das nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Parameter werden nur für die WHERE-Clause verwendet und auch nur nach Plausiprüfungen, also kann eigentlich nix passieren. Gästebuch habe ich wie gesagt auch keins. Reine Anzeigeseiten.

Zur Zeit habe ich die Prüfung so ausprogrammiert, dass jede Parameterart (Zahl, Datum, Kurztext) eine eigene Prüfung hat und die Parameter müssen auch zur angeforderten Seite passen. Sonst wird eine Fehlerseite angezeigt.

Die Variante bestimmte Useragents auszusperren ist nicht praktikabel, da diese Bots sich als IE ausgeben. Und den IE kann ich nicht generell blockieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich finde du widersprichst dir. Erst sagst du, dass du jetzt erst eine Funktion zur Prüfung vorgeschaltet hast und dann dass die Parameter auf jeden Fall erst geprüft werden :confused:

Naja,ich lass das mal so stehen, da hierfür einfach zu wenig Infos da sind.

Form und POST können latürnich von jedem ausgelesen werden. Sonst könnte ja auch keiner deine Seite sehen oder benutzen.

IMHO fehlt hier bissl das Grundlagenwissen ;)

Alles was zum Server oder vom Server übertragen wird ist Text, reine, lesbarer Text. Dieser Text kann u.U. selbst eine verschlüsselte Version von etwas sein, aber die Übertragung ist einfach so lesbar erstmal.

Du weißt was GET macht? Es hängt die Parameter einfach an die URL um sie an den Server zu übermitteln. Also denkst du das kann ja jeder lesen. POST sieht man nix, also denkst du, das ist versteckt und kann nicht gelesen werden.

Der Unterschied von POST und GET ist, dass POST die Parameter nicht an die URL hängt, sondern im Body mitschickt. Es steht also ganz genau dasselbe da, nur an einer anderen Stelle (die du als Absender so nicht direkt siehst).

Ein Ausschließen von Bots ist also so einfach nicht möglich. Denn ein Bot ist im Prinzip nichts anderes als jeder Browser.

Um Menschen von bots zu unterscheiden gibt es viele Versuche, zusammengefasst werden die als Captchas

Das hast du bestimmt schon gesehen.

Aber auch da können Bots immer mehr über OCR o.ä. überlisten. Oder Menschen können nichts erkennen.

Was ganz lustig aussah war ein Captcha, wo du von 6 angezeigten Bildern 2 mit Tieren anklicken musst. Vielleicht ist da auf der verlinkten Seite ein Link, weil ich mich an die Seite nicht mehr erinnern kann.

Eine andere Prüfung gegen Bots gibt es nicht.

Naja, hab ich mal hier im Forum gelesen: Ein oder 2 hidden Felder, die leer sind. Bots füllen die aber und somit kann das überprüft werden. Aber auch das ist wohl eher nur te temporär, denn es ist kaum ein Problem für den bot auf hidden zu prüfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich finde du widersprichst dir. Erst sagst du, dass du jetzt erst eine Funktion zur Prüfung vorgeschaltet hast und dann dass die Parameter auf jeden Fall erst geprüft werden

OK, der Satz war vielleicht ein bisschen verwirrend geschrieben.

Ich versuche es noch mal:

Die Parameter werden in dieser Funktion geprüft, ob die a) zur Seite passen und B) der Wert zum Parameter passt. Z.B. muss o.g. wkdat ein gültiges Datum enthalten, sonst wird abgelehnt.

Form und POST können latürnich von jedem ausgelesen werden. Sonst könnte ja auch keiner deine Seite sehen oder benutzen.

IMHO fehlt hier bissl das Grundlagenwissen

[...]

Du weißt was GET macht? Es hängt die Parameter einfach an die URL um sie an den Server zu übermitteln. Also denkst du das kann ja jeder lesen. POST sieht man nix, also denkst du, das ist versteckt und kann nicht gelesen werden.

Der Unterschied von POST und GET ist, dass POST die Parameter nicht an die URL hängt, sondern im Body mitschickt. Es steht also ganz genau dasselbe da, nur an einer anderen Stelle (die du als Absender so nicht direkt siehst).

Die Unterschiede von GET und POST sind mir sehrwohl klar. Und ich habe auch nirgendwo die Frage gestellt (oder stellen wollen, falls es so rüber gekommen ist), ob POST lesbar ist oder nicht.

Der Frageteil war nur " oder ist das "sicher" genug?"

Die Frage war also, ob Bots sich dadurch erstmal abhalten lassen.

Das Schema ist ja immer das gleiche:

1. Bot ruft die Startseite auf

2. ALLE verfügbaren Links werden abgeklappert und dabei die Parameter mit URLs befüllt.

Laut den Logdateien passieren diese Schritte immer, ich hatte (bis jetzt) noch keinen, der direkt eine Unterseite aufrufen wollte.

Wenn also kein <A href="ziel.php?p1=w1&p2=w2">xyz</A> mehr auf der Seite zu finden ist, stattdessen sowas in der Art:


<FORM action=ziel.php method=POST id=testform>

   <INPUT type=hidden name=p1 value=w1>

   <INPUT type=hidden name=p2 value=w2>

   <A onclick="testform.submit()">xyz</A>

</FORM>

Könnte das reichen?

Ein Ausschließen von Bots ist also so einfach nicht möglich. Denn ein Bot ist im Prinzip nichts anderes als jeder Browser.

Um Menschen von bots zu unterscheiden gibt es viele Versuche, zusammengefasst werden die als Captchas

Das hast du bestimmt schon gesehen.

[...]

Captchas o.ä. brauch ich hier nicht, die DB-Zugriffe sind IMMER nur lesend.

Ich kann ja schlecht so was machen wie:

Sie haben den Link xyz angeklickt. Damit sie auf die Seite gelangen, geben Sie bitte den Validierungscode ein.

Wollte halt nur wissen, ob es möglich ist diese Versuche verschiedene URLs einzutragen zu unterbinden. Wegen der Frequenz der Zugriffe (zur Zeit sind es ca. 20 pro Sekunde). Der dadurch verursachte Traffic kommt ja auch noch dazu. Den konnte ich aber durch o.g. Prüfung und Ausgabe einer Fehlerseite schon mal ein bisschen reduzieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

ein URL-Rewrite würde evtl. helfen.

d.h. du schreibst keine normalen Links mit ?var= und &var=

sondern http://meinserver.meinetld/meineseite/meinevariable_wert/anderevariable_wert.html

oder, wenn du die Probleme mit 'simulierten' ORdnern umgehen willst,

http://meinserver.meinetld/meineseite.meinevariable:wert.anderevariable:wert.html

funktionieren. Und für dein PHP nutzt du dann eine .htaccess Datei die das zurückverwandelt.

Bzw. du kannst diesen String dann selbst parsen und in $_GET variablen zurückformen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn also kein <A href="ziel.php?p1=w1&p2=w2">xyz</A> mehr auf der Seite zu finden ist, stattdessen sowas in der Art:


<FORM action=ziel.php method=POST id=testform>

   <INPUT type=hidden name=p1 value=w1>

   <INPUT type=hidden name=p2 value=w2>

   <A onclick="testform.submit()">xyz</A>

</FORM>

Und was machst du, wenn beim Besucher Javascript deaktiviert ist?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mod-Rewrite ist leider nicht verfügbar.

Und was machst du, wenn beim Besucher Javascript deaktiviert ist?

Wers aus hat würde nicht weiter kommen.

Ich habe aber jetzt schon hier und da JS verbaut.

Ich bastel mal was rum. Habe bei Antispam noch ein paar Ansätze gefunden, vielleicht kombiniere ich da ein wenig.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Falls es immer von den gleichen IP-Adressen oder aus dem gleichen IP-Adressbereich kommen sollte, könntest du diese auch einfach direkt ausschliessen und die Kommunikation zu deinem Server erst gar nicht erlauben (Firewall, IP-Tables, Blacklist).

Hast du denn da nur Webspace, oder kannst du Zugriff auf den Server?

Falls nur Webspace vorhanden ist, muss man das mit dem blockieren halt über PHP lösen und z.B. eine 404er-Seite anzeigen lassen für die IP, oder sobald ein Link mit übergeben wird.

Ich hatte eine Zeit lang in meinem Gästebuch damals das Problem, dass dauernd von irgendwo aus China jemand oder ein Bot da Werbeeinträge für irgendwelche Onlinecasinos machte. Hab das dann einfach durch die vorgeschaltete Überprüfung der IP-Adresse abwehren können. Die IP-Adresse wurde jeweils auf eine Blacklist gesetzt, sobald bestimmte Wörter in der Nachricht vorkamen. Könntest du ja machen, sobald ein http oder so übergeben wird. Wenn eine IP-Adresse drauf zugreifen versuchte, die aus einem bestimmten Netz stammte, wurde dann einfach eine Fehlerseite zurückgeliefert. Nach ein oder zwei Wochen hatte ich dann Ruhe vor dem Spam. :)

Falls es dynamische IP-Adressen sein sollten, wäre es dann natürlich sinnvoll, die IP-Adressen nach einer bestimmten Dauer auch wieder von der Blacklist zu löschen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist Webhosting, habe nur über Plesk auf ein paar Einstellungen Zugriff.

Die IPs sind immer komplett unterschliedlich. Teilweise aus Korea, Japan aber auch USA oder Spanien. Deutschland hatte ich auch schon.

Hier habe ich auch noch ein paar Methoden gefunden, auch mit Blacklisten. Denke mal ich werde mir in PHP eine Blacklistfunktion schreiben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mod-Rewrite ist leider nicht verfügbar.

Dann bleibt ja immernoch die "mod_rewrite-ohne-mod_rewrite-funktion" ;)

Das sollte eigentlich meistens funktionieren, wie oben angegeben kannst du ja mal ein Testskript schreiben, ung so:


<?php

echo "URI: ".$_SERVER["REQUEST_URI"];

?>
[/php]

und aufrufen tust du das über den Link

< href="test.php/Bla/bla/blubb.html">Test</a>

Der sollte trotzdem die Seite test.php aufrufen, auch wenn im Link am Ende ja was ganz anderes steht. Wenn das geht, dann kannst du so dein umschreiben von hand machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dann bleibt ja immernoch die "mod_rewrite-ohne-mod_rewrite-funktion" ;)

Das sollte eigentlich meistens funktionieren, wie oben angegeben kannst du ja mal ein Testskript schreiben, ung so:


<?php

echo "URI: ".$_SERVER["REQUEST_URI"];

?>
[/php]

und aufrufen tust du das über den Link

< href="test.php/Bla/bla/blubb.html">Test</a>

Der sollte trotzdem die Seite test.php aufrufen, auch wenn im Link am Ende ja was ganz anderes steht. Wenn das geht, dann kannst du so dein umschreiben von hand machen.

Ah ich dachte das Modul wäre zwingend notwendig.

Werde ich doch gleich mal testen.

Heute hatte ich wieder welche hier aus Deutschland. Wenn ich die IP-Adresse ansurfe, bekomme ich sogar eine Internetseite angezeigt. Laut diesem Tool hier bei Strato gehostet.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wow, geniales Modul. Jetzt weiß ich auch endlich mal wie das z.B. bei Spiegel.de und Wikis funktioniert.

Ich habe jetzt alle Links umgeschrieben, benutze jetzt "seite,p1,p2.html"

Mal sehen was passiert, bzw. das ganze ist jetzt erst mal in der Testphase in einer Subdomain, da lass ich jetzt mal ein paar Tester drauf los.

Eine Frage noch, habe bis jetzt noch nix passendes gefunden (und auch noch nicht durch alles geblickt):

Kann ich damit auch den direkten Zugriff auf die PHP-Dateien verbieten?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eine Frage noch, habe bis jetzt noch nix passendes gefunden (und auch noch nicht durch alles geblickt):

Kann ich damit auch den direkten Zugriff auf die PHP-Dateien verbieten?

Klar kannst du:


#.htaccess


RewriteEngine On


RewriteCond %{REQUEST_URI} ^.*\.php(\?.*)?$ [NC]

RewriteRule .* - [F,L]


Alle Anfragen auf *.php optional mit ?... dahinter werden mit forbidden (403) beantwortet... oder du könntest mit [R=404,L] die Anfrage mit "nicht gefunden" beantworten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das führt aber leider auch dazu, dass keine andere Seite geöffnet werden kann.

Im Hintergrund wird ja immer noch auf die PHP-Seiten zugegriffen.

Beispielsweise habe ich sowas:


RewriteRule wk,(.*)(\.html?)$ /rwk/rwk_details.php?wid=$1 [L]

Wenn ich dann auf z.B. wk,2.html zugreifen will, kommt "You don't have permission to access /rwk/rwk_details.php on this server."

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich glaube das liegt an der Reihenfolge

erst alle PHP's ausschließen, "danach" die HTML's umschreiben.

sonst trifft deine geänderte URL ja auf den neuen Rewrite-Filter.

Nee, die geänderte durchläuft auch noch mal alle Prüfungen, es ist also wurscht wo das steht.

Vielleicht ist das aber auch noch ein Konfigurationsfehler bei mir, da hatte ich gestern echt mit zu kämpfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nee, die geänderte durchläuft auch noch mal alle Prüfungen, es ist also wurscht wo das steht.

'nosubreq|NS' ( not for internal sub-requests)

This flag forces the rewrite engine to skip a rewrite rule if the current request is an internal sub-request. For instance, sub-requests occur internally in Apache when mod_include tries to find out information about possible directory default files (index.xxx). On sub-requests it is not always useful, and can even cause errors, if the complete set of rules are applied. Use this flag to exclude some rules.

Also meine RewriteRule von oben, und dahinter halt ein [NS,L]

Manchmal kann einem so eine Anleitung schon helfen :D

EDIT:

Ich hab leider mein gutes Apache-Buch nicht mehr zur Hand, da ich bei meinem Job jetzt mit dem Apache wenig bis gar nichts mehr zu tun hab. Deswegen hab ich das oben vergessen ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...