PHP knihovna pro Captcha a kontaktní formulář

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:

DefaultMessage = '[zprava]'; $email->doFormExtras(); $email->doMail(); ?>
Kontakt

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 21

  1. #1 Humbucker

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

  2. #2 Patrik

    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 autor webu ▲10 ▼0

    [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

    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 autor webu ▲10 ▼0

    [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

    Nestačí pred odoslaním test na referrer?

  7. #7 zomm

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

  8. #8 Radek Hulán autor webu ▲10 ▼0

    [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

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

  10. #10 Radek Hulán autor webu ▲10 ▼0

    [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

    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? 😄

  12. #12 Radek Hulán autor webu ▲10 ▼0

    [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

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

  14. #14 dimmu

    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 autor webu ▲10 ▼0

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

  16. #16 Fred

    Díky

  17. #17 dimmu

    [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

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

  19. #19 Pavel T.

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

  20. #20 JF

    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