[PHP] Tegenwerken gastenboek-spambot*

Pagina: 1
Acties:
  • 1.451 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
hey hallo allemaal

ik heb mijn eigen gastenboekje gemaakt in PHP 4 met mysql 3.23 en is te vinden op
http://guestbook.sourceshock.com

nu heb ik sinds kort last van een spambot in mijn gastenboek, althans dat gok ik :) maar aangezien er elke keer op een ander ip adres gespamt wordt (iets in mijn gastenboek wordt gezet) ...

vind het op zich wel leuk om er hier en daar wat opvaningen voor te schrijven enzo, daar wordt het alleen maar beter van, alleen heb ik sinds kort een soort woord filtertje erin gebouwd

als er bijv. in het onderwerp of het bericht bepaalde woorden zoals porn of sex in voorkomt moet hij
een "exit" geven en verder niks meer doen, dit heb ik getest en hij werkt zoals het hoort te werken

hoe is het toch mogelijk toch mogelijk dat die bot/persoon er toch woorden in weet te krijgen
waarvan ik ze blokkeer ? ik maak ook gebruik van htmlentities en ook dat komt er soms gedeeltelijk in.. ik zit me echt af te vragen hoe dit kan...

mysql injection heb ik ook al geprobeerd bij mezelf uit te voeren maar misschien dat ik het verkeerd doe :) iemand enig idee hoe dit kan ?

Acties:
  • 0 Henk 'm!

  • xtra
  • Registratie: November 2001
  • Laatst online: 13:44
Het kan zijn dat ze foute woorden 'verbouwen' als in 'fout[ b][ /b]woord' waardoor je filter het niet ziet. Dat kun je zelf zo zien.

Zelf heb ik in zo'n soort geval wel eens iets gemaakt dat alle POST-data logt. Achteraf kun je dan vrij goed zien waar het mis gaat of wat men probeert.

Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
ja klopt ja dat hebben we ook al getest maar het zijn dus de volledige foute woorden die niet verbouwd zijn

Acties:
  • 0 Henk 'm!

  • Tuumke
  • Registratie: Januari 2002
  • Laatst online: 25-12-2024

Tuumke

Shingaling?

ik heb er ook last van..
gebruik AkoBook voor in Mambo..
daar zit al geen woordfilter o.i.d. op :S
kan het gelukkig makkelijk verwijderen via adminpanel > components > akobook > view comments
en dan al die spam zooi verwijderen..

maar het is echt wel irritant :S

[WhatPulse Profiel] [ Tuumke's n00by website]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Heb je wel eens geprobeerd te zoeken? Dit is al vrij vaak voorbij gekomen, dus ik kan me niet voorstellen dat er niet in één van die topics het antwoord staat dat je zoekt. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • CrashOne
  • Registratie: Juli 2000
  • Niet online

CrashOne

oOoOoOoOoOoOoOoOoOo

Ik heb wel een makkelijke oplossing:

Gooi zodra iemand op je GB komt een nummer in een sessie, genereer met JS een hidden input field in je form met als value ook dat nummer.

Na de post even controleren of het nummer bestaat en of deze gelijk zijn aan elkaar. Bots maken namelijke (vaak) geen gebruik van cookies en javascript.

Lijkt mij wel te werken (niet getest).

Huur mij in als freelance SEO consultant!


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
ik heb uiteraard gezocht en kan een oplossing vinden/maken om het tegen te gaan maar dat is
mijn vraag niet ...

mijn vraag is hoe krijgt ie het voor mekaar om door mijn filter heen te komen

excuus als mijn topictitel niet duidelijk was

[ Voor 13% gewijzigd door klapvee op 13-12-2005 11:50 ]


Acties:
  • 0 Henk 'm!

  • Tuumke
  • Registratie: Januari 2002
  • Laatst online: 25-12-2024

Tuumke

Shingaling?

Ik heb voor AkoBook wel een spamfilter fix gevonden :)
werkt met zo'n uniek plaatje dat je moet invullen
http://www.tuumke.nl/downloads/akobook_spamfix.rar
klapvee schreef op dinsdag 13 december 2005 @ 11:47:
ik heb uiteraard gezocht en kan een oplossing vinden/maken om het tegen te gaan maar dat is
mijn vraag niet ...

mijn vraag is hoe krijgt ie het voor mekaar om door mijn filter heen te komen

excuus als mijn topictitel niet duidelijk was
maak je ook gebruik van bb codes o.i.d. ?

[ Voor 56% gewijzigd door Tuumke op 13-12-2005 11:52 ]

[WhatPulse Profiel] [ Tuumke's n00by website]


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

CrashOne schreef op dinsdag 13 december 2005 @ 11:44:
Ik heb wel een makkelijke oplossing:

Gooi zodra iemand op je GB komt een nummer in een sessie, genereer met JS een hidden input field in je form met als value ook dat nummer.

Na de post even controleren of het nummer bestaat en of deze gelijk zijn aan elkaar. Bots maken namelijke (vaak) geen gebruik van cookies en javascript.

Lijkt mij wel te werken (niet getest).
Zijn script is blijkbaar zo lek als een mandje. Om dan met een of ander javascript dat te gaan camoufleren ipv gewoon het probleem op te lossen lijkt me niet zo'n goed plan ;)

Acties:
  • 0 Henk 'm!

  • MuddyMagical
  • Registratie: Januari 2001
  • Laatst online: 15:08
Probeer ook niet te voor de hand liggende veldnamen te gebruiken. Dingen zoals 'title' en 'message' worden makkelijk herkend door een bot en misbruikt.

Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
er komen wel codes in voor maar dat moet met htmlentities gefilterd worden dus ..

wrom is mijn script zo lek als een mandje ? :)

zit een check in of er niet te snel gepost wordt met hetzelfde ip binnen x tijd
html tags worden eruit gekickt
geblokkeerde ip adressen worden eruit gekickt
bericht met bepaalde woorden worden niet toegestaan

hoe dicht kan ik het nog gooien volgens jou bosmonster ? :)


maar waar het dus om gaat is dat hij toch voor elkaar weet te krijgen om met bepaalde woorden
berichten te plaatsen terwijl er niet eerder een query uitgevoerd mag worden als ik een bepaalde var op true zet

[ Voor 21% gewijzigd door klapvee op 13-12-2005 11:57 ]


Acties:
  • 0 Henk 'm!

Verwijderd

je kan ook extra check doen op de referal, om te zien of de pagina vanaf jouw domein gepost werd.

Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Misschien handig als je de code die je gebruikt post.. we kunnen natuurlijk zo niet raden wat het probleem kan zijn.

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
sorry is inderdaad wel eens handig

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?PHP


    require "config.php";
    require "function_lib.php";

    $time = time();
    
    $ip = $REMOTE_ADDR;

    $result = mysql_query("SELECT * FROM iplog WHERE ip='$ip' ORDER BY timestamp DESC");

    if (mysql_num_rows($result) > 0) {

        $row = mysql_fetch_assoc($result);

        if ($row["timestamp"] > $time - 40) {
            
            exit;
        }

    } else {
        
        $result = mysql_query("INSERT INTO iplog SET ip='$ip',timestamp='$time'");
    }

    $result = mysql_query("SELECT * FROM spamfilter");

    while ($row = mysql_fetch_array($result)) {
        if (preg_match("/". $row["word"] . "/i",$website)) {
            exit;
        }

        if (preg_match("/". $row["word"] . "/i",$message)) {
            exit;
        }
    }

    $result = mysql_query("SELECT * FROM blocklist WHERE ip='$ip'");
    $numrows = mysql_num_rows($result);

    if ($numrows > 0) {
        echo $blocked_message;
        exit;
    }

    $fields = Array($name,$email,$message);
    $form = Array("name","email","message");
    $set = true;

    for($i=0;$i<count($fields);$i++) {

        $testfield = str_replace(" ","",$fields[$i]);
        $testfield = str_replace("\n","",$fields[$i]);

        if ($testfield == "") {
            $set = false;
            if (!IsSet($required)) {
                $required = "$form[$i]";
            } else {
                $required .= ";$form[$i]";
            }
        }
    }

    if (!IsSet($showmail)) {
        $value = 0;
    } else {
        $value = 1;
    }

    $ip = $REMOTE_ADDR;

    $time = time();

    if ($set) {

        foreach($HTTP_POST_VARS as $key => $value) {
            $$key = htmlentities($value);
        }


        $result = mysql_query("INSERT INTO guestbook (naam,email,showmail,website,bericht,datum,ip,icon,msn,icq) VALUES ('$name','$email','$value','$website','$message','$time','$ip','$mIcon','$msn','$icq')");

        gotoURL("index.php");

    } else {
        
        gotoURL("sign.php?required=$required");

    }

?>

Acties:
  • 0 Henk 'm!

  • Tuumke
  • Registratie: Januari 2002
  • Laatst online: 25-12-2024

Tuumke

Shingaling?

of een verificatie code vragen
die via een plaatje zichtbaar is ?

[WhatPulse Profiel] [ Tuumke's n00by website]


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

klapvee schreef op dinsdag 13 december 2005 @ 11:56:
er komen wel codes in voor maar dat moet met htmlentities gefilterd worden dus ..

wrom is mijn script zo lek als een mandje ? :)

zit een check in of er niet te snel gepost wordt met hetzelfde ip binnen x tijd
html tags worden eruit gekickt
geblokkeerde ip adressen worden eruit gekickt
bericht met bepaalde woorden worden niet toegestaan

hoe dicht kan ik het nog gooien volgens jou bosmonster ? :)


maar waar het dus om gaat is dat hij toch voor elkaar weet te krijgen om met bepaalde woorden
berichten te plaatsen terwijl er niet eerder een query uitgevoerd mag worden als ik een bepaalde var op true zet
Aangezien er vanalles in je database gepost wordt zonder dat het uberhaupt door je filters heen gaat?

Acties:
  • 0 Henk 'm!

  • Stilgar
  • Registratie: Maart 2002
  • Niet online
klapvee schreef op dinsdag 13 december 2005 @ 11:56:
wrom is mijn script zo lek als een mandje ? :)
Je bent iets (naar mijn mening) heel belangrijks vergeten: het escapen van quotes e.d. in je gebruiker input, waardoor het mogelijk is SQL injections te doen.

Kijk bijvoorbeeld eens naar:
http://guestbook.sourceshock.com/index.php?offset=0&limit=5&orderType=DESC1&cpage=1

En ik vermoed dat er nog wel meer van dat soort fouten in je script zitten. Zo krijg ik een lege pagina als ik wat uitgekiende waarden in je 'sign' formulier zet en vervolgens submit...

Wat betreft je spam-probleem... zoek eens naar 'Turing test' of 'Captcha' in Google. Met zo'n met GD gegenereerd plaatje kun je veel robots al uitfilteren.

Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
Bosmonster schreef op dinsdag 13 december 2005 @ 12:18:
[...]


Aangezien er vanalles in je database gepost wordt zonder dat het uberhaupt door je filters heen gaat?
helemaal onderaan net boven de query staat foreach loopje met htmlentities
die zet quotes als het goed is toch ook om naar & quot ; ...

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Waarom gebruik je htmlentities om iets in je db op te slaan? Daar heb je mysql_real_escape_string() voor.

Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
htmlentities heeft altijd goed gewerkt maar als dat veiliger is ga ik dat gebruiken
maar dit geeft nog geen antwoord op mijn vraag of wel ? :)

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
klapvee schreef op dinsdag 13 december 2005 @ 12:25:
htmlentities heeft altijd goed gewerkt maar als dat veiliger is ga ik dat gebruiken
maar dit geeft nog geen antwoord op mijn vraag of wel ? :)
dit zou heel goed de reden kunnen zijn dat het 'lijkt' alsof er vanaf apparte ips gespamt word
jij kwakt zo alles in de DB wat er naar die file gepost word.

als jij thuis een html file maakt die data post naar jouw php file dan voeg jij het zo in. dus met een ander ip etc.
mm ip adres nog niet

maar sql injection blijft mogelijk als je geen quotes escaped

[ Voor 10% gewijzigd door BasieP op 13-12-2005 12:30 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
BasieP schreef op dinsdag 13 december 2005 @ 12:26:
[...]


dit zou heel goed de reden kunnen zijn dat het 'lijkt' alsof er vanaf apparte ips gespamt word
jij kwakt zo alles in de DB wat er naar die file gepost word.

als jij thuis een html file maakt die data post naar jouw php file dan voeg jij het zo in. dus met een ander ip etc.
dan nog moet ie eerst door mijn script heen.. ook dan komt ie mijn filters tegen, ip blokkering, htmlentities, ook dan zegt ie -> Exit :)

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

klapvee schreef op dinsdag 13 december 2005 @ 12:25:
htmlentities heeft altijd goed gewerkt maar als dat veiliger is ga ik dat gebruiken
maar dit geeft nog geen antwoord op mijn vraag of wel ? :)
htmlentities is om iets in een html pagina weer te kunnen geven en geeft je geen enkele beveiliging tegen sql injection

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
trouwens doe je ook 2x dit
PHP:
1
2
$time = time();
$ip = $REMOTE_ADDR;
is ook niet echt nuttig die 2de keer, het ip adres zal echt niet anders worden de 2de keer

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value) {
            $$key = htmlentities($value);
        }

Is die dubbele $$ hier een tiepfout in je post, of staat het ook zo in je gastenboek-code?

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
het is geen typfout zo kan ik heel snel in een loopje alle geposte vars door htmlentities() heenjagen

Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
Bosmonster schreef op dinsdag 13 december 2005 @ 12:29:
[...]


htmlentities is om iets in een html pagina weer te kunnen geven en geeft je geen enkele beveiliging tegen sql injection
als htmlentities de quotes eruit haalt kan er in principe geen sql injection meer worden uitgevoerd
dan wordt de query die geprobeerd wordt uit te voeren als gewone plain text in mijn db

Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
OkkE schreef op dinsdag 13 december 2005 @ 12:37:
Is die dubbele $$ hier een tiepfout in je post, of staat het ook zo in je gastenboek-code?
Dat mag gewoon in PHP, daarmee zet ie de waarde van $naam naar htmlentities($HTTP_POST_VARS['naam']) :)

Zie ook Variable variables

edit:
laat :(

[ Voor 5% gewijzigd door Huppie op 13-12-2005 12:50 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
klapvee schreef op dinsdag 13 december 2005 @ 12:48:
[...]


als htmlentities de quotes eruit haalt kan er in principe geen sql injection meer worden uitgevoerd
dan wordt de query die geprobeerd wordt uit te voeren als gewone plain text in mijn db
correct :)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

klapvee schreef op dinsdag 13 december 2005 @ 12:48:
[...]


als htmlentities de quotes eruit haalt kan er in principe geen sql injection meer worden uitgevoerd
dan wordt de query die geprobeerd wordt uit te voeren als gewone plain text in mijn db
Dat noem ik meer een toevallig neveneffect, maar goed. Dan kun je zelfs urlencode gebruiken of een van de andere duizenden php functies die toevallig iets met strings doen.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
OkkE schreef op dinsdag 13 december 2005 @ 12:37:
PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value) {
            $$key = htmlentities($value);
        }

Is die dubbele $$ hier een tiepfout in je post, of staat het ook zo in je gastenboek-code?
Het is volgens mij zowiezo niet echt handig om het zo te doen. Want volgens mij gaat het nou harstikke fout in je script als ik zelf bijvoorbeeld een value post met de name HTTP_POST_VARS. Volgens mij wordt de $HTTP_POST_VARS array dan overschreven met de $value die ik dan gepost heb.

Je kan veel beter gewoon zo doen.
PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value){
    $HTTP_POST_VARS[ $key ] = htmlentities($value);
}

Zo te zien heb je ook register globals aan staan. Dit kan ook nogal wat security leaks veroorzaken. Waarom maak je trouwens gebruik van $HTTP_POST_VARS i.p.v. $_POST

En tegen SQL injection kan je idd het best mysql_escape_string gebruiken als je gebruik maakt van een mysql database. htmlentities hoef je in principe alleen te gebruiken voordat je data die door een gebruiker is ingevoert wilt tonen.

[ Voor 12% gewijzigd door Woy op 13-12-2005 13:01 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • SYQ
  • Registratie: Oktober 2001
  • Niet online

SYQ

hier heb ik dus ook last van, dagelijks ruim 50 berichten of meer in mijn gastenboek :( tijdelijk maar offline gehaald

ipranges bannen en floodtime op 1uur mocht niet baten

Acties:
  • 0 Henk 'm!

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 04-09 08:16

OkkE

CSS influencer :+

Huppie schreef op dinsdag 13 december 2005 @ 12:49:
[...]

Dat mag gewoon in PHP, daarmee zet ie de waarde van $naam naar htmlentities($HTTP_POST_VARS['naam']) :)

Zie ook Variable variables

edit:
laat :(
Ik weet dat het mag. Ik vind het alleen niet erg netjes om het zo te doen. :)

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


Acties:
  • 0 Henk 'm!

  • Sassie
  • Registratie: November 1999
  • Laatst online: 17:39
klapvee schreef op dinsdag 13 december 2005 @ 11:56:
maar waar het dus om gaat is dat hij toch voor elkaar weet te krijgen om met bepaalde woorden
berichten te plaatsen terwijl er niet eerder een query uitgevoerd mag worden als ik een bepaalde var op true zet
die variabele waar je het over hebt, is dat $set?

Zo ja dan zou ik die toch als 'false' initialiseren en pas op 'true' zetten als alle benodigde checks zijn uitgevoerd (iig de check op spamwoorden dan).
Want volgens mij zit het nu zo:
- in regel 49 zet je $set op true
- als er velden ($name,$email,$message) leeg zijn in de invoer gaat $set op false en krijg je vervolgens een required-boodschap
- maar als er geen lege velden ($name,$email,$message) zijn dan blijft $set gewoon op true staan en kan de inhoud zonder verdere checks de db in? :?


En hoe controleer je je invoer velden nu precies op spamwoorden? Heb je daar een apart stukje code voor geschreven?

[ Voor 29% gewijzigd door Sassie op 13-12-2005 13:11 ]


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Sassie schreef op dinsdag 13 december 2005 @ 13:04:
[...]

die variabele waar je het over hebt, is dat $set?

Zo ja dan zou ik die toch als 'false' initialiseren en pas op 'true' zetten als alle benodigde checks zijn uitgevoerd (iig de check op spamwoorden dan).
En hoe controleer je je invoer velden nu precies op spamwoorden?
Hij bedoeld dit stukje...
klapvee schreef op dinsdag 13 december 2005 @ 12:18:
PHP:
27
28
29
30
31
32
33
34
35
36
37
    $result = mysql_query("SELECT * FROM spamfilter");

    while ($row = mysql_fetch_array($result)) {
        if (preg_match("/". $row["word"] . "/i",$website)) {
            exit;
        }

        if (preg_match("/". $row["word"] . "/i",$message)) {
            exit;
        }
    }
Waarom er precies woorden doorgelaten worden is mij zo snel ook een raadsel eigenlijk...het ziet ernaar uit dat je met die regexes netjes verboden woorden afvangt... Ik zou zelf alleen wel een wat snellere methode gebruiken namelijk:
PHP:
1
2
3
if(stripos($website, $row["word"]) > -1 || stripos($message, $row["word"]) > -1){
    exit;
}

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
Huppie schreef op dinsdag 13 december 2005 @ 13:11:
[...]

Hij bedoeld dit stukje...

[...]


Waarom er precies woorden doorgelaten worden is mij zo snel ook een raadsel eigenlijk...het ziet ernaar uit dat je met die regexes netjes verboden woorden afvangt... Ik zou zelf alleen wel een wat snellere methode gebruiken namelijk:
PHP:
1
2
3
if(stripos($website, $row["word"]) > -1 || stripos($message, $row["word"]) > -1){
    exit;
}
is inderdaad een betere manier maar dacht dat die functie ook case-sensitive was :)

Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Heb je wel een goed password op je database zitten?

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
klapvee schreef op dinsdag 13 december 2005 @ 13:18:
[...]


is inderdaad een betere manier maar dacht dat die functie ook case-sensitive was :)
Nope, strpos is case censitive, stripos is dat niet ;)
stripos

(PHP 5)
stripos -- Find position of first occurrence of a case-insensitive string

[ Voor 3% gewijzigd door Huppie op 13-12-2005 13:22 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
justmental schreef op dinsdag 13 december 2005 @ 13:20:
Heb je wel een goed password op je database zitten?
als dat niet zo was was er al heel wat meer gespamd ipv alleen me gastenboek denk ik ;)
maar het zal ongetwijfeld sql injection zijn


btw huppie: had het idd al gelezen ;)

[ Voor 7% gewijzigd door klapvee op 13-12-2005 13:34 ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
rwb schreef op dinsdag 13 december 2005 @ 12:58:
[...]

Het is volgens mij zowiezo niet echt handig om het zo te doen. Want volgens mij gaat het nou harstikke fout in je script als ik zelf bijvoorbeeld een value post met de name HTTP_POST_VARS. Volgens mij wordt de $HTTP_POST_VARS array dan overschreven met de $value die ik dan gepost heb.

Je kan veel beter gewoon zo doen.
PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value){
    $HTTP_POST_VARS[ $key ] = htmlentities($value);
}

Zo te zien heb je ook register globals aan staan. Dit kan ook nogal wat security leaks veroorzaken. Waarom maak je trouwens gebruik van $HTTP_POST_VARS i.p.v. $_POST

En tegen SQL injection kan je idd het best mysql_escape_string gebruiken als je gebruik maakt van een mysql database. htmlentities hoef je in principe alleen te gebruiken voordat je data die door een gebruiker is ingevoert wilt tonen.
PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value) {
  $$key = htmlentities($value);
}

nu je het zegt, dit is idd vrij dom, zeker als je eerst 100 checks uitvoert, en vervolgens gewoon alle waardes laat overschrijven door post vars :D
als iemand nu een ip adres post dan word je huidige van $ip gewoon overschreven door die post meuk :D

best wel gaar zo
ikzelf gebruik dit:
PHP:
1
2
3
4
    $vars=explode(",","waarde1,waarde2,waarde3,waarde4,etc");
    foreach($vars as $v) {
        $$v = (isset($_POST[$v])) ? $_POST[$v] : "";
    }

zo zorg ik sowieso dat niet alle post values domweg overgenomen worden, maar alleen die in $vars staan (die ik dus zelf opgeef)
(verder heb ik er dan voor gekozen om als de var niet gepost word of leeg is hem altijd "" te maken, zodat mijn checks in de rest van de file alleen van "" uit hoeven te gaan en niet van null ofzo

[ Voor 12% gewijzigd door BasieP op 13-12-2005 13:46 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
BasieP schreef op dinsdag 13 december 2005 @ 13:44:
[...]
best wel gaar zo
ikzelf gebruik dit:
PHP:
1
2
3
4
$vars=explode(",","waarde1,waarde2,waarde3,waarde4,etc");
foreach($vars as $v) {
    $$v = (isset($_POST[$v])) ? $_POST[$v] : "";
}
Waarom doe je daar explode als je ook gewoon
PHP:
1
$vars = array( 'waarde1', 'waarde2', 'waarde3', 'waarde4', 'etc' );

kan schrijven. Zelf vindt ik het trouwens een beetje overbodig om dit zo automatisch te doen. Want ik wil toch per variabele weten of hij gepost is of niet. En een empty string is niet hetzelfde als dat hij niet gepost is. Ik ken dus alle $_POST zelf aan een var toe wanneer dat nodig is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
BasieP schreef op dinsdag 13 december 2005 @ 13:44:
[...]


PHP:
1
2
3
foreach($HTTP_POST_VARS as $key => $value) {
  $$key = htmlentities($value);
}

nu je het zegt, dit is idd vrij dom, zeker als je eerst 100 checks uitvoert, en vervolgens gewoon alle waardes laat overschrijven door post vars :D
als iemand nu een ip adres post dan word je huidige van $ip gewoon overschreven door die post meuk :D

best wel gaar zo
ikzelf gebruik dit:
PHP:
1
2
3
4
    $vars=explode(",","waarde1,waarde2,waarde3,waarde4,etc");
    foreach($vars as $v) {
        $$v = (isset($_POST[$v])) ? $_POST[$v] : "";
    }

zo zorg ik sowieso dat niet alle post values domweg overgenomen worden, maar alleen die in $vars staan (die ik dus zelf opgeef)
(verder heb ik er dan voor gekozen om als de var niet gepost word of leeg is hem altijd "" te maken, zodat mijn checks in de rest van de file alleen van "" uit hoeven te gaan en niet van null ofzo
het is niet vrij dom want die controles doen niks met mijn vars....!!!!!
ipv dat je nou mee dnket met hoe het kan gebeuren ipv stukjes code af te zeiken

[ Voor 7% gewijzigd door klapvee op 13-12-2005 14:58 ]


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
klapvee schreef op dinsdag 13 december 2005 @ 14:53:
het is niet vrij dom want die controles doen niks met mijn vars....!!!!!
ipv dat je nou mee dnket met hoe het kan gebeuren ipv stukjes code af te zeiken
Volgens mij begrijp je het niet goed...

Er wordt vanuit gegaan dat je register_globals = on hebt in je php.ini, dit zorgt ervoor dat een gepostte veld 'name' in php meteen geaccepteerd wordt als $name...

Wat BassieP probeerd te zeggen is dat als iemand anders met zijn eigen formulier met een veld 'ip' naar jouw pagina submit dat er op de volgende plek in ieder geval de ruimte gegeven wordt om het ip van de poster te masken :)

PHP:
78
79
80
81
82
83
        foreach($HTTP_POST_VARS as $key => $value) {
            $$key = htmlentities($value);
        }


        $result = mysql_query("INSERT INTO guestbook (naam,email,showmail,website,bericht,datum,ip,icon,msn,icq) VALUES ('$name','$email','$value','$website','$message','$time','$ip','$mIcon','$msn','$icq')");

Gezien ie daar $HTTP_POST_VARS['ip'] als $ip verwerkt...

Zelfs al heb je register-globals op off staan zal het ip-adres in ieder geval nog te maskeren zijn. Ik weet dat dit uiteindelijk niet uit zou moeten maken voor de woordenfilter maar het is in ieder geval verstandig hier een keertje naar te kijken :)

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
sorry huppie maar als hij bijv zegt dit had ik zo gedaan en het is vrij dom om te doen dan moet hij nog eens goed kijken naar wat er gebeurd :)

dat register_globals verhaal ga idd vanavond op me gemak even naar kijken.. heb intussen wel al kleine aanpassingen gemaakt met de tips meegekregen van hier

Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Om dan nog maar een hintje te geven....:)

Op deze plek probeer je whitespace te trimmen om te zorgen dat mensen niet *enkel* een enter en/of een spatie plaatsen...

PHP:
53
54
        $testfield = str_replace(" ","",$fields[$i]);
        $testfield = str_replace("\n","",$fields[$i]);


Je kan dan beter de whitespace trimmen :)
PHP:
53
        $testfield = trim($fields[$i]);

Dat is (1) eenvoudiger en (2) zorgt ervoor dat alle whitespace aan de voor èn achterkant van de string weggehaald worden...dus niet alleen \n en spatie.

edit:
En het is (natuurlijk) niet de bedoeling om af te zeiken...het is meer dat we je graag wat mee willen geven ter verbetering. Constructieve kritiek geven kan alleen niet iedereen.

[ Voor 18% gewijzigd door Huppie op 13-12-2005 15:22 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het stukje code waar ik het over had zou ik ieder geval even naar kijken want dat is echt een groot security gat. Door dat stukje code kan een gebruiker van je script elke willekeurige variabele in je script overschrijven. Dat is natuurlijk nooit de bedoeling. Variabele variabelen zijn bijna altijd gewoon slecht en leveren vaak ook security problemen op.

Als je data wilt benaderen aan de hand van een string kan je daar beter gewoon een associatieve array voor gebruiken ( Wat array's in php dus ook zijn ). Daarvoor is het ook beter om gewoon zelf je variabelen te initializeren aan de hand van de $_POST array. Dan kan het ook niet voorkomen dat een gebruiker je variabelen gaat overschrijven want je haalt namenlijk enkel de variabelen uit je de $_POST array die je verwacht.

Eventueel zou je nog een controle in kunnen bouwen of er extra POST vars mee gestuurd worden, op dat moment wordt waarschijnlijk met je script gekloot dus dan kan je gewoon een standaard foutmelding tonen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • klapvee
  • Registratie: Mei 2004
  • Laatst online: 13-04-2022
ga ik doen rwb, dank allen, en huppie heb wederom gelijk :)
ik wist het stiekum al maar nooit aangepast ;)

Acties:
  • 0 Henk 'm!

  • CyBeRSPiN
  • Registratie: Februari 2001
  • Laatst online: 19:47

CyBeRSPiN

sinds 2001

voorkomen spam:
De grote truc: zet een hidden variabele in je FORM dmv van JavaScript op een bepaalde waarde. Dit javascript kan bijv aan het onFocus()-event van het invoerveld, of de onSubmit() van je formulier.

Enige wat je dan nog moet doen in PHP is te checken of de betreffende variabele inderdaad gezet is, zo ja, dan voer je de rest van het script uit.
De spambots van tegenwoordig voeren zelf (nog) geen javascript uit, dus hiermee houd je die gegarandeerd tegen, geen gezeik met woordenlijsten en andere ingewikkelde constructies :)

Voorbeeldje:
HTML:
1
2
<input type="hidden" name="check" value="0">
<textarea name="msg_text" onFocus="if (msg_text.value=='<Vul hier je bericht in>') {msg_text.value=''; check.value='1'} >


en in het script:
PHP:
1
2
3
4
5
6
7
8
9
if ($_POST["check"]==1)
{
   //voer script uit
}
else
{
   //SPAM
   mail hier bijv. naar jezelf met de inhoud van $_POST, voor debuggen/tracen
}


Zelf bedacht, en het werkt echt als een tierelier! :)

[ Voor 32% gewijzigd door CyBeRSPiN op 13-12-2005 18:51 ]


Acties:
  • 0 Henk 'm!

  • SYQ
  • Registratie: Oktober 2001
  • Niet online

SYQ

tnx! ff gelijk toepassen

Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
CyBeRSPiN schreef op dinsdag 13 december 2005 @ 18:38:
[...]

Zelf bedacht, en het werkt echt als een tierelier! :)
1) Dat was al eerder gezegd in dit topic ;)
2) En wat als je browser nu geen javascript support heeft?
3) En wat als de bot of spammer nu zelf het formulier nabouwt en naar jouw pagina laat posten?

Kortom...geen echte oplossing :)

Zie ook hier en hier.
edit:
2 Links toegevoegd...

[ Voor 21% gewijzigd door Huppie op 13-12-2005 22:51 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Huppie schreef op dinsdag 13 december 2005 @ 22:49:
[...]

1) Dat was al eerder gezegd in dit topic ;)
2) En wat als je browser nu geen javascript support heeft?
3) En wat als de bot of spammer nu zelf het formulier nabouwt en naar jouw pagina laat posten?

Kortom...geen echte oplossing :)

Zie ook hier en hier.
edit:
2 Links toegevoegd...
Het is misschien geen officiele oplossing, maar ik vind hem wel vrij effectief :) spambotjes posten idd vaak zelf vars ipv een html file als basis te gebruiken, dus daarom zal optie 3 iig niet opgaan.
als je browser geen js support heeft doe je tegenwordig wat fout, en zal je een site als t.net ook niet zien, dus zo'n ramp vind ik dat niet

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

De Tnet frontpage doet het anders prima zonder javascript ;) (er zijn nog wat secties die dan niet toegankelijk zijn, maar ook dat gaat nog veranderen)

Een challenge-response systeem houdt 3) in elk geval al prima tegen en als je echt een waterdicht systeem wilt hebben zal je met registratie en/of met captcha's moeten gaan werken...

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
crisp schreef op dinsdag 13 december 2005 @ 23:22:
De Tnet frontpage doet het anders prima zonder javascript ;) (er zijn nog wat secties die dan niet toegankelijk zijn, maar ook dat gaat nog veranderen)

Een challenge-response systeem houdt 3) in elk geval al prima tegen en als je echt een waterdicht systeem wilt hebben zal je met registratie en/of met captcha's moeten gaan werken...
Tja, captcha's en registratie vindt ik nogal gebruikers onvriendelijk op een site. Om een Captcha voor een registratie te gebruiken kan nog wel redelijk aangezien je dat maar een keer doet. Maar als je een site wilt hebben die voor iedereen makkelijk toegankelijk is wil je eigenlijk niet dat je moet registreren. Ook door gebruik te maken van pure html kan je nog wel dingen bedenken waardoor een programma wat gewoon data post niet werkt. Al doe je maar gewoon een hidden field toevoegen die een value heeft die maar tijdelijk geldig is. Dan moet de spammer ieder geval al eerst een request doen om te kunnen spammen. En dan moet je wel een redelijk populaire site hebben voordat het voor de spammer rendabel wordt om voor jouw site een aparte oplossing te gaan maken.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

BasieP schreef op dinsdag 13 december 2005 @ 23:14:
[...]


Het is misschien geen officiele oplossing, maar ik vind hem wel vrij effectief :) spambotjes posten idd vaak zelf vars ipv een html file als basis te gebruiken, dus daarom zal optie 3 iig niet opgaan.
als je browser geen js support heeft doe je tegenwordig wat fout, en zal je een site als t.net ook niet zien, dus zo'n ramp vind ik dat niet
Handiger is dan een hidden form met random variabele laten vullen (geen javascript, gewoon door server) en deze ook in de sessie te zetten. Na het posten controleer je of de var overeenkomt met die in de sessie.

Zo moet je wel het formulier gebruiken om te posten en daar haakt een bot dus al af. Ook geen javascript benodigd. Ik weet niet of dit valt onder het kopje 'challenge response', maar volgens mij is het net wat anders, in ieder geval simpeler :P

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Bosmonster schreef op woensdag 14 december 2005 @ 11:20:
[...]


Handiger is dan een hidden form met random variabele laten vullen (geen javascript, gewoon door server) en deze ook in de sessie te zetten. Na het posten controleer je of de var overeenkomt met die in de sessie.

Zo moet je wel het formulier gebruiken om te posten en daar haakt een bot dus al af. Ook geen javascript benodigd. Ik weet niet of dit valt onder het kopje 'challenge response', maar volgens mij is het net wat anders, in ieder geval simpeler :P
Tsja, een dergelijke constructie heb ik een paar weken geleden ook in mijn gastenboek ingebouwd, maar sinds een paar dagen stroomt de spam weer binnen. Volgens de logs doen de spambots nu wel eerst een GET request om vervolgens samen met het token weer een POST te doen :/

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

Ik zet met javascript een <input type="text" /> om naar een hidden. Die hidden vul ik met JavaScript; in een <noscript> tag zet ik een captcha, die dezelfde code toont als waarmee JavaScript het hiddenfield vult.

Javascript aan -> merk je als bezoeker niets van; Javascript uit -> Captcha overtypen.

Acties:
  • 0 Henk 'm!

  • ramonp
  • Registratie: Januari 2001
  • Laatst online: 19-09 10:35
Ik heb gelijksoortige problemen gehad en wat mij opgevallen is,
dat meestal de variabele $_SERVER["HTTP_USER_AGENT"] leeg is.

Dus controleer ik daar maar op.
Het is natuurlijk niet een geweldige oplossing, maar het werkt tot nu toe wel.

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

crisp schreef op woensdag 14 december 2005 @ 11:35:
[...]

Tsja, een dergelijke constructie heb ik een paar weken geleden ook in mijn gastenboek ingebouwd, maar sinds een paar dagen stroomt de spam weer binnen. Volgens de logs doen de spambots nu wel eerst een GET request om vervolgens samen met het token weer een POST te doen :/
Damn.. spambots zijn tegenwoordig ook wat geavanceerder geworden begrijp ik...

Acties:
  • 0 Henk 'm!

  • SYQ
  • Registratie: Oktober 2001
  • Niet online

SYQ

ramonp schreef op woensdag 14 december 2005 @ 11:47:
Ik heb gelijksoortige problemen gehad en wat mij opgevallen is,
dat meestal de variabele $_SERVER["HTTP_USER_AGENT"] leeg is.

Dus controleer ik daar maar op.
Het is natuurlijk niet een geweldige oplossing, maar het werkt tot nu toe wel.
dit heeft bij mij niks geholpen, gaat nog even hard door dat gespam :(

Acties:
  • 0 Henk 'm!

  • ramonp
  • Registratie: Januari 2001
  • Laatst online: 19-09 10:35
Je kan ook $_SERVER['HTTP_REFERER'] gebruiken om te kijken waar men vandaan post.
Wanneer dat niet jou script is, dan niet in de database laten zetten.

Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

ramonp schreef op vrijdag 16 december 2005 @ 13:28:
Je kan ook $_SERVER['HTTP_REFERER'] gebruiken om te kijken waar men vandaan post.
Wanneer dat niet jou script is, dan niet in de database laten zetten.
En waar komt $_SERVER['HTTP_REFERER'] vandaan?
De client geeft deze mee; is dus wel heel erg gemakkelijk te omzeilen.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Bosmonster schreef op woensdag 14 december 2005 @ 11:52:
[...]


Damn.. spambots zijn tegenwoordig ook wat geavanceerder geworden begrijp ik...
Bij het doorspitten van de apachelogs viel het me op dat de GET met een ander IP werd gedaan dan de POST, dus dat is wel weer af te vangen met een extra check - eens kijken hoelang het duurt voordat ze dat weer weten te omzeilen...

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • SYQ
  • Registratie: Oktober 2001
  • Niet online

SYQ

crisp, kun je het misschien vertalen naar php. wordt er namelijk strontziek van om elke dag intussen ruim 200 of meer te moeten verwijderen. ik wil niet zover gaan om in een gastenboek catchpa ofzo te installeren, dan verwijder ik hem liever.

wat me wel opvalt is dat er ook velden worden ingevuld zoals url, location, email terwijl ik deze velden handmatig had verwijderd uit de formulier

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Natuurlijk moet je de spammer niet laten weten dat zijn spam mislukt.
Sla zijn berichten gewoon op met een speciale flag, of gooi ze alleen in een sessie, en toon die alleen bij requests van hemzelf waardoor het lijkt alsof zijn spam lukt, terwijl neimand anders zijn berichten ziet.

Simpelste methode is door middel van een aantal routines te bepalen of het wel of geen spam is, en in dat geval het IP-adres bij de post op te slaan. Vervolgens kun je bij het ophalen van de berichten de berichten zonder flag, en die met flag waar ook het IP-adres matcht.
SQL:
1
WHERE spam IS NULL OR (spam IS NOT NULL AND IP = '{$_SERVER['REMOTR_ADDR']}')


Zolang de spammert dentk dat zijn acties werken, zal hij zijn script ook niet aanpassen om je routines te omzeilen.

[ Voor 9% gewijzigd door frickY op 19-12-2005 15:33 ]


Acties:
  • 0 Henk 'm!

  • SYQ
  • Registratie: Oktober 2001
  • Niet online

SYQ

punt is dat er gebruik gemaakt wordt van tig verschillende ipnummers, heb op dit moment reeds 20 ipranges geblokkeerd + floodtime op 1 uur gezet. en alsnog loopt ie vol met troep

Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 10-08 02:59

Gerco

Professional Newbie

Misschien is het een optie om ze aan te pakken op processortijd? Schrijf een eenvoudige javascript functie die een aantal seconden duurt (10 ofzo) en voer deze uit onload() van de pagina. Het resultaat van deze functie is een token zoals bij de challenge-response aanpak.

Die functie zal dat getal na zijn berekening (die grotendeels zinloos kan zijn) in een hidden form var plaatsen (niet in genereren met PHP dus, maar met JS vullen) en op de server check je of de hidden form var gevuld is met de goede waarde.

Voorbeeld:

Op de server:
- Genereer random getal en md5() dat vijf keer (of een andere relatief dure operatie)
- Zet random getal in js variabele/functie/formvar
- Zet resultaat van eerste berekening in de sessie.

Op de client:
- onLoad() van het document voer je de js functie uit
- Deze pakt het getal uit de variabele/functie/formvar en doet dezelfde dure operatie als de server (5xmd5() in dit geval)
- Plaats in andere hidden form var

Serverside bij POST:
- Controleer hidden formvar2 met getal in session, goed -> posten, fout -> exit();

Op die manier merkt een normale gebruiker er niets van (tenzij deze binnen 10 sec post en dat doen ze meestal niet) en als de spammer door wil spammen, zal hij elke keer die dure operatie moeten uitvoeren om een bericht te plaatsen. Als die dure operatie duur genoeg is kost dat zoveel resources dat hij het gewoon opgeeft.

[ Voor 14% gewijzigd door Gerco op 19-12-2005 16:56 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Volgens mij is die $$set variable variable een serieus security leak hoor. Je kan nu toch gewoon PHP code posten die wordt uitgevoerd? Wat gebeurt er dan als ik iets post als "ip=0&myvar=/index.php&doit=$$unlink($myvar)" misschien dat dit exact niet werkt, maar andere vormen?

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Gerco schreef op maandag 19 december 2005 @ 16:55:
Hele lap tekst over een langdurige berekening
Waarom zo moeilijk. Je kan dan toch ook gewoon een key genereren en pas een post accepteren als daar minstens een x aantal seconden tussen zit. Eventueel kan je in de reply de message wel tonen alsof het gelukt is maar hem niet opslaan in de database.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 10-08 02:59

Gerco

Professional Newbie

rwb schreef op maandag 19 december 2005 @ 17:08:
Je kan dan toch ook gewoon een key genereren en pas een post accepteren als daar minstens een x aantal seconden tussen zit.
Omdat ze dan met verschillende IPs tegelijk kunnen gaan wachten tot de tijd voorbij is (zo'n spamrun gebruikt toch al tig servers) en alsnog 100 berichten in een uur kunnen posten. Met zo'n berekening garandeer je dat er aan de kant van de spammer iets bezig moet gaan om deze te voltooien willen ze posten. Meer threads = meer werk.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ok maar ik denk dat het niet echt vriendelijk voor de client wordt. Ik zit niet te wachten op een gastenboek wat opeens 100% van mijn cpu gaat gebruiken voor 10 seconden. Tevens moet je er rekening mee houden dat een spammer waarschijnlijk een stuk meer processor kracht tot zijn beschikking heeft dan de gebruiker met de langzaamste processor die je site bezoekt.

Tevens denk ik dat de meeste spam bots wel automatisch proberen om zo snel mogenlijk te posten. Als je dan netalsof doet alsof het gelukt is vang je denk wel een hoop spambots al af.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Wim-Bart
  • Registratie: Mei 2004
  • Laatst online: 10-01-2021

Wim-Bart

Zie signature voor een baan.

Als eerste mis ik bij de code de statement:
PHP:
1
  mysql_free_result($result);

Ten tweede zie ik nogal wat ongecontroleerde acties. Het meest nette is werken met registerglobals = false, dat voorkomt heel wat ellende.
Daarnaast zou ik post values anders afvangen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
  $sEmail = trim(isset($_POST['email']?$POST['email']:'');
  $sName = trim(isset($_POST['name']?$POST['name']:'');

  // andere acties

  if (strlen($sEmail)>0) && (strlen($sName)>0))
  {
    // Voer andere controles uit, bijvoorbeeld foute letters of andere zaken zoals lengte.
  }
  else
  {
    die('Piss off!');
  }

Wanneer je de waarden op basis eisen hebt gevalideerd kan je verder gaan. Je kan injection voorkomen door types toe te passen en strings voor te bereiden:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  $sEmail = trim(isset($_POST['email']?$POST['email']:'');
  $sName = trim(isset($_POST['name']?$POST['name']:'');
  $sMsg = trim(isset($_POST['msg']?$POST['msg']:'');
  $iAge = trim(isset($_POST['age']?$POST['age']:0);

  settype($sEmail,'string');
  settype($sName,'string');
  settype($sMsg,'string');
  settype($iAge,'integer');

  $aSpam= array('sex','porn','teens','slut');  // Zelf voorbereiden

  // andere acties

  if (strlen($sEmail)>0) && (strlen($sName)>0) && ($iAge>0) && ($iAge<150) && strlen($Msg)>10))
  {
    // Voer andere controles uit, bijvoorbeeld foute letters of andere zaken zoals lengte.

    // We gaan even filteren
    $sSearch= $sEmail . $sName . $sMsg;
    $bError= FALSE;
    foreach($aSpam as $sTest)
    {
      $bError= (stripos($sSearch,$sTest)>0?TRUE:$bError);
    }
    if (!$bError)
    {
      // We kunnen verder
    }
    else
    {
      die("Don't try me!");
    }
  }
  else
  {
    die('Piss off!');
  }

Natuurlijk kunnen ze grapjes uithalen met HTML code en hidden zaken. Dus kan je nog wat extra doen om dat te voorkomen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  $sEmail = trim(isset($_POST['email']?$POST['email']:'');
  $sName = trim(isset($_POST['name']?$POST['name']:'');
  $sMsg = trim(isset($_POST['msg']?$POST['msg']:'');
  $iAge = trim(isset($_POST['age']?$POST['age']:0);

  settype($sEmail,'string');
  settype($sName,'string');
  settype($sMsg,'string');
  settype($iAge,'integer');

  $aSpam= array('sex','porn','teens','slut');  // Zelf voorbereiden

  // andere acties

  if (strlen($sEmail)>0) && (strlen($sName)>0) && ($iAge>0) && ($iAge<150) && strlen($Msg)>10))
  {
    // Voer andere controles uit, bijvoorbeeld foute letters of andere zaken zoals lengte.

    // We gaan even filteren (aangepast met functie)
    $sSearch= StripTheShit($sEmail . $sName . $sMsg);
    $bError= FALSE;
    foreach($aSpam as $sTest)
    {
      $bError= (stripos($sSearch,$sTest)>0?TRUE:$bError);
    }
    if (!$bError)
    {
      // We kunnen verder
    }
    else
    {
      die("Don't try me!");
    }
  }
  else
  {
    die('Piss off!');
  }

function StripTheShit($sDocument)
{
  $aSearch = array ('@<script[^>]*?>.*?</script>@si', // Strip out javascript
                '@<[\/\!]*?[^<>]*?>@si',          // Strip out HTML tags
                '@([\r\n])[\s]+@',                // Strip out white space
                '@&(quot|#34);@i',                // Replace HTML entities
                '@&(amp|#38);@i',
                '@&(lt|#60);@i',
                '@&(gt|#62);@i',
                '@&(nbsp|#160);@i',
                '@&(iexcl|#161);@i',
                '@&(cent|#162);@i',
                '@&(pound|#163);@i',
                '@&(copy|#169);@i',
                '@&#(\d+);@e');                    // evaluate as php

  $aReplace = array ('',
                 '',
                 '\1',
                 '"',
                 '&',
                 '<',
                 '>',
                 ' ',
                 chr(161),
                 chr(162),
                 chr(163),
                 chr(169),
                 'chr(\1)');

  return preg_replace($aSearch, $aReplace, strip_tags($sDocument));
}

Maar dit is natuurlijk niet genoeg. De database moet worden bijgewerkt en er moet wat op het scherm gegooid worden:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  $sEmail = trim(isset($_POST['email']?$POST['email']:'');
  $sName = trim(isset($_POST['name']?$POST['name']:'');
  $sMsg = trim(isset($_POST['msg']?$POST['msg']:'');
  $iAge = trim(isset($_POST['age']?$POST['age']:0);

  settype($sEmail,'string');
  settype($sName,'string');
  settype($sMsg,'string');
  settype($iAge,'integer');

  $aSpam= array('sex','porn','teens','slut');  // Zelf voorbereiden

  // andere acties

  if (strlen($sEmail)>0) && (strlen($sName)>0) && ($iAge>0) && ($iAge<150) && strlen($Msg)>10))
  {
    // Voer andere controles uit, bijvoorbeeld foute letters of andere zaken zoals lengte.

    // We gaan even filteren (aangepast met functie)
    $sSearch= StripTheShit($sEmail . $sName . $sMsg);
    $bError= FALSE;
    foreach($aSpam as $sTest)
    {
      $bError= (stripos($sSearch,$sTest)>0?TRUE:$bError);
    }
    if (!$bError)
    {
      // We gaan strings voorbereiden:
      $sDBEmail= mysql_real_escape_string($sEmail);
      $sDBName= mysql_real_escape_string($sName);
      $sDBMsg= mysql_real_escape_string($sMsg);
      $iDBAge= $iAge;
      $sEmail= htmlentities($sEmail);
      $sName= htmlentities($sName);
      $sMsg= htmlentities($sMsg);
      // Niet nodig $iAge= $iAge;
     
      // Database bijwerken
      $sSql= "INSERT INTO `mytable` SET `email`='".$sDBEmail."', ".
                                      " `name`='".$sDBName."', ".
                                      " `age`=".$iDBAge.", ".
                                      " `msg`='".$sDBMsg."';";
      if (mysql_query($sSql))
      {
        // Dump hier de tekst naar het scherm
      }
      else
      {
        die('Update failed!');
      } 
    }
    else
    {
      die("Don't try me!");
    }
  }
  else
  {
    die('Piss off!');
  }

function StripTheShit($sDocument)
{
  $aSearch = array ('@<script[^>]*?>.*?</script>@si', // Strip out javascript
                '@<[\/\!]*?[^<>]*?>@si',          // Strip out HTML tags
                '@([\r\n])[\s]+@',                // Strip out white space
                '@&(quot|#34);@i',                // Replace HTML entities
                '@&(amp|#38);@i',
                '@&(lt|#60);@i',
                '@&(gt|#62);@i',
                '@&(nbsp|#160);@i',
                '@&(iexcl|#161);@i',
                '@&(cent|#162);@i',
                '@&(pound|#163);@i',
                '@&(copy|#169);@i',
                '@&#(\d+);@e');                    // evaluate as php

  $aReplace = array ('',
                 '',
                 '\1',
                 '"',
                 '&',
                 '<',
                 '>',
                 ' ',
                 chr(161),
                 chr(162),
                 chr(163),
                 chr(169),
                 'chr(\1)');

  return preg_replace($aSearch, $aReplace, strip_tags($sDocument));
}

Natturlijk kan je hiermee nog niet alles voorkomen. Een simpele doch doeltreffende methode is gebruik maken van een aantal technieken zonde javascript.

De code van je post form:
PHP:
1
2
3
4
5
6
7
8
9
10
11
// headers etc.
echo '<form method="post" action="formhandler.php">';
echo '<input type="hidden" name="ip" value="'.$_SERVER['REMOTE_ADDR'].'">';  // Dummy voor de afleiding, doen we niet echt veel mee.
echo '<input type="text" name="email" size="50" maxlength="50" /><br />';
echo '<input type="text" name="name" size="50" maxlength="50" /><br />';
echo '<input type="text" name="age" size="4" maxlength="4" /><br />';
echo '<textarea name="msg" rows="10" cols="50"></textarea><br />';
// Nu een stukje funny code
echo '<input type="submit" value="Add to guestbook" name="'.base64_encode(md5($_SERVER['REMOTE_ADDR'])).'" />';
echo '</form>';
// Footers etc.

Let nu goed op, de Submit actie wordt gewoon doorgegeven als een $_POST veld. De voorgaande code kunnen we als volgt aanpassen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// We maken gebruik van de data zoals in de form is meegegeven:
// Bereken de naam van het button veld.
$sTest= base64_encode(md5($_SERVER['REMOTE_ADDR']));
$bButton= (isset($_POST[$sTest])?TRUE:FALSE);
$sIp= trim(isset($_POST['ip']?$POST['ip']:'');
settype($sIp,'string');

if (($bButton) && ($_SERVER['REMOTE_ADDR']))==$sIp))
{
  $sEmail = trim(isset($_POST['email']?$POST['email']:'');
  $sName = trim(isset($_POST['name']?$POST['name']:'');
  $sMsg = trim(isset($_POST['msg']?$POST['msg']:'');
  $iAge = trim(isset($_POST['age']?$POST['age']:0);

  settype($sEmail,'string');
  settype($sName,'string');
  settype($sMsg,'string');
  settype($iAge,'integer');
  settype($sIp,'string');

  $aSpam= array('sex','porn','teens','slut');  // Zelf voorbereiden

  // andere acties

  if (strlen($sEmail)>0) && (strlen($sName)>0) && ($iAge>0) && ($iAge<150) && strlen($Msg)>10))
  {
    // Voer andere controles uit, bijvoorbeeld foute letters of andere zaken zoals lengte.

    // We gaan even filteren (aangepast met functie)
    $sSearch= StripTheShit($sEmail . $sName . $sMsg);
    $bError= FALSE;
    foreach($aSpam as $sTest)
    {
      $bError= (stripos($sSearch,$sTest)>0?TRUE:$bError);
    }
    if (!$bError)
    {
      // We gaan strings voorbereiden:
      $sDBEmail= mysql_real_escape_string($sEmail);
      $sDBName= mysql_real_escape_string($sName);
      $sDBMsg= mysql_real_escape_string($sMsg);
      $sDBIp= mysql_real_escape_string($sIp);

      $iDBAge= $iAge;
      $sEmail= htmlentities($sEmail);
      $sName= htmlentities($sName);
      $sMsg= htmlentities($sMsg);
      // Niet nodig $iAge= $iAge;
     
      // Database bijwerken
      $sSql= "INSERT INTO `mytable` SET `email`='".$sDBEmail."', ".
                                      " `name`='".$sDBName."', ".
                                      " `age`=".$iDBAge.", ".
                                      " `ip`='".$iDBIp."', ".
                                      " `msg`='".$sDBMsg."';";
      if (mysql_query($sSql))
      {
        // Dump hier de tekst naar het scherm
      }
      else
      {
        die('Update failed!');
      } 
    }
    else
    {
      die("Don't try me!");
    }
  }
  else
  {
    die('Piss off!');
  }
}
else
{
  die('Try to play with your IP?');
}

function StripTheShit($sDocument)
{
  $aSearch = array ('@<script[^>]*?>.*?</script>@si', // Strip out javascript
                '@<[\/\!]*?[^<>]*?>@si',          // Strip out HTML tags
                '@([\r\n])[\s]+@',                // Strip out white space
                '@&(quot|#34);@i',                // Replace HTML entities
                '@&(amp|#38);@i',
                '@&(lt|#60);@i',
                '@&(gt|#62);@i',
                '@&(nbsp|#160);@i',
                '@&(iexcl|#161);@i',
                '@&(cent|#162);@i',
                '@&(pound|#163);@i',
                '@&(copy|#169);@i',
                '@&#(\d+);@e');                    // evaluate as php

  $aReplace = array ('',
                 '',
                 '\1',
                 '"',
                 '&',
                 '<',
                 '>',
                 ' ',
                 chr(161),
                 chr(162),
                 chr(163),
                 chr(169),
                 'chr(\1)');

  return preg_replace($aSearch, $aReplace, strip_tags($sDocument));
}

Uiteindelijk wordt het volgende bereikt:
  1. Vreemde woorden,
  2. Verborgen HTML en andere zaken zoals javascripts, php etc,
  3. Request en post vanaf verschillende adressen,
  4. SQL injection (door gebruik van mysql_real_escape_string en backtics (`)),
  5. Code injection in database en return pagina.
  6. Misleiding, door IP nummer van request te maskeren in een button veld en een simpel hidden ip-veld. Dit laatste zorgt ervoor dat kwaadwillenden om de tuin worden geleid.
Niet gebruikte truuk is gebruikmaken van SessionId(). Dit kan ook nog samen met de $_SESSION array voor sessie gebaseerde opslag. Cookies zijn ook leuk trouwens.

WB

[ Voor 38% gewijzigd door Wim-Bart op 22-12-2005 01:39 ]

Beheerders, Consultants, Servicedesk medewerkers. We zoeken het allemaal. Stuur mij een PM voor meer info of kijk hier De mooiste ICT'er van Nederland.

Pagina: 1