Domanda

L'utente equivale a inaffidabile.Non fidarti mai dell'input di un utente inaffidabile.Lo capisco.Tuttavia, mi chiedo quale sia il momento migliore per disinfettare l'input.Ad esempio, memorizzi ciecamente l'input dell'utente e poi lo sanitizzi ogni volta che vi si accede/utilizza, oppure sanitizzi immediatamente l'input e poi memorizzi questa versione "pulita"?Forse ci sono anche altri approcci a cui non ho pensato oltre a questi.Mi propendo maggiormente verso il primo metodo, perché tutti i dati provenienti dall'input dell'utente devono comunque essere affrontati con cautela, laddove i dati "puliti" potrebbero ancora inconsapevolmente o accidentalmente essere pericolosi.In ogni caso, quale metodo la gente ritiene sia migliore e per quali ragioni?

È stato utile?

Soluzione

Mi piace disinfettarlo il prima possibile, il che significa che la sanificazione avviene quando l'utente tenta di inserire dati non validi.Se c'è una casella di testo per la loro età e digitano qualcosa di diverso da un numero, non lascio passare la pressione del tasto per la lettera.

Quindi, qualunque cosa stia leggendo i dati (spesso un server), eseguo un controllo di integrità quando leggo i dati, solo per assicurarmi che nulla sfugga a causa di un utente più determinato (come la modifica manuale di file o anche la modifica di pacchetti !)

Modificare:Nel complesso, disinfetta presto e disinfetta ogni volta che perdi di vista i dati anche per un secondo (ad es.Salva file -> Apri file)

Altri suggerimenti

Sfortunatamente, quasi nessuno dei partecipanti capisce mai chiaramente di cosa sta parlando.Letteralmente.Solo @Kibbee è riuscito a farcela.

Questo argomento riguarda la sanificazione.Ma la verità è che una cosa come la cosiddetta “sanificazione per uso generale” di cui tutti sono così ansiosi di parlare è semplicemente non esiste.

Ci sono un'infinità di mezzi diversi, ciascuno richiede è una formattazione dei dati propria e distinta. Inoltre - anche un singolo mezzo richiede una formattazione diversa per le sue parti.Supponiamo che la formattazione HTML sia inutile per JavaScript incorporato nella pagina HTML.Oppure la formattazione della stringa è inutile per i numeri nella query SQL.

È un dato di fatto, una tale "sanificazione il più presto possibile", come suggerito nella maggior parte delle risposte votate, è semplicemente impossibile.Perché non è proprio possibile sapere in quale mezzo o in quale parte del mezzo verranno utilizzati i dati.Diciamo che ci stiamo preparando a difenderci dalla "sql-injection", sfuggendo a tutto ciò che si muove.Ma ops!- alcuni campi obbligatori non sono stati compilati e dobbiamo compilare nuovamente i dati nel modulo anziché nel database...con tutte le barre aggiunte.

D'altra parte, abbiamo diligentemente evitato tutti gli "input dell'utente"...ma nella query SQL non abbiamo virgolette attorno ad esso, poiché è un numero o un identificatore.E nessuna "sanificazione" ci ha mai aiutato.

D'altra parte, okay, abbiamo fatto del nostro meglio per eliminare il terribile, inaffidabile e disprezzato "input dell'utente"...ma in qualche processo interno abbiamo utilizzato proprio questi dati senza alcuna formattazione (dato che abbiamo già fatto del nostro meglio!) - e whoops!ho ottenuto l'iniezione di secondo ordine in tutto il suo splendore.

Quindi, dal punto di vista dell'utilizzo nella vita reale, l'unico modo corretto sarebbe

  • formattazione, non qualunque "sanificazione"
  • subito prima dell'uso
  • secondo determinate regole del mezzo
  • e anche seguendo le sottoregole richieste per le diverse parti di questo mezzo.

Disinfetto i miei dati utente in modo molto simile a Radu...

  1. Primo lato client utilizzando sia Regex che prendendo il controllo su caratteri ammissibili input in campi di modulo determinati utilizzando JavaScript o jQuery legati agli eventi, come Onchange o Onbur, che rimuove qualsiasi input non consentito prima ancora che possa essere inviato.Renditi conto, tuttavia, che questo ha davvero l'effetto di far sapere a quegli utenti, che i dati verranno controllati anche sul lato server.È più un avvertimento di qualsiasi protezione effettiva.

  2. In secondo luogo, e raramente lo vedo più in questi giorni, che il primo controllo è stato fatto dal lato server è verificare la posizione da dove viene inviato il modulo.Consentendo solo l'invio del modulo da una pagina che hai designato come una posizione valida, è possibile uccidere lo script prima ancora di leggere qualsiasi dati.Certo, che di per sé è insufficiente, poiché un buon hacker con il proprio server può "fare la parodia" sia il dominio che l'indirizzo IP per far apparire al tuo script che proviene da una posizione di modulo valida.

  3. Poi, e non dovrei nemmeno dirlo, ma sempre, e dico SEMPRE, Esegui gli script in modalità DEAT.Questo ti costringe a non diventare pigro e ad essere diligente riguardo al passaggio numero 4.

  4. Sanitare i dati dell'utente il prima possibile utilizzando regex ben formati appropriati ai dati previsti da un determinato campo del modulo.Non prendere scorciatoie come il famigerato 'corno magico dell'unicorno' per superare i tuoi controlli di contaminazione...Oppure puoi anche disattivare il controllo di Taint in primo luogo per tutto il bene che farà per la tua sicurezza.È come dare a uno psicopatico un coltello affilato, con la gola e dire "non mi farai del male a quello che vuoi".

    Ed qui è dove differisco la maggior parte degli altri in questo quarto passo, poiché solo sanificato i dati dell'utente che utilizzerò effettivamente in un modo che può presentare un rischio per la sicurezza, come qualsiasi chiamata di sistema, incarichi ad altre variabili o qualsiasi scrittura per archiviare i dati.Se sto solo usando l'input dei dati da parte di un utente per fare un confronto con i dati che ho memorizzato sul sistema da solo (quindi sapendo che i dati miei sono sicuri), allora non mi preoccupo di disinfettare i dati dell'utente, come i Non ci va mai un modo che si presenta come un problema di sicurezza.Ad esempio, prendi un input del nome utente come esempio.Uso l'input del nome utente da parte dell'utente solo per verificarlo rispetto a una partita nel mio database e se vero, dopo di che utilizzo i dati del database per eseguire tutte le altre funzioni che potrei chiamarlo nello script, sapendo che è sicuro , e non utilizzare mai più i dati degli utenti dopo.

  5. Infine, è quello di filtrare tutti i tentativi auto-submiti dai robot in questi giorni, con un sistema di "autenticazione umana", come CAPTCHA.Questo è abbastanza importante in questi giorni che mi sono preso il tempo di scrivere il mio schema di "autenticazione umana" che usa le foto e un input per l '"umano" per inserire ciò che vedono nella foto.L'ho fatto perché ho scoperto che i sistemi di tipo Captcha infastidiscono davvero gli utenti (puoi dirlo dai loro occhi socchiusi dal tentativo di decifrare le lettere distorte ...di solito più e più volte).Ciò è particolarmente importante per gli script che utilizzano Sendmail o SMTP per e-mail, in quanto questi sono i preferiti per i tuoi spam-bot affamati.

Per concludere in poche parole, lo spiegherò come faccio a mia moglie...Il tuo server è come un nightclub popolare e più buttafuori hai, meno guai è probabile che tu abbia in discoteca.Ho due buttafuori fuori dalla porta (convalida lato client e autenticazione umana), un buttafuori proprio all'interno della porta (controllo della posizione valida per l'invio del modulo..."È davvero tu su questo ID") e molti altri buttafuori nelle immediate vicinanze della porta (eseguendo la modalità di contaminazione e utilizzando buoni regex per controllare i dati dell'utente).

So che questo è un post più vecchio, ma l'ho ritenuto abbastanza importante per chiunque lo legga dopo la mia visita qui per rendersi conto che il loro non è "proiettile magico' quando si tratta di sicurezza, ed è necessario che tutti questi lavorino in sinergia tra loro per rendere sicuri i dati forniti dagli utenti.Usare solo uno o due di questi metodi da soli è praticamente inutile, poiché il loro potere esiste solo quando si uniscono tutti insieme.

O in sintesi, come diceva spesso mia mamma...'Meglio prevenire che curare".

AGGIORNAMENTO:

Un'altra cosa che sto facendo in questi giorni è codificare in Base64 tutti i miei dati e quindi crittografare i dati Base64 che risiederanno nei miei database SQL.Per archiviarli in questo modo è necessario circa un terzo di byte totali in più, ma a mio parere i vantaggi in termini di sicurezza superano la dimensione aggiuntiva dei dati.

Dipende da che tipo di sanificazione stai facendo.

Per proteggersi dall'SQL injection, non fare nulla ai dati stessi.Usa semplicemente istruzioni preparate e, in questo modo, non devi preoccuparti di fare confusione con i dati immessi dall'utente e di far sì che influenzino negativamente la tua logica.Devi disinfettare un po', per assicurarti che i numeri siano numeri e le date siano date, poiché tutto è una stringa poiché proviene dalla richiesta, ma non provare a fare alcun controllo per fare cose come bloccare parole chiave o altro.

Per proteggersi dagli attacchi XSS, sarebbe probabilmente più semplice correggere i dati prima che vengano archiviati.Tuttavia, come altri hanno già detto, a volte è bello avere una copia intatta di ciò che l'utente ha inserito, perché una volta modificato, viene perso per sempre.È quasi un peccato che non esista un modo infallibile per garantire che l'applicazione pubblichi solo HTML ripulito nel modo in cui puoi assicurarti di non essere catturato dall'iniezione SQL utilizzando query preparate.

La cosa più importante è essere sempre coerenti quando scappi.La doppia sanificazione accidentale è noiosa e la mancata sanificazione è pericolosa.

Per SQL, assicurati solo che la libreria di accesso al database supporti variabili di associazione che sfuggono automaticamente ai valori.Chiunque concateni manualmente l'input dell'utente su stringhe SQL dovrebbe saperlo meglio.

Per l'HTML preferisco scappare all'ultimo momento possibile.Se distruggi l'input dell'utente, non potrai più recuperarlo e, se commette un errore, potrà modificarlo e correggerlo in seguito.Se distruggi il loro input originale, sparirà per sempre.

Presto va bene, sicuramente prima di provare ad analizzarlo.Tutto ciò che verrà generato in seguito, o in particolare passato ad altri componenti (ad esempio, shell, SQL, ecc.) deve essere disinfettato.

Ma non esagerare: ad esempio, le password vengono sottoposte ad hashing prima di memorizzarle (giusto?).Le funzioni hash possono accettare dati binari arbitrari.E non stamperai mai una password (giusto?).Quindi non analizzare le password e non disinfettarle.

Inoltre, assicurati di eseguire la disinfezione da un processo affidabile: JavaScript/qualsiasi cosa sul lato client è peggio dell'inutile sicurezza/integrità.(Tuttavia, fallire presto potrebbe fornire un'esperienza utente migliore: basta farlo in entrambi i posti.)

Perl ha un'opzione taint che considera tutto l'input dell'utente "contaminato" finché non viene controllato con un'espressione regolare.I dati contaminati possono essere utilizzati e distribuiti, ma contaminano tutti i dati con cui entrano in contatto finché non sono incontaminati.Ad esempio, se l'input dell'utente viene aggiunto a un'altra stringa, anche la nuova stringa verrà contaminata.Fondamentalmente, qualsiasi espressione che contiene valori contaminati produrrà un risultato contaminato.

I dati contaminati possono essere gettati in giro a piacimento (contaminando i dati man mano che vengono utilizzati), ma non appena vengono utilizzati da un comando che ha effetto sul mondo esterno, lo script Perl fallisce.Quindi, se utilizzo dati contaminati per creare un file, costruire un comando shell, cambiare directory di lavoro, ecc., Perl fallirà con un errore di sicurezza.

Non sono a conoscenza di un'altra lingua che abbia qualcosa come "contaminazione", ma usarla mi ha aperto gli occhi.È sorprendente la rapidità con cui i dati contaminati si diffondono se non vengono contaminati immediatamente.Cose che sono naturali e normali per un programmatore, come impostare una variabile in base ai dati dell'utente o aprire un file, sembrano pericolose e rischiose con la contaminazione attivata.Quindi la migliore strategia per portare a termine le cose è incontaminare non appena si ottengono dati dall'esterno.

E sospetto che sia il modo migliore anche in altre lingue:convalidare immediatamente i dati dell'utente in modo che bug e buchi di sicurezza non possano propagarsi troppo lontano.Inoltre, dovrebbe essere più semplice controllare il codice per individuare eventuali falle di sicurezza se le potenziali falle si trovano in un unico posto.E non puoi mai prevedere quali dati verranno utilizzati per quale scopo in seguito.

La mia opinione è di disinfettare l'input dell'utente non appena possibile lato client e lato server, lo sto facendo in questo modo

  1. (lato client), consentire all'utente di inserire solo chiavi specifiche nel campo.
  2. (lato client), quando l'utente va al campo successivo utilizzando OnBlur, testare l'input che ha inserito contro un regexp e nota l'utente se qualcosa non va bene.
  3. (lato server), testare nuovamente l'input, se il campo dovrebbe essere un controllo intero per quello (in PHP è possibile utilizzare IS_numeric ()), se il campo ha un formato ben noto, controllalo contro un regexp, tutti gli altri (come i commenti di testo), Basta sfuggire a loro.Se qualcosa è sospetto, interrompi l'esecuzione dello script e restituisci un avviso all'utente che i dati immessi non sono validi.

Se qualcosa sembra davvero un possibile attacco, lo script mi ​​invia un'e-mail e un SMS, così posso controllare e forse prevenirlo il prima possibile, devo solo controllare il registro in cui sto accedendo a tutti gli input dell'utente, e i passaggi eseguiti dallo script prima di accettare l'input o rifiutarlo.

Pulisci i dati prima di archiviarli.Generalmente non dovresti esibirti QUALUNQUE Azioni SQL senza prima pulire l'input.Non vuoi sottoporti a un attacco SQL injection.

In un certo senso seguo queste regole di base.

  1. Esegui solo la modifica di azioni SQL, come INSERT, UPDATE, DELETE tramite POST.Non OTTIENI mai.
  2. Fuggire da tutto.
  3. Se ti aspetti che l'input dell'utente sia qualcosa, assicurati di controllare che sia quel qualcosa.Ad esempio, stai richiedendo un numero, quindi assicurati che sia un numero.Utilizzare le convalide.
  4. Usa i filtri.Elimina i caratteri indesiderati.

Gli utenti sono cattivi!

Beh, forse non sempre, ma il mio approccio è quello di sanitizzare sempre immediatamente per garantire che nulla di rischioso si avvicini al mio backend.

Il vantaggio aggiuntivo è che puoi fornire un feedback all'utente se sanitizzi il punto di input.

Supponiamo che tutti gli utenti siano dannosi.Disinfettare tutti gli input il prima possibile.Punto.

Disinfetto i miei dati subito prima di eseguirne qualsiasi elaborazione.Potrebbe essere necessario prendere i campi Nome e Cognome e concatenarli in un terzo campo che verrà inserito nel database.Pulirò l'input prima ancora di eseguire la concatenazione in modo da non ricevere alcun tipo di errore di elaborazione o inserimento.Prima è meglio è.Anche l'utilizzo di Javascript sul front-end (in una configurazione Web) è l'ideale perché ciò avverrà senza che alcun dato venga inviato al server.

La parte spaventosa è che potresti persino voler iniziare a disinfettare anche i dati che escono dal tuo database.La recente ondata di attacchi ASPRox SQL Injection che si sono verificati è doppiamente letale perché infetterà tutte le tabelle di database in un determinato database.Se il tuo database è ospitato da qualche parte dove ci sono più account ospitati nello stesso database, i tuoi dati vengono danneggiati a causa dell'errore di qualcun altro, ma ora ti sei unito ai ranghi di hosting di malware per i tuoi visitatori senza alcuna colpa iniziale da parte tua .

Sicuramente questo richiede molto lavoro in anticipo, ma se i dati sono critici, allora è un investimento degno.

Trovo che pulirlo subito abbia due vantaggi.Innanzitutto, puoi convalidarlo e fornire feedback all'utente.Due: non devi preoccuparti di consumare i dati in altri posti.

L'input dell'utente deve essere sempre considerato dannoso prima di essere trasferito ai livelli inferiori dell'applicazione.Gestisci sempre gli input di sanificazione il prima possibile e non devono per nessun motivo essere archiviati nel database prima di aver verificato eventuali intenti dannosi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top