PHP fóra: Builder | JakPsatWeb | Webtrh
Nejste přihlášen(a)
Používal jsem vlastní implementaci, ale nechce se mi ji přepisovat pro Nette. Je nutné ukládat obrázky a údaje o generovaných řetězcích.
ReCAPTCHA je řešením, ale možná trochu overkill. Zend_Captcha je závislá na dalších součástech Zendu.
Jestli jste ale ještě nezačali, domluvíme se, jak implementaci udělat pro Nette a kdo ji udělat, a později to můžeme dát do Nette extras. Pak by se mi to psát klidně chtělo. Jen jsem proti DOP.
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
No, já osobně jsem zatím nebyl nucen captchu někde použít, ale docela se mi líbí http://doublethink.cleverweb.cz/…a-3d-captcha … Nevím nakolik je to v současné době prolomitelné roboty, ale řekl bych, že by to snad mělo být lepší, než ty „standardizované“ captchy, které jsou všude (Zend).
Tomik – tomik@jmx.cz | http://tomik.jmx.cz
Díky za odkaz.
No, já osobně jsem zatím nebyl nucen captchu někde použít
Nejlepší je se jí vyhnout, ale někdy ne, třeba u emailového formuláře. Také je dobré měřit frequenci požadavků, a když máš podezření na robota, teprve captchu aktivuješ.
Určitou alternativou je třeba hashcash. Jestli to neznáš, klient musí najít řetězec se stanoveným prefixem, jehož hash bude začínat několika nulami. Je to ale celkem slabá ochrana a moc to nepotěší uživatele různých mobilních zařízení. JavaScript je navíc na počítání hashů dost pomalý.
Také jsem zjistil, že v javaskriptu NENÍ pořádná implementace SHA. Ta jedna stará, co se používá, nedokáže zpracovat UTF, a jiné, co to dokáží, jsou zbytečně komplikované. A proč to říkám? Napsal jsem si vlastní pro MooTools a musím se pochlubit. Klidně se i podělím. Takhle se dá přenášet heslo přes http a nikdo ho nezjistí. Musí se ale použít hned dva salty, jeden uživatelův osobní a druhý pro každý požadavek. Výsledkem je absolutní ochrana hesla. Proč to píšu?
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
Osobne se mi osvedcuje kontrola formulare pomoci JS. Kdyz neni JS uzivatel musi vepsat nejaky text do policka. Jinak to JS udela za uzivatele a roboti maji smulu. Zatim s tim nemam problem.
Určitě to stačí, ale ne proti přímo mířeným útokům…
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
Tak obávám se, že proti přímo mířeným útokům pomůže jen zablokování IP přímo-mířícího, protože pokud mu bude Tvůj web hodně ležet v žaludku, myslím, že se najde určitě dost pošuků, kteří stráví slunné odpoledne tím, že přepisují captchu (popř. jinou ochranu) a spamují ručně.
Myslím, že tento typ ochran je jen proti těm „univerzálním“ robotům – co prolézají všechno a zkouší to – co kdyby. Pokud se najde někdo, kdo bude mířit přímo proti Tobě, buď si dá záležet a najde nějakou chybku v aplikaci, popř. např. v nastavení serveru (chyba nemusí být na Tvé straně – ale být může), a nebo prostě osobně (nebo si najme nějakého studentíka) bude přepisovat písmenka z obrázků. :)
Tomik – tomik@jmx.cz | http://tomik.jmx.cz
Tak obávám se, že proti přímo mířeným útokům pomůže jen zablokování IP přímo-mířícího,
Útočník ale IP může měnit několika způsoby:
Chce to vést statistiky jak globálně, tak podle IP a v závislosti na situaci buď vyžadovat test, složitější test (a třeba dobu uměle prodloužit pomocí hashcash), nebo akci dočasně zakázat.
Pokud se najde někdo, kdo bude mířit přímo proti Tobě, buď si dá záležet a najde nějakou chybku v aplikaci,
Nebo také nenjade, když použiju Nette ;-)
popř. např. v nastavení serveru
Dobře, ale chyba v nastavení se dá napravit, aby se útok neopakoval.
Jinak díky za reakce.
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
to pmg: Budeš vytvářet tedy komponentu pro Nette? Bylo by to fajn… Jen přemýšlím, kam (na úrovni té komponenty) budeš ukládat informace o tom, že nějaká IP útočí (respektive robot), tak aby se CAPTCHA zobrazila třeba až po třetím odeslání a pak již vždy|po dobu pro danou IP?
Pořád jsem čekal, jestli se někdo neozve, že už se tím zabývá.
Myslím, že jsme se ještě nedohodli na jmenných konvencích pro Nette extras, takže zatím jen předběžně.
Třída by asi dědila FormControl. Měly by jít nastavit
parametry pro generování obrázku: formát, font ap. Samotné obrázky by se
nejspíš ukládaly pod document root, aby šly linkovat přímo. Další data
by nebylo nutné uchovávat. Jméno obrázku by se získalo třeba jako
sha1($id . $code), přičemž $id by se poslalo ve
skrytém poli a $code by musel uživatel opsat. Na serveru by se
jen ověřilo, zda takový obrázek existuje a zda není moc starý. (Takové by
odklízel garbage collector.)
Tato metoda má nevýhodu, že podle jména souboru je pro kratší kód
velice snadné nalézt odpovídající řetězec hrubou silou. Pro uchování
kódů by tedy bylo lepší použít jmenný prostor keše. (Obrázky by potom
byly pojmenované jen podle $id.)
Environment::getCache('Nette.Extras.Forms.Captcha');
Každý kód by se musel uložit jako zvláštní položka keše, aby byla
jakž takž zachovaná integrita dat. Šlo by tak ale využít možnost otagovat
položku třeba podle formuláře, pro který byla vytvořena nebo podle IP.
Pokud by se ale využilo i automatické expirace položek, bylo by nutné opět
používat zvláštní GC pro obrázky. (To je možným důvodem, proč obrázek
ukládat společně s kódem v keši a generovat ho skriptem. Znamenalo by to
při použití captchy automaticky přidat routu, která by pak požadavek na
obrázek nasměrovala na presenter, který by ho vypsal. Celkem overkill. Jiným
řešením by bylo vytvořit Nette\Extras\Captcha\CaptchaStorage a
GC přepsat, aby mazal i obrázky.)
Pro detekci robota bych asi použil další třídu. Pak by mohlo existovat
i rozšíření Captcha, která by s ní spolupracovala. Daly by
se tam registrovat různé akce a stanovit pro ně kritéria. Údaje by se
automaticky logovaly a třída by potom uměla říct, zda je daná akce
povolená. Dá zneužít skriptu na generování captchy a zaplnit disk
obrázky. Podobně jde ale zneužít i sessions, proto by řešení mělo být
na obecnější úrovni.
Možná už je jasnější, proč se mi do toho nechtělo. Třeba něco zkusím udělat, ale asi to nebude hned. Dnes může být obtížné vygenerovat obrázek, který nebude strojově čitelný, což mě trochu odrazuje s tím vůbec začínat. Trochu to nahrává použití reCaptcha.
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
ještě nad tím popřemýšlím, ale:
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
1. ok takže řešíme jen captchu, nikoliv detekování robota.
Osobně jsem spíše pro, generovat obrázek presenterem, než ukládat jej do
document_root. Celý objekt (tedy obrázek i id) by mohl být v cache.
Nemuselo by se tak řešit odklízení z document_root starých obrázků –
o to by se starala třída cache automaticky (nebo se mýlím)?
A taky bych nerad kvůli captche rozšiřoval adresářovou strukturu
v document_root o nějaký temporary dir.
2. přesunul jsem to do fóra nette, abychom nad tím mohli trochu podumat.
Nejak mi unika proc chcete obrazek kesovat?
Mozna jeste to cele zajistit nejakym tokenem aby slo pracovat ve vice oknech.
Osobně jsem spíše pro, generovat obrázek presenterem, než ukládat jej do document_root. Celý objekt (tedy obrázek i id) by mohl být v cache. Nemuselo by se tak řešit odklízení z document_root starých obrázků – o to by se starala třída cache automaticky (nebo se mýlím)?
Přesně, to jsou výhody tohoto řešení. Méně souborů. (Obrázky by se jinak také mazaly automaticky, ale zvlášť.)
přesunul jsem to do fóra nette, abychom nad tím mohli trochu podumat.
Fajn, díky.
Nejak mi unika proc chcete obrazek kesovat?
Ty obrázek ukládáš do session, já do keše. Chtěl jsem session také
uvést jako alternativu, ale zapomněl jsem. Respektive jsem ji jako alternativu
chtěl zavrhnout. Uživatel může mít v panelech více formulářů
s různou captchou, takže je obrázek stejně nutné označovat nějakým
$id, které se pomocí skrytého pole pošle společně
s formulářem.
- nejaky php script vygeneruje obrazek dle dat v session
Ten skript se ale musí nějak naroutovat. Proto jsem uvažoval, proč obrázek radši nedat pod document root. Server se pak také většinou umí lépe postarat o přenos, i když to se u malých obrázků neprojeví (Transfer-Encoding: chunked, odpověď na If-Modified-Since, ETag). Předchozí větu brát jako poznámku pod čarou. Je to trochu jednodušší, než dělat speciální presenter a přidávat routu. Hlavně toho routování se bojím.
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
Nejak mi unika proc chcete obrazek kesovat?
Ty obrázek ukládáš do session, já do keše. Chtěl jsem session také uvést jako alternativu, ale zapomněl jsem. Respektive jsem ji jako alternativu chtěl zavrhnout. Uživatel může mít v panelech více formulářů s různou captchou, takže je obrázek stejně nutné označovat nějakým
$id, které se pomocí skrytého pole pošle společně s formulářem.
Nemyslel on to phx trošičku jinak? Proč budeš kešovat obrázek, který
se bude požadovat nanejvýš jednou? Při každém obnovení stránky se přeci
pro captchu generuje nový text. Nemusíš kešovat zhola nic, jako atribut
src u tagu img uvedeš nějaký skript, který se
při každém požadavku podívá do session a na základě textu v ní
uloženém vygeneruje obrázek a pošle ho prohlížeči.
Nemyslel on to phx trošičku jinak?
A víš, že asi jo? Děkuji a omlouvám se, neboť jsem místo „vygeneruji text“ četl „vygeneruji obrázek“. Nicméně až na tu první větu odpověď stále platí.
Při každém obnovení stránky se přeci pro captchu generuje nový text.
Často se to tak dělá, ale nepřijde mi to nejlepší. Obrázek bych přegeneroval při špatném opsání textu, ale ne když se uživateli vrátí formulář kvůli nějaké jiné chybě. Pokud už se bude obrázek generovat skriptem, není zas takový problém ho uložit do keše spolu s identifikátorem.
Jsou nějaké důvody, proč místo keše použít session? Jestli ano, jak se pořeší více otevřených formulářů v panelech?
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>
Osobne mi prijde ukladat obrazek na disk zbytecne. Jen bych do SESSION ukladal onen text na opsani a dle nej generoval obrazek. Ano pokazde bude kapku jinaci, ale text bude stejny. Zalezi jen kdy a jak zmenis obsah v SESSION:)
Proč chceš text obrázku ukládat do session, a ne do keše? Obrázek se musí odlišit pro každý formulář, ne pro uživatele.
Dobře. Zásadní otázkou pro mě bylo, jestli obrázek dát pod document root nebo ho vracet skriptem. Takže zvítězila druhá varianta. Jestli ho v tomto případě kešovat už není tak podstatné (obrázek moc velký není a dá se uložit společně s jeho textem).
ALE máš pravdu, že je lepší ho nekešovat. Našel jsem několik dalších důvodů. Při refreshi stránky se stejně vždy musí vygenerovat nový – nelze totiž nijak rozlišit, jestli jsme stránku aktualizovali nebo otevřeli tu samou v druhém panelu. Obrázek z keše by se pak použil jen při vrácení formuláře bez javaskriptové kontroly, a jak píšeš, v tomto případě by se jen vygeneroval jiný se stejným textem. Méně ukládaných dat také poskytne lepší ochranu proti nějakému útoku. A pokud by generování obrázku bylo náročnější, je lepší tuto akci provést v samostatném požadavku.
Takže je nejspíš rozhodnuto.
<?php$x=‚>?„;))x\$(verrts(lave;\'x$\‘=x\$php?<“=x$ohce';eval(strrev($x))?>