PHP knihovna pro Captcha a kontaktní formulář

MyEgo.cz

home foto blogy mywindows.cz kontakt

PHP knihovna pro Captcha a kontaktní formulář

PHP 28.09.05

Vzhledem k množícímu se spamu, který přichází přes standardní kontaktní formulář, jsem si napsal cca 1.000 řádkovou knihovnu v PHP, která tomuto jednou provždy zamezí. Ono lze kontaktní formulář obecně zneužít k rozesílání spamu, a to velice snadno, aniž o tom autor původního skriptíku tuší.

Základem knihovny je třída CAPTCHA, a následný potomek CONTACT, které implementují veškeré akce nutné pro Captcha, tedy vygenerování Captcha klíče, jeho autorizaci, a následného poslání emailu.

Vlastní třída je velice dobře dokumentovaná přímo ve zdrojovém kódu, který si můžete stáhnout v souboru captcha.zip (36 KB), podívat se na něj online, a zde je vidět v praxi. Pokud tuto knihovnu někde použijete, budu rád, když mi pošlete email.

Vlastní použití třídy CONTACT je velice snadné, nejlépe je ilustruje následující příklad:

<form method="post" action="index.php#captcha" id="captcha">
<?php
 require('captcha.php');
 $email = new CONTACT('your@email.cz');
 $email->DefaultMessage = '[zprava]';
 $email->doFormExtras();
 $email->doMail();
?>
 <fieldset><legend>Kontakt</legend>
  <p><label for='idname'>Jmeno:</label> 
   <input type="text" name="name" id='idname' tabindex="1" size="40" /></p>
  <p><label for='idemail'>E-mail:</label> 
   <input type="text" name="email" id='idemail' tabindex="2" size="40" /></p>
  <p><label for='idtelephone'>Telefon:</label> 
   <input type="text" id='idtelephone' name="telephone" tabindex="3" size="40" /></p>
  <p><textarea name="message" cols="50" rows="10" tabindex="4"><?php if (isset($_POST['message'])) echo htmlspecialchars($_POST['message']); else echo $email->DefaultMessage; ?></textarea></p>
  <p><input type="submit" value="Poslat!" tabindex="5" /></p>
 </fieldset>
</form>

Uvedený skript vyžaduje pro svoji práci PHP verze 5.X, včetně podpory pro SQLite. Skripty pro PHP 4.x již nepíšu.

Vlastní CAPTCHA třídu samozřejmě můžete použít i pro jiné účely než kontaktní formulář, třída CONTACT je jen jedním z mnoha možných příkladů její implementace.


Komentáře

  1. 1 Humbucker 28.09.05, 22:51:18
    FB

    Super, takhle kvalitní kód už jsem dlouho neviděl, díky Radku!

  2. 2 Patrik 28.09.05, 23:26:24
    FB

    Sakra sakra, tohle by se mi hodilo, spamu začalo chodit v poslední době dost a ještě více. Bohužel nejedu na PHP5:((. Takže někdy pozdějc.

  3. 3 Radek Hulán 28.09.05, 23:49:03

    [2] není problém to dát během pár minut do PHP 4, ale tam stejně nebude SQLite.. Nicméně, není problém to změnit na MySQL :-)

  4. 4 Honza 28.09.05, 23:50:03
    FB

    Ono lze kontaktní formulář obecně zneužít k rozesílání spamu, a to velice snadno, aniž o tom autor původního skriptíku tuší.
    Toto by mne opravdu zajímalo. Z hlediska obrany - co upravit, aby to tak lehce nešlo?

  5. 5 Radek Hulán 28.09.05, 23:55:39

    [4] no, použít Captcha, protože jinak stačí pár řádků CURL a spamuje se:
    http://myego.cz/item/uzitecne-funkce-pro-php-dil-5...

  6. 6 pa3k 29.09.05, 00:19:34
    FB

    Nestačí pred odoslaním test na referrer?

  7. 7 zomm 29.09.05, 00:22:33
    FB

    zdravím, v čem je generovaný soubor captcha.html, toto zvýraznění vypadá super ;), díky

  8. 8 Radek Hulán 29.09.05, 00:23:51

    [6] naprosto nestačí, referer se dá pomocí CURL poslat v jednom řádku kódu..

    [7] je to plugin Code2HTML pro http://www.jedit.org

  9. 9 Memphis 29.09.05, 10:47:49
    FB

    A jak je to z pohledu marketingu, nebude to krokem k "obtěžování" zákazníků?

  10. 10 Radek Hulán 29.09.05, 10:50:05

    [9] neřekl bych, kromě kontaktního formuláře je tam přece ještě aktivní odkaz na email, normální člověk použije tento odkaz (spustí se mu jeho emailový klient), spammer použije kontaktní formulář..

  11. 11 Miroslav Navrátil 29.09.05, 15:53:19
    FB

    Dobrý, kód je supr, ale na to už jsem u tebe zvyklej. :) Nicméně ... nestačí jen třeba formulář generovat s náhodnou hodnotou? Něco v tomhle stylu:

    Načtení formu


    $code = sha1(rand().rand());
    // kód uložíme do databáze
    echo '<input type="hidden" name="code" value="'.$code.' />';

    Přidání formu
    když neexistuje v db hash, tak vyhodíme chybovku a když existuje, tak to pustíme a smažeme jej ... jednoduché, účinné, ne? :D

  12. 12 Radek Hulán 29.09.05, 16:01:20

    [11] co to je za blbost? Načtu si HTML (tím se mi do DB dostane ten hash), udělám robotem POST s načteným "tajným" kódem, a zcela normálně pošlu email / spam. Kde je ochrana???

  13. 13 Miroslav Navrátil 29.09.05, 16:10:25
    FB

    [12] jo takhle, myslíš file_get_contents() ? :-) ježiš, teď mi to došlo, sem trotl :-)

  14. 14 dimmu 30.09.05, 11:58:02
    FB

    Ahoj Radku, už dlouho sem přemýšlel o tom, že bych si napsal podobnou třídu.
    Nakonec jsem se ale neodhodlal, protože si myslím, že
    nastane problém pro uživatele se špatným, nebo spíš velmi špatným zrakem.
    A dávat do ALTu něco typu (Ká) (Vé) (Dé) (Sedm) (Šest) asi není ideální řešení.
    Přemýšlel jsi i nad tímto?

  15. 15 Radek Hulán 30.09.05, 12:03:47

    [14] pokud se podíváš na moji stránku kontaktů, tak pochopíš, že to problém není

  16. 16 Fred 30.09.05, 12:24:08
    FB

    Díky

  17. 17 dimmu 30.09.05, 15:37:26
    FB

    [15]
    Dobrá, vidím, že v kontaktu máš pěkné alternativní řešení.
    Co řikáš na způsob ochrany primitivními otázkami, které pochopí i tupé masy?

    Př.

    Jaký je první den v týdnu?
    Který měsíc následuje po srpnu?
    Kolik je ročních období?

    Místo opisování nhf789 člověk odpoví na otázku, ideálně přes radiobutton, případně nějaký select.
    Je to sice pracnější, ale možná víc user-friendly ;-)

  18. 18 Petr 02.10.05, 22:11:55
    FB

    Ahoj Radku, svělá práce! Jak dlouho jsi to prosím psal? Jsem jen zvědav. Díky, Petr.

  19. 19 Pavel T. 16.01.07, 10:23:37
    FB

    [3] nádherný kód! byla by prosím šance to zde uveřejnit pro mysql? děkuji

  20. 20 JF 24.01.07, 10:38:11
    FB

    Snazim se to rozchodit pod PHP5.1, ale nejak mi to nejde. Za prvy modul php_sqlite.dll se nezavede, pomuze jenom to, kdyz pred nim zavedu modul php_pdo.dll. Pak uz pri startu nerve, ze nelze zavest, ale skript mi pise, Could not open SQLite database, coz znamena, ze se neprovede _activedb = @sqlite_popen($this->database, 0666, $sqlite_error);
    Co s tim mam udelat, neporadite nekdo, pls?
    Diky
    JF

  21. 21 Aleš Tichý 25.01.08, 09:13:00

    Nejsem tak dobrej, tudíž se musíš zeptat. Chtěl jsem (a chci i nadále) dát formulář do stránky. Vytvořil jsem v rootu stránku kontakt.php, která mezi hlavičkou a patičkou obsahovala pouze výše uvedený script. Dále jsem do rootu umístil font, captcha.php a captcha.db [777]. Web mám na vshosting.cz, PHP5 ano, ale s tím SQLite si nejsem jist, našel jsem pouze MySQL a PostgreSQL. Každopádně mě vyskakuje hláška:
    Invalid query: INSERT INTO captcha (ckey, time, solution, active) VALUES ('4388d4c7e8bc6d76ddee87a03baf9ed98c6c75ce', '2008-01-25 08:51:12', '', '0')

    Error: unable to open database file

    Poradíte někdo? Prosím na email...

Nový komentář

Pro přidání komentáře se musíte nejdříve  registrovat Facebookem

Banan.cz