Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    Captcha ini PHP/Flash - No GDlib

    Salve a tutti.

    A prescindere da tutti i discorsi circa l'accessibiltà e l' usabilità delle immagini di CAPTCHA (spesso illeggibili per persone senza alcun problema, figuriamoci per coloro che hanno handicap), penso che tutti noi abbiamo avuto problemi di spam nei nostri siti.

    Più volte ho letto dei thread di persone che avevano necessità di inserire un sistema di captcha nelle loro form per cercare di far diminuire i messaggi di spam dalle loro pagine web, e molte di quelle volte la risposta che si leggeva suonava tipo “mi spiace, ma non hai la possibilità di creare immagini da codice perché il tuo spazio web non supporta le librerie GD”.

    Mi ci sono messo di punta ed ho pensato che, sfruttando le possibilità che un programma come Adobe Flash mette a disposizione, si poteva comunque creare un'immagine con del testo creato al volo da utilizzare come CAPTCHA pure in assenza delle tanto blasonate librerie GD.

    Per farlo, è bastato creare due file PHP (uno chiamato index.php che è quello che metteremo a disposizione dei nostri utenti, l'altro sessione.php che verrà utilizzato dal nostro filmato di Flash), ed il nostro filmato Flash chiamato captcha.swf, a sua volta generato dal sorgente chiamato captcha.fla. Nella cartella in cui sono presenti questi file, è stata poi creata una cartella /contenitore per salvare i nostri file di sessione.

    Cominciamo ad illustrare captcha.fla, partendo dal presupposto che io l'ho creato con una versione di Flash piuttosto datata (Flash MX 2004) ed usando ActionScript 2.0.

    Aprite un nuovo progetto, impostate le dimensioni che preferite, e create due livelli. Il primo (quello inferiore) chiamato background, l'altro captcha.
    Nel primo livello va importata un'immagine di sfondo (meglio se PNG) con il classico “rumore” per rendere il tutto un po' più illeggibile, ma potete anche creare un movieclip con una animazione. Questa parte è letteralmente a vostro gusto. Ricordate che spesso, però, per rendere troppo difficile la vita agli spammer ed ai loro OCR, si rende difficile la vita anche ai nostri poveri utenti!

    Nel secondo livello, invece, dovete creare una etichetta di testo dinamico e chiamarla testo_txt. A questa etichetta associate le dimensioni ed il carattere che preferite, ma ricordate di usare delle font comuni oppure di importare nel file anche il font che avete scelto... a scapito però delle dimensioni del file SWF.
    Sempre nello stesso livello, inserite il seguente codice:

    codice:
    var lv:LoadVars = new LoadVars();
    
    lv.onLoad = function(success:Boolean) {
        if (success) {
         var captcha:String = this.str_captcha;
         var num:Number = captcha.length; 
    
    	 for (i = 0; i < num; i++){ 
    		var singola_lettera:String = captcha.substr(i, 1); 
    		trace(singola_lettera);
    		testo_txt.text += singola_lettera;
    		testo_txt.selectable = false;
        } 
        } else {
    		testo_txt.text = "Errore!!!";
        }
    };
    lv.load("sessione.php"); // commentare in caso di debug
    // lv.load("sessione.txt"); // DE-commentare in caso di debug
    Spiego brevemente.
    Si crea un nuovo oggetto LoadVars (lv).
    Al momento che questo oggetto viene istanziato, il programma legge il file sessione.php presente nella nostra root. In caso di successo di questa operazione, il codice va a leggere il contenuto del file in questione, che sarà così formattato:
    codice:
    str_captcha=xxxxxx
    Il ciclo di FOR presente nel codice, conta di quante lettere è composta la stringa ed effettua un ciclo per estrarne una per volta e mandarla in stampa nel campo di testo dinamico creato precedentemente.
    L'opzione testo_txt.selectable = false; l'ho aggiunta semplicemente per evitare il copia/incolla del testo nel campo input della form.

    Ho appositamente lasciato il trace() nel codice per la fase di debug, che vi consiglio di fare con un file di testo da richiamare al posto di quello PHP (sessione.txt) nel quale avrete avuto premura di scrivere il seguente semplice testo:
    codice:
    str_captcha=abcdef123
    Una volta che avrete testato il funzionamento del filmato, non vi resta che esportare in formato SWF, avendo premura di scegliere le migliori impostazioni di compressione, nel caso abbiate usato una immagine per sfondo, per far risultare il filmato stesso di dimensioni ridotte.

    Spero che per la parte Flash di questo progetto sia tutto chiaro.... passiamo quindi alla questione PHP.

    Partiamo dal file che legge la sessione per Flash, la quale deve fare poche azioni: leggere la variabile di sessione e mandarla in echo in un formato che sia leggibile per flash.
    Ecco il codice di sessione.php:

    Codice PHP:
    <?php
    /*
    ###############################
    ##    CAPTCHA in PHP/HLASH   ##
    ##  =======================  ##
    ##         by © Alcio        ##
    ##  per tutti voi del forum  ##
    ###############################
    */
    ini_set("session.save_path","contenitore");
    session_start();

    $hash $_SESSION['stringa'];

    echo 
    "str_captcha=$hash";
    ?>
    A parte il “momento di gloria” che mi sono auto-regalato nel commento iniziale, il codice è piuttosto semplice: si imposta con ini_set(), la cartella delle sessioni diversa da quella di default del server. È solo un piccolo aiutino alla sicurezza globale dello script, ma - unitamente ad altri accorgimenti - piuttosto utile.
    Si avvia l'utilizzo delle sessioni per lo script, e si legge il contenuto di quella attiva, associando la variabile $_SESSION['stringa'] ivi contenuta alla nuova $hash.
    Il file compone quindi la stringa formattata per Flash con la conclusiva echo.
    Tutto qui. Semplice, no?

    Passiamo ora al cuore della nostra applicazione, il file index.php.

    Codice PHP:
    <?php
    /*
    ###############################
    ##    CAPTCHA in PHP/HLASH   ##
    ##  =======================  ##
    ##         by © Alcio        ##
    ##  per tutti voi del forum  ##
    ###############################
    */
    ini_set("session.save_path","contenitore");
    session_start();

    // controllo sull'input
    function validate_texts($str){
         
    $str trim($str);
        return (bool) 
    preg_match("^[[:alnum:]]+$^"$str);
    }

    $clicked $_POST['click'];

    if (!
    $clicked) {
    // imposto la variabile nella sessione 
    $stringa SHA1(microtime());

    $hash str_shuffle($stringa);
    $hash substr($hash08);

    $_SESSION['stringa'] = $hash;
    // stampo la form
        
    echo "
    <h1>Controllo CAPTCHA</h1>
    <hr />

    <form action=\"index.php\" method=\"POST\" enctype=\"multipart/form-data\">

    <object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0\" width=\"200\" height=\"70\" id=\"captcha\" align=\"middle\">
    <param name=\"allowScriptAccess\" value=\"sameDomain\" />
    <param name=\"movie\" value=\"captcha.swf\" />
    <param name=\"quality\" value=\"high\" />
    <param name=\"bgcolor\" value=\"#e0dfe3\" />
    <embed src=\"captcha.swf\" quality=\"high\" bgcolor=\"#e0dfe3\" width=\"200\" height=\"70\" name=\"captcha\" align=\"middle\" allowScriptAccess=\"sameDomain\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />
    </object>
        


            <label for=\"tascrivi\">Trascrivi la stringa:</label>
            <input type=\"password\" name=\"stringa\" id=\"stringa\" />
        </p>
        


            <input type=\"submit\" value=\"Invia\" name=\"click\" id=\"click\" />
        


    </form>


    "
    ;    
    } else {
     
    $stringa_da_controllare $_POST['stringa']; 
    $stringa_nella_sessione $_SESSION['stringa'];

    if(
    validate_texts($stringa_da_controllare)) {

     if (
    $stringa_da_controllare === $stringa_nella_sessione) {
        echo 
    "<h2>Controllo superato</h2>";
    } else {
        echo 
    "<h2>Controllo NON superato</h2>";
    }
        
    } else {
        echo 
    "Spiacente ma alcuni caratteri presenti nella stringa non sono validi";
    }

    session_unset();
    session_destroy();    
            
    }
    ?>
    Anche in questo caso, sempre dopo il messaggio auto-celebrativo, la prima cosa che si deve fare è impostare la directory di default dove lo script andrà a salvare/leggere le sessioni, quindi dare lo start alle sessioni stesse.

    La funzione immediatamente successiva, non è altro che un controllo sull'input: si occuperà di ritornare FALSE nel caso la stringa passata dall'utente presenti caratteri diversi da quelli alfanumerici.
    Si recupera poi la variabile associata al pulsante submit della form: se non istanziata significa che l'utente non ha premuto il pulsante, per cui stampo la form stesa in attesa dell'interazione.
    In questa fase, è anche necessario creare una stringa alfanumerica casuale: la nostra CAPTCHA.
    In questo esempio viene creata semplicemente crittando in SHA1 il microtime() del momento in cui lo script viene eseguito. Le lettere vengono mescolate (str_shuffle()), quindi ne vengono estratte solo una certa quantità con substr().

    La nuova stringa così creata viene quindi salvata nella sessione.
    La form successiva è classica, se non per il richiamo al file captcha.swf, il quale stamperà a video la variabile di sessione appena creata sotto forma di filmato flash.

    Il resto dello script credo sia piuttosto semplice da capire.
    La stringa riportata dall'utente viene filtrata con la funzione di cui sopra, e confrontata con la variabile salvata nella sessione.
    Se il confronto da' esito positivo, lo script comunica l'avvenuto riconoscimento, altrimenti comunica il contrario.

    Spero di essere stato chiaro nell'esposizione, e spero di ricevere commenti sia sul PHP sia sul Flash, in modo da migliorarlo, se ce ne fosse bisogno.
    Per quello che concerne la sicurezza, ho evitato di appesantire troppo questo post ed i suoi script, riducendo davvero all'osso i controlli.
    Per quello che riguarda il file di flash, invece, si potrebbe pensare di modificare ogni singola lettera con una inclinazione, degli effetti di blur o quant'altro.

    Aspetto i vostri commenti, e sarebbe davvero bello vedere questo thread trasformato in una pillola!

    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

  2. #2
    Utente di HTML.it L'avatar di Ranma2
    Registrato dal
    Mar 2003
    Messaggi
    2,650
    di flash sono a zero, ma il filmato viene creato da php? cioè php genera il file swf? in termini di prestazioni quanto ci mette?

  3. #3
    Per creare il filmato con PHP sarebbe necessario disporre delle librerie MING, e non so quanti hosting le hanno abilitate.
    Questo, invece, viene creato direttamente con Flash in locale: in remoto viene trasferito direttamente il SWF.

    Pensavo di essere stato un po' più chiaro.

    Comunque.... parlando di prestazioni, tieni conto che il file swf che ho creato io è di circa 6 kb, per cui viene caricato piuttosto velocemente.
    Anche per quello che riguarda l'elaborazione del testo del captcha, se ci si mantiene ad un massimo di 10 caratteri, la visualizzazione è piuttosto veloce.

    Ad ogni modo, lo scopo di questo mio script è quello di andare a creare una captcha al volo negli hosting che non permettono l'uso delle GD: penso che si possano sacrificare alcuni decimi di secondo per questo motivo!
    No????

    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

  4. #4
    UP!

    Credevo di avere aperto un thread un po' più interessante!
    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

  5. #5
    Utente di HTML.it L'avatar di jappoz
    Registrato dal
    Dec 2007
    Messaggi
    114
    beh, io trovo che hai fatto prorpio un ottimo lavoro, anche perchè non tutti hanno voglia di studiare nuove librerie o comunque hanno capacità col flash e le vogliono sfruttare...
    direi che hai dato un grosso aiuto, complimenti
    "Un film è, o dovrebbe essere, più simile alla musica che non alla fiction. Dovrebbe essere una progressione di stati d'animo e sentimenti. Il tema, ciò che è dietro all'emozione, il significato: tutto viene dopo"
    Stanley Kubrick

  6. #6
    Originariamente inviato da jappoz
    beh, io trovo che hai fatto prorpio un ottimo lavoro, anche perchè non tutti hanno voglia di studiare nuove librerie o comunque hanno capacità col flash e le vogliono sfruttare...
    direi che hai dato un grosso aiuto, complimenti
    Grazie del supporto!
    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

  7. #7
    bene, quindi basta connettersi via browser al file sessione.php dopo aver avuto accesso alla pagina ed ho il codice senza dover fare null'altro

  8. #8
    Beh.... questi sono i commenti che mi aspettavo!

    Ci avevo pensato anche io a questa possibilità, però ho anche considerato alcuni aspetti:

    1. I nomi dei file che ho scritto sono a semplici e stupidi, per cui si possono sempre modificare a piacimento, ovviamente anche nel SWF. Si potrebbe ottenere il sorgente del file flash con un decompiler, però.... e qui vado al punto 2

    2. Se anche racimolo il nome della pagina PHP, e la apro via browser, non ottengo altro che una pagina bianca, visto che non c'è HTML e che se richiamo la pagina da browser qesta viene comunque processata prima dal server. O no???

    3. Per ogni browser, c'è una sessione (eventualmente aperta), quindi il problema principale della sicurezza si avrebbe con un session highjacking. Ma questo è un altro aspetto.

    Ad ogni modo, mi piacerebbe sapere cosa ne pensi: ho postato questo codice anche per migliorarlo!

    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

  9. #9
    Originariamente inviato da alcio74
    Beh.... questi sono i commenti che mi aspettavo!

    Ci avevo pensato anche io a questa possibilità, però ho anche considerato alcuni aspetti:

    1. I nomi dei file che ho scritto sono a semplici e stupidi, per cui si possono sempre modificare a piacimento, ovviamente anche nel SWF. Si potrebbe ottenere il sorgente del file flash con un decompiler, però.... e qui vado al punto 2
    Vero, ma sei partito dal principio che non tutti sanno usare flash e quindi hai postato il codice direttamente. Anche se cambiare un semplice nome del file è un operazione estremamente semplice c'è chi può far casino.

    In ogni caso basterebbe utilizzare il player flash e intercettare quale pagina richiama (dico dentro un bot) per risolvere il problema (dai un occhio alle winpcap)

    2. Se anche racimolo il nome della pagina PHP, e la apro via browser, non ottengo altro che una pagina bianca, visto che non c'è HTML e che se richiamo la pagina da browser qesta viene comunque processata prima dal server. O no???
    ottieni esattamente quello che otteresti via flash

    3. Per ogni browser, c'è una sessione (eventualmente aperta), quindi il problema principale della sicurezza si avrebbe con un session highjacking. Ma questo è un altro aspetto.
    si ma per prendere la sessione ci vorrebbe stare fisicamente davanti al pc e prendersi i cookie ... a quel punto sinceramente mi preoccuperei di altro

    Ad ogni modo, mi piacerebbe sapere cosa ne pensi: ho postato questo codice anche per migliorarlo!

    Il problema principale è che passi in chiaro i dati e non puoi fare altrimenti. Anche crittografandoli non risolvi più di tanto il problema perché il flash è facilmente decompilabile.

    Ci sono altre valide alternative quando non c'è disponibilità delle GD direttamente via php:
    http://www.phpclasses.org/browse/package/3163.html


    Il problema è che anche se potrebbe sembrare una soluzione valida il punto debole di tutta la situazione è la necessità di inviare a flash il dato da visualizzare

    Sarebbe cosa ben diversa se tu compilassi il file, lo mettessi (base64 encodato) dentro un file PHP e, prima di inviarlo, sostituiresti la stringa on-the-fly

    Facendo cosi già la situazione cambia perché dovresti decompilare, ad ogni esecuzione, il file flash e, anche se possibile, lo vedo molto più complicato per un bot

  10. #10
    Il problema principale è che passi in chiaro i dati e non puoi fare altrimenti. Anche crittografandoli non risolvi più di tanto il problema perché il flash è facilmente decompilabile.
    Si, in effetti meglio non potevo fare, partendo dal presupposto che mi ero fissato di risolvere con Flash.

    Comunque..... grazie per le dritte!
    Ci lavorerò un po' sopra e vedrò quello che riesco a fare.

    Sarebbe cosa ben diversa se tu compilassi il file, lo mettessi (base64 encodato) dentro un file PHP e, prima di inviarlo, sostituiresti la stringa on-the-fly
    Questo sembra un buon punto di partenza..... ma non so se sarò in grado di svilupparlo.
    Se (come credo) avrò problemi, ti farò risapere!

    <ALCIO />
    Per cortesia: no PVT Tecnici
    ******* LINKS *******
    SRL
    MetalWave

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.