Visualizzazione risultati 1 fino 10 di 10

Discussione: Sanificazione variabili - curiosità

  1. #1
    kairos2020 non è connesso Utente giovane
    Data registrazione
    16-04-2020
    Residenza
    Castegnato (BS)
    Messaggi
    49

    Predefinito Sanificazione variabili - curiosità

    Buongiorno,
    ho una curiosità in ordine alla sanificazione di input e output.
    Quando registro dati li sanifico con le funzioni PHP per i valori _POST, poi li memorizzo nel database
    usando ADO PREPARED STATMENT, quindi credo di aver la certezza che le informazioni sono inserite in MYSql
    correttamente.

    Quindi perchè è necessario sanificarle in fase di output con echo ?

    Grazie

  2. #2
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Ci sono più processi che vengono mischiati sotto il termine "sanificazione", quindi separiamoli

    1) Quando ricevi dati da un browser, questi non sono sicuri (safe) finché non li hai validati. Validare vuole dire assicurarsi che siano del formato giusto: i numeri siano numeri accettabili, date siano nel formato giusto, stringhe della lunghezza giusta, etc. La validazione dipende dall'uso che vuoi fare dei dati.

    2) Quando salvi i dati da qualche parte (database, file CSV, JSON), devi assicurarti che i dati siano in un formato accettabile per la destinazione: per un file CSV non vuoi avere virgole nel posto sbagliato (vedi fputcsv), in un file JSON i doppi apici sarebbero un problema (quindi json_encode), per il database devi proteggere i caratteri speciali nelle stringhe, oppure usare gli slot dei prepared statements. Questo passo dipende dallo storage che usi per i dati.

    3) Quando mandi i dati in output, devi assicurarti che siano in un formato adatto per l'output: in una pagina HTML, devi proteggere <, >, & e compagnia, per evitare che la pagina si rompa o qualcuno inserisca codice malevolo; per il testo c'è di solito htmlspecialchars, ma per i parametri di un URL useresti urlencode. Un'API che risponde XML ha requisiti simili, mentre per un payload in JSON torniamo alle virgolette, etc.

    Errori comuni:
    - dimenticare 2, aprendo la porta a SQL injection ed altri rischi
    - mischiare 1 e 3, "rovinando" i dati nel database: perché sono stati preparati per l'output troppo presto, e diventano difficili da elaborare

    Un esempio del "difficile da elaborare": usare htmlspecialchars trasforma & in &amp;; se dopo vuoi calcolare la lunghezza del testo, ti ritrovi con 4 caratteri in più, mentre se vuoi tagliarlo rischi di finire con messaggi tipo "Bed & Breakfast" -> "Bed &am...". È importante salvare il testo originale nel database, e usare htmlspecialchars all'ultimo momento, solo per l'output.
    Ultima modifica di dreadnaut : 03-03-2023 alle ore 18.27.04

  3. #3
    kairos2020 non è connesso Utente giovane
    Data registrazione
    16-04-2020
    Residenza
    Castegnato (BS)
    Messaggi
    49

    Predefinito

    Grazie per la puntale risposta.
    Un esempio del "difficile da elaborare": usare htmlspecialchars trasforma & in &amp;; se dopo vuoi calcolare la lunghezza del testo, ti ritrovi con 4 caratteri in più, mentre se vuoi tagliarlo rischi di finire con messaggi tipo "Bed & Breakfast" -> "Bed &am...". È importante salvare il testo originale nel database, e usare htmlspecialchars all'ultimo momento, solo per l'output.
    Tutto chiaro e spiegato in modo semplice, il mio problema nasce appunto da un caso 'difficile da elaborare', l'apostrofo.
    Esempio, se mando in output con echo il valore stringa "Sant'Andrea Cantina" (valore preso da Mysql e salvato con ADO PREPARED STATMENT quindi sicuro) viene mostrato correttamente a video, se lo filtro con htmlspecialchars a video viene mostrato Sant&#39;Andrea Cantina ( apostrofo trasformato in &#39; ) che non è leggibile.
    Due opzioni uso o non uso htmlspecialchars ... oppure scrivo una semplicissima funzione che sostituisce in output
    la substringa &#39; con il carattere '.
    Ci sono controindicazioni, nel senso puo essere pericoloso?.
    Grazie

  4. #4
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Citazione Originalmente inviato da kairos2020 Visualizza messaggio
    Grazie per la puntale risposta.
    Esempio, se mando in output con echo il valore stringa "Sant'Andrea Cantina" (valore preso da Mysql e salvato con ADO PREPARED STATMENT quindi sicuro) viene mostrato correttamente a video, se lo filtro con htmlspecialchars a video viene mostrato Sant'Andrea Cantina ( apostrofo trasformato in ' ) che non è leggibile.
    Strano: se una pagina contiene &#39;, il browser dovrebbe mostrare il carattere corrispondente, cioè '. Se vedi proprio &#39;, il codice sorgente contiene &amp;#39;, come se avessi chiamato htmlspecialchars due volte.

    Hai un esempio online a cui possiamo dare un'occhiata?
    Ultima modifica di dreadnaut : 03-03-2023 alle ore 22.43.20

  5. #5
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,896

    Predefinito

    Sei sicuro che il tuo apostrofo originale (nel tuo caso non è la stringa di input ma la stringa recuperata dal tuo database che può essere trasformata dal tuo applicativo) con codifica percentuale
    Codice PHP:
    $var = '&' . '#39;'; // concatenazione stringa con l'operatore dot nella sintassi del linguaggio php
    var_dump(urlencode($var), htmlspecialchars($var, ENT_QUOTES | ENT_HTML401, 'UTF-8'));
    /* Risultato atteso:
    string(11) "%26%2339%3B"
    string(9) "&amp;#39;"
    */
    // Se la pagina è servita come html il browser interpreta l'entità
    Nota* la funzione htmlspecialchars se la costante ENT_QUOTES è impostata la conversione della citazione singola è &#039;
    La stringa letterale citata in mysql può anche essere raddoppiata.
    Dunque da linguaggio php che prevede una sintassi al linguaggio mysql che prevede un'altra sintassi.
    Codice PHP:
    $var = '\'\'\'\''; // escape in php che produce output ''''
    //Come menzionato sopra in mysql è indicare la citazione, se la stringa letterale citata da quattro citazioni diventa una poiché i delimitatori indicano stringa anche in mysql
    $sql = 'SELECT ' . $var;
    Ultima modifica di darbula : 04-03-2023 alle ore 02.14.15

  6. #6
    kairos2020 non è connesso Utente giovane
    Data registrazione
    16-04-2020
    Residenza
    Castegnato (BS)
    Messaggi
    49

    Predefinito

    Buongiorno,
    il link all'esempiohttp://www.kairos2020.altervista.org

    Dalla home menu AZIENDE -> GUARDA ->SELEZIONE PER INIZIALE -> S

    PAGINA 2 4° RECORD
    San Michele All&#39;Adige Ist. Agr. e nel campo accanto San Michele All'Adige Ist. Agr.

    Leggendo però la tua risposta ho un dubbio, la prima versione del sito era stata una sorta di test,
    in pratica trasformavo il codice VB con i relativi comandi PHP, funzionava tutto ma in una gara di 'spaghetti code' avrei vinto alla grande.
    Ma era giusto per fare esperienza.
    Il db che utilizzo ora è lo stesso, per quanto possibile lo rendo conforme allo standard ACID ma i dati
    sono gli stessi.
    L'inserimento dei dati funzionava così
    Codice PHP:
    $colAzi=filter_input(INPUT_POST, 'colAzi', FILTER_SANITIZE_STRING);

    $sql="INSERT INTO `commemorative` ( `colAzi`,`colCen`, `colBor`, `colCol`, `colNot`, `colVal`, `colDre`, `colRet`) VALUES (:c_cod,:c_var,:c_pro,:c_reg,:c_azi ...)"; }
    $stmt = $this->conn->prepare($sql);
    ;
    $stmt->bindparam(":c_azi",$capAzi);
    $stmt->bindparam(":c_cen",$capCen);
    ....
    $stmt->execute();
    Ho tagliato il codice inutile ma i comandi chiave erano questi.
    Da quanto hai scritto mi viene un dubbio
    L'utente inserisce San Michele All'Adige Ist. Agr.
    la funzione filter_input FILTER_SANITIZE_STRING agisce come HTMLENTITIES
    e trasforma l'apostrofo in &#39;
    poi il prepared statment che agisce ancora da filtro (semplifico) ci mette
    del suo, alla fine come dici tu 'viene fatto il pane doppio'...
    Controllo facendo delle prove e poi ti faccio sapere ... ma sono convinto che
    ancora una volta hai centarto il problema
    Grazie

  7. #7
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,896

    Predefinito

    Si i filtri
    Codice PHP:
    $var = '\''; // i dati POST potrebbero essere nella codifica percentuale (' inviato come %27) e php applica urldecode automaticamente
    var_dump(filter_var($var, FILTER_SANITIZE_SPECIAL_CHARS));
    converte in &#39; mentre htmlspecialchars in &#039;
    sanitize filters
    filter flags
    Ultima modifica di darbula : 04-03-2023 alle ore 14.45.46

  8. #8
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    Citazione Originalmente inviato da kairos2020 Visualizza messaggio
    L'utente inserisce San Michele All'Adige Ist. Agr.
    la funzione filter_input FILTER_SANITIZE_STRING agisce come HTMLENTITIES
    Hai trovato il problema! FILTER_SANITIZE_STRING fa "troppo" in questo caso, e nel database finisce la stringa già convertita per l'output. Una successiva chiamata a htmlspecialchars raddoppia l'encoding, e ti ritrovi con la sequenza invece dell'apostrofo: la situazione "1 + 3" menzionata prima.

    Forse potresti usare strip_tags al suo posto?

    Suggerirei anche di "ripulire" i dati nel database, sostituendo sequenze di escape con i caratteri originali — sempre se la cosa ha senso per l'uso che vuoi farne.
    Ultima modifica di dreadnaut : 04-03-2023 alle ore 19.39.51

  9. #9
    kairos2020 non è connesso Utente giovane
    Data registrazione
    16-04-2020
    Residenza
    Castegnato (BS)
    Messaggi
    49

    Predefinito

    Buonasera, farò quanto suggerito.
    Per avere il valore corretto nel database, ovvero : S'anta Barbara devo evitare di applicare filtri di sanificazione sui dati in entrata mentre potrò applicare htmlenties in output.
    Peraltro ricordo che nella seconda versione di un libro di Kevin Yank & Tom Butler (1a vers.2012 - 2a vers.2018), si suggeriva di non sanificare i dati in entrata ma solo in uscita, nella prima si raccomandava di sanificare sempre e comunque i dati.
    Grazie ancora per il gentile supporto e la pazienza dimostrata.

  10. #10
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,306

    Predefinito

    È solo un piacere!

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •