Pagina 2 di 8 primaprima 1 2 3 4 ... ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 76

Discussione: Purga stringhe PHP

  1. #11
    Quote Originariamente inviata da brancomat Visualizza il messaggio
    Francamente di emoji, caratteri strani o inglese non è che mi interessi più di tanto.
    La domanda è più modesta, ovvero
    "con una funzione del genere sto sicuro sia per quanto riguarda injection che xss?"
    Se la risposta è SI' allora per me va bene.
    Di corsi di sicurezza PHP ne ho letti mille e sono davvero complicatissimi e difficilissimi da mettere in pratica, per una scelta che non capisco (quella di lasciar liberi di inserire qualsiasi cosa).

    Forse come principiante PHP paradossalmente vedo le cose più "chiaramente".
    Forse.
    Sei tu che hai chiesto "se ha senso o mi sto complicando solo la vita". La risposta e' che no, non ha senso, se poi ti va bene lo stesso e' un altro discorso.

    Il motivo per cui non ha senso pero' e' piu' profondo e non riguarda sintassi o funzioni specifiche. Il punto e' che se l'utente invia dati e non comandi (cioe' NON stai riscrivendo phpmyadmin), allora bisogna trattare tutto cio' che ti invia come un dato. Per evitare SQL injections c'e' uno strumento efficace al 100% senza sbattimenti, e cioe' i prepared statements. I prepared statements consistono in parole povere nel separare query e dati, in modo che sia impossibile che i dati vadano a modificare la query stessa.

    Quindi analizzare il testo di input ed eliminare manualmente cose come INSERT, DELETE, DROP eccetera, e' fatica sprecata nonche' un procedimento passibile di errore (magari ti dimentichi qualcosa), quando invece c'e' come alternativa uno strumento che risolve il problema alla perfezione.

    L'unica cosa che hai come principiante e' una incorretta percezione della complessita'. Studiarti PDO e i prepared statements e' molto piu' semplice che scrivere un'assurda funzione come quella sopra, e' una soluzione infinitamente migliore, ed e' un investimento preziosissimo per la tua conoscenza.

    L'errore che tutti i principianti commettono (che e' sicuramente colpa di vecchie guide obsolete scritte da altri principianti che si credevano esperti) e' quello di creare le stringhe delle query mescolandoci i dati dell'utente, esempio:

    Codice PHP:
    $email $_POST['email'];
    $name $_POST['name'];
    $sql "INSERT INTO utenti (email, name) VALUES ($email$name)"
    il problema qui non e' non aver fatto l'escape dei valori, il problema e' che LA STRINGA DELLA QUERY NON DEVE CONTENERE DATI PASSATI DALL'UTENTE, in nessun caso e in nessuna forma.

  2. #12
    Utente bannato
    Registrato dal
    Jul 2013
    Messaggi
    290
    Quote Originariamente inviata da k.b Visualizza il messaggio
    Sei tu che hai chiesto "se ha senso o mi sto complicando solo la vita". La risposta e' che no, non ha senso, se poi ti va bene lo stesso e' un altro discorso.

    Il motivo per cui non ha senso pero' e' piu' profondo e non riguarda sintassi o funzioni specifiche. Il punto e' che se l'utente invia dati e non comandi (cioe' NON stai riscrivendo phpmyadmin), allora bisogna trattare tutto cio' che ti invia come un dato. Per evitare SQL injections c'e' uno strumento efficace al 100% senza sbattimenti, e cioe' i prepared statements.
    Li uso da sempre, è uno dei vantaggi di partire da zero (cioè senza trascinarsi dietro codice vecchio).
    Quindi analizzare il testo di input ed eliminare manualmente cose come INSERT, DELETE, DROP eccetera, e' fatica sprecata nonche' un procedimento passibile di errore (magari ti dimentichi qualcosa), quando invece c'e' come alternativa uno strumento che risolve il problema alla perfezione.
    Alla perfezione non direi, perchè non comprende il problema della generazione dinamica del nome della tabella

    L'unica cosa che hai come principiante e' una incorretta percezione della complessita'...
    Direi il contrario, ho visto circa 4000 tipi diverse di vulnerabilità PHP, da semplici ad enormemente complesse.
    Quindi se basta usare pDO e gli statement preparati allora sono già a livello avanzato

    Scherzo.
    Comunque per quanto riguarda XSS e cugini i metodi proposti sono talmente tanti, e talmente complessi, e insicuri (lo scrivono gli stessi autori) che "purgare" tutto mi sembra assolutamente adatto.
    Meglio (per quanto mi riguarda) un sito che non accetta email del tipo @@@bvad@@°ççç\bii@qualcosa.com ma che è sicuro.

    Mi sto facendo la mia piccola libreria di sanitizzazione brutale, per gli interi ad esempio oltre che per le stringhe.
    Poi le userò, magari prima o poi salterà fuori qualcosa di meglio (a dir la verità su stackoverflow ho visto la codifica hex, ma non ho ancora ben riflettuto su come usarla, la utilizzo per la spedizione di nome utente e password).

    La domanda resta: se taglio via tutto quello che non è alfanumerico, sia in input dall'utente, sia prima di postare sul db, non ottengo un livello di sicurezza valido, senza complicarmi la vita più di tanto?

  3. #13
    Utente bannato
    Registrato dal
    Jul 2013
    Messaggi
    290
    Quote Originariamente inviata da .Kurt Visualizza il messaggio
    La differenza tra una funzione/libreria scritta da te ed una scritta da una pluralità di esperti dovrebbe essere abbastanza evidente.ì
    mi spieghi dove sarebbe la differenza, se la procedura è di una decina di righe?
    correntemente sto rifinendo un pochino per gestire meglio il caso di eliminazione dei caratteri, ma sono fiducioso di trovare il consenso di una vasta plurarità di esperti

  4. #14
    Utente di HTML.it L'avatar di .Kurt
    Registrato dal
    Jul 2007
    Messaggi
    654
    a dir la verità su stackoverflow ho visto la codifica hex, ma non ho ancora ben riflettuto su come usarla, la utilizzo per la spedizione di nome utente e password
    Eh?
    La domanda resta: se taglio via tutto quello che non è alfanumerico, sia in input dall'utente, sia prima di postare sul db, non ottengo un livello di sicurezza valido, senza complicarmi la vita più di tanto?
    Ma ti abbiamo già risposto più di una volta
    E' sicuro? No. Prendi come esempio
    codice:
    $sql = "INSERT INTO utenti (userid) VALUES (". solo_caratteri_alfanumerici($userid) .")";
    Questo è vulnerabile.
    codice:
    $sql = "SELECT name FROM utenti WHERE id = ". solo_caratteri_alfanumerici($name);
    Questo è vulnerabile.
    In più ti stai complicando la vita. Un'applicazione che va in crisi solo perché ho deciso di terminare una frase con un punto (.), o mettere tra virgolette (") una parola, o impossibilitato a scrivere un banale indirizzo email (@), è un'applicazione con dei grossi limiti, oltre ad essere immensamente complicata da gestire. Inoltre queste limitazioni sono gratuite, imposte da te senza un reale motivo.

    mi spieghi dove sarebbe la differenza, se la procedura è di una decina di righe?
    Un po' mi secca spiegarlo. Tu stai re-inventando la ruota. Al momento hai preso un blocco di roccia e l'hai scolpita dandogli una forma a ciambella. Ma rimane sempre uno strumento inutilizzabile, per te e per gli altri: non ci fai nulla. Quindi cosa dovresti fare? Cos'è più semplice fare? Riprovare a costruire la ruota come disco di legno con un foro centrale? Oppure utilizzare la ruota che tutti usano, prepared statements, con cerchione e pneumatico?
    In ogni caso, dopo anni di fatica a migliorare la tua ruota, scoprirai infine che somiglia tantissimo a quella che noi abbiamo usato tutto questo tempo.
    Ultima modifica di .Kurt; 13-09-2015 a 22:30

  5. #15
    Utente bannato
    Registrato dal
    Jul 2013
    Messaggi
    290
    Quote Originariamente inviata da .Kurt Visualizza il messaggio
    Eh?
    E' in uno dei link che mi sono stati messi proprio in questo thread
    perchè li leggo
    Ma ti abbiamo già risposto più di una volta
    E' sicuro? No. Prendi come esempio
    codice:
    $sql = "INSERT INTO utenti (userid) VALUES (". solo_caratteri_alfanumerici($userid) .")";
    Questo è vulnerabile.
    codice:
    $sql = "SELECT name FROM utenti WHERE id = ". solo_caratteri_alfanumerici($name);
    Questo è vulnerabile.
    Non è questo che mi interessa, uso solo statement PDO.
    Quello che mi interessa è la concatenazione del NOME DELLA TABELLA, dove PDO non funziona.
    In più ti stai complicando la vita. Un'applicazione che va in crisi solo perché ho deciso di terminare una frase con un punto (.), o mettere tra virgolette (") una parola, o impossibilitato a scrivere un banale indirizzo email (@), è un'applicazione con dei grossi limiti, oltre ad essere immensamente complicata da gestire. Inoltre queste limitazioni sono gratuite, imposte da te senza un reale motivo.
    Non so dove sarebbe "immensamente complicata", per la verità sto cercando i seguire i dettami della "bibbia" della sicurezza (OWASP.org).
    A me, francamente, consentire un nome utente con ., " o quello che vuoi frega proprio niente.
    Ma davvero zero.
    Così come durante l'upload dei file "purgo" superbrutalmente i nomi, se uno vuol chiamare un file foto@@@òçòa@wed"$$$###.jpg (o magari http://evil/sto.jpg) io lo rinomino foto.jpg e buonanotte

    Un po' mi secca spiegarlo. Tu stai re-inventando la ruota. Al momento hai preso un blocco di roccia e l'hai scolpita dandogli una forma a ciambella. Ma rimane sempre uno strumento inutilizzabile, per te e per gli altri: non ci fai nulla. Quindi cosa dovresti fare? Cos'è più semplice fare? Riprovare a costruire la ruota come disco di legno con un foro centrale? Oppure utilizzare la ruota che tutti usano, prepared statements, con cerchione e pneumatico?
    In ogni caso, dopo anni di fatica a migliorare la tua ruota, scoprirai infine che somiglia tantissimo a quella che noi abbiamo usato tutto questo tempo.
    francamente non ho capito nulla.
    La "ruota" non è mica farina del mio sacco, viene da qui, e sembrerebbe far parte proprio delle best practices per siti sicuri
    https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet

    In sostanza voglio 1) "demolire" SQL injection sul nome delle tabelle. A dir la verità penso di fare ancora meglio con un concatenatore di stringhe che opera con un vero e proprio switch (cioè può prendere solo una delle tabelle che voglio, approccio a whitelist, ci sto lavorando)
    2) impedire qualsiasi possibilità di XSS perchè taglio via senza pietà tutto in input, e tutto in output (prima di fare il bind con PDO)
    Cioè mi voglio fare una funzione (quando imparerò magari un metodo della classe) che opera qui

    $stmt->bindValue(':name', PURGA($name), PDO::PARAM_STR);
    purgando senza pietà (sempre approccio safe by default).
    In sostanza sul db non si possono scrivere nè leggere campi se non purgati,
    per il semplice fatto che sono tutti statement preparati e usando un "bindpurga" automaticamente non posso dimenticarmi di usarlo da qualche parte (al massimo userò grep per controllare)

    Penso farò due funzioni diverse, purga "generica" e "speciale" per i nomi dei file.
    Magari apro un altro thread per gli oggetti, per ora farò qualcosa del genere
    function bindpurga($i_statement,$i_segnaposto,$i_valore)
    $i_statement->bindValue($i_segnaposto,PURGA($i_valore)...)

    3) sostituire a echo, print etc funzioni "sicure", cioè che per default taglino via tutto quanto, per avere una "sicurezza by default" e non il contrario
    4) me ne frego (anzi, strafrego) di consentire all'utente di fare quello che vuole. fa quello che voglio io (cioè sceglie all'interno delle scelte a whitelist che consento, non a blacklist) Poi c'è l'argomento sistemistico ma lo sto approcciando con calma, prima volevo sistemare possibilmente gli script PS. il testo è sottolineato non so perchè pazienza non ho fatto io questo script
    Ultima modifica di brancomat; 13-09-2015 a 23:00

  6. #16
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,372
    Ma a questo punto invece di purgare le stringhe; converti i caratteri nel loro valore numerico e salvi cosi. Poi converti di nuovo in alfanumerico prima di stampare a video. Ti costa un po' di spazio disco ma non devi più farti delle domande se rimpiazzare o meno una parola e di sicuro eviti ogni tipo di SQL injection.
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  7. #17
    Se vuoi possiamo fare una discussione analoga e infinita sull'opportunità o meno di creare tabelle a) a nome dinamico e b) con nome PRESO DALL'INPUT DELL'UTENTE!! Ma stai facendo un gestionale per creare un db da interfaccia web o è una scelta (scellerata) di organizzazione dei dati? Perchè, mentre nel caso A avresti "ragione" dal momento che il nome della tabella lo devi pulire perchè pdo non lo farebbe per te, nel secondo caso è (ihmo stra-ihmo ma molto ihmo-fondato) una cosa sensa senso e inutile e pericolosa, quando ti basterebbe una fk tra due tablle invece di avere N tabelle che non servono a nulla.

    purgare i dati prima di passarli al prepared statement non ha senso, perchè il prepared statement lo fa in automatico, non nel senso che purga i valori, ma nel senso che si assicura che il valore non modifichi la query e quindi che tu non abbia sql injection. Poi, se vuoi essere sicuro che nel campo A ci siano solo lettere e numeri, allora te li "purghi" a mano nei modi piu disparati. Se poi questi valori li usi per generare nomi delle tabelle, allora guarda fai prima a far si che i il valore sia fatto solo da lettere e numeri e senza spazi, al limite gli underscore, perchè tutti gli altri caratteri non andrebbero bene. Ma questo non è pulire il codice dell'utente per evitare sql injection (perchè lo fa pdo), ma è "VALIDARE" l'input dell'utente per garantire un corretto comportamento dell'applicativo. Ad esempio, se un campo accetta solo interi, e l'utente ti passa anche delle lettere, PRIMA di passare il tutto a PDO validi l'input per essere sicuro (lato applicativo) che i dati passati rispettino la logica del sistema, e dopo li dai a PDO. Se non lo fai, l'utente può pure passarti "DROP TABLE USERS" nelle varie forme da SQL injection, ma tutto quello che otterrai sarà un'eccezione sul tipo di dati non compatibile

    Per il resto, quel bel link che hai postato te te lo dice a chiare lettere: usa un ORM (evitando ovviamente di creare query con l'input dell'utente) e usa template engine per stampare output. Poi vabbeh entriamo nell'annosa questione "perchè utilizzare un template engine ulteriore se lo è già php di suo", ma hanno tutta una serie di funzionalità comode per far concentrare il programmatore solo sulla logica dell'applicativo e non sul come realizzare (es: normalmente fanno l'escape in automatico delle stringe che stampi proprio per evitare injection varie).

    Poi una domanda: ma una tabella non la posso chiamare "tabellaINSERTO" secondo te? no perchè la funzione che hai postato me la converte in "tabellaO" -_- Quindi non vendere il tuo programma ai giornalai

    A giudicare da come hai risposto, il problema è a monte, nella struttura generale dell'applicazione. Rivedi quella, e poi pensi a come implementarla, non "penso come ad implementarla e poi la rivedo".

    Pure quello che dici, delle "whitelist", quello è validare l'input, non purgare, e poi essere sicuri che il valore scelto lato client (il browser web) sia valido anche lato server (lo script php), perchè cambiare o bypassare la parte client non ci vuole nulla, sta alla parte server garantire i dati

    ah poi un'ultima considerazione di esperienza personale: salva i dati inseriti dall'utente nel modo piu "originale" possibile, perchè se tu li elabori in un modo che ora ti sembra figo, e dopo scopri che esiste un modo molto piu figo (o anche solo che cambiano le esigenze), rischi di ritrovarti con dati incompatibili.

    Quindi io arriverei a due conclusioni: 1) non usare quella funzione oppure spiega chiaramente in quali casi e per quale motivo ti serve, perchè impiegata su tutto "non serve a nulla" e ci sono anche soluzioni migliori a seconda dei casi, 2) rivedere l'architettura generale e capire veramente dove stanno i punti deboli e rinforzarli in maniera opportuna, piuttosto che idealizzare una "sicurezza by default" che non esiste, perchè il problema sei tu, non è ne l'utente (che poverino, digita tasti a caso sulle tastiere) nè del linguaggio che usi, ma il problema è quello che dici al linguaggio di fare. lì, nel 99,999% dei casi è il bug.
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  8. #18
    Quote Originariamente inviata da brancomat Visualizza il messaggio
    Alla perfezione non direi, perchè non comprende il problema della generazione dinamica del nome della tabella
    A parte il caso in cui tu ti ritrovi a scrivere un tool simile a phpmyadmin, nel 99% dei casi la necessita' di nomi dinamici delle tabelle e' un errore di progettazione. Supponendo comunque di trovarci nel 1% in cui sia una caratteristica legittima, la cosa si risolve con una semplicissima whitelist, perche' la regola e' sempre quella: nessun dato fornito dall'utente deve andare nella stringa che compone una query. Se ti attieni a questa regola, non avrai MAI problemi di SQL injection.

    Quote Originariamente inviata da brancomat Visualizza il messaggio
    Meglio (per quanto mi riguarda) un sito che non accetta email del tipo @@@bvad@@°ççç\bii@qualcosa.com ma che è sicuro.
    Accettare una mail di quel tipo di per se' non pone nessun problema di sicurezza, ma comunque si puo' sempre fare il controllo sulla presenza di UN UNICO carattere "@", che peraltro e' l'unico check che ha senso fare su un indirizzo email

    Quote Originariamente inviata da brancomat Visualizza il messaggio
    La domanda resta: se taglio via tutto quello che non è alfanumerico, sia in input dall'utente, sia prima di postare sul db, non ottengo un livello di sicurezza valido, senza complicarmi la vita più di tanto?
    Se fai questo l'unica cosa che ottieni e' dei dati corrotti rispetto all'originale, e' un po' come dire "visto che non voglio che mi rubino la macchina le do' fuoco cosi' risolvo il problema".
    La cosa migliore da fare e' salvare l'input cosi' com'e', e gestirlo poi a seconda dei casi. Modificare l'input e' il peggior modo di approcciare il discorso sicurezza.

    Ti faccio un esempio: stai creando un'applicazione che permette agli utenti di postare messaggi con una firma. In base alle tue regole di sicurezza, quando l'utente inserisce una firma con codice HTML tu purghi via tutto e lasci solo plain text. Un giorno decidi che vuoi dare agli utenti le firme piu' fighe e attivi l'HTML, nel frattempo pero' per quelli che l'avevano gia' messa l'HTML e' andato e non lo puoi recuperare.
    Viceversa se tu ti salvi le cose come sono, hai tutti i dati nel database. Quando stampi la firma puoi tranquillamente usare strip_tags() o qualsiasi altra funzione per ottenere lo stesso risultato della tua purga, ma i dati ti rimangono dovessero mai servirti.

    Stessa cosa per quello che vedo molto spesso menzionato su questo forum, e cioe' usare htmlspecialchars() o htmlentities() come forma di escaping o perche' non sanno gestire le vocali accentate. E' una cosa estremamente stupida, intanto perche' quelle funzioni NON SONO funzioni di escaping ne' alternative a utf8 ma hanno uno scopo ben preciso, e poi perche' se quei dati li vuoi usare al di fuori di una pagina HTML (in una newsletter, in un file di log, etc) tutti i codici HTML non hanno alcun senso e non fanno altro che corrompere i dati.

  9. #19
    Quote Originariamente inviata da Santino83_02 Visualizza il messaggio
    Ma questo non è pulire il codice dell'utente per evitare sql injection (perchè lo fa pdo), ma è "VALIDARE" l'input dell'utente per garantire un corretto comportamento dell'applicativo. Ad esempio, se un campo accetta solo interi, e l'utente ti passa anche delle lettere, PRIMA di passare il tutto a PDO validi l'input per essere sicuro (lato applicativo) che i dati passati rispettino la logica del sistema, e dopo li dai a PDO.
    Esatto, la validazione e' un altro discorso, e comunque un dato non validato deve generare una exception, non deve essere "ripulito".

  10. #20
    Ecco i nomi dei file sono forse l'unica eccezione, un po' perche' alcuni filesystem hanno limitazioni riguardo cos'e' lecito come nome, un po' perche' il nome originale del file raramente e' un dato importante (e anche in quel caso puoi salvarlo nel database), e un po' perche' molto spesso e' piu' utile riscriverlo in un formato adatto alla specifica applicazione.

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.