Disinfezione dell'input per query parametrizzate

10

Se utilizzo query completamente parametrizzate ovunque, è ancora necessario e / o rilevante per la sicurezza per in qualche modo disinfettare l'input? Per esempio. controllare che gli indirizzi di posta siano validi prima di inviare una query parametrizzata al database o filtrare determinati caratteri speciali dal testo?

Penso a strumenti di terze parti benevoli, ma non così ben progettati (magari script autodidattici da parte dell'amministratore, o alcuni fantasiosi CrystalReports realizzati da un non tecnico) che cercano di consumare dati non pubblicitari dal nostro database.

Al momento, abbiamo un completo supporto Unicode contro SQL Server (MySQL sembra avere problemi con Emojis), non sono sicuro di come filtrare i rischi per la sicurezza senza perdere quella proprietà.

    
posta Alexander 27.10.2017 - 13:09
fonte

3 risposte

12

No, non è necessario. Ma per favore, continua a leggere.

L'input sanitizzazione è un termine orribile che finge di poter agitare una bacchetta magica con dati e renderli "dati sicuri". Il problema è che la definizione di "sicuro" cambia quando i dati vengono interpretati da diversi software.

I dati che potrebbero essere sicuri di essere incorporati in una query SQL potrebbero non essere sicuri per l'incorporamento in HTML. O JSON. O comandi di shell. O CSV. E spogliare (o addirittura rifiutare) i valori in modo che siano sicuri per l'incorporamento in tutti quei contesti (e molti altri) è troppo restrittivo.

Quindi cosa dovremmo fare? Assicurati che i dati non siano mai in grado di fare del male.

Il modo migliore per ottenere questo è evitare l'interpretazione dei dati in primo luogo. Le query SQL parametrizzate sono un eccellente esempio di questo; i parametri non vengono mai interpretati come SQL, vengono semplicemente inseriti nel database come, beh, dati.

Per molte altre situazioni, i dati devono ancora essere incorporati in altri formati, ad esempio HTML. In quel caso, i dati dovrebbero essere salvati per quella specifica lingua nel momento in cui è incorporata. Quindi, per prevenire l'XSS, i dati sono sfuggiti in HTML al momento della visualizzazione. Non al momento dell'inserimento. Lo stesso vale per altre situazioni di incorporamento.

Quindi, se dovessimo semplicemente passare qualcosa, andremo direttamente al database?

Forse. Dipende.

Ci sono sicuramente cose che puoi controllare sull'input dell'utente, ma questo è altamente dipendente dal contesto. Poiché la sanitizzazione è mal definita e mal utilizzata, preferisco chiamare questa validazione .

  • Ad esempio, se si suppone che un campo sia un numero intero, puoi certamente convalidare questo campo per assicurarti che contenga un numero intero (o forse NULL).
  • Puoi certamente fare qualche convalida sui campi email (anche se alcune persone sostengono che non c'è molto che puoi fare oltre a verificare la presenza di un @ , e hanno un buon punto).
  • Puoi richiedere che i commenti abbiano una lunghezza minima e massima.
  • Probabilmente dovresti verificare che ogni stringa contenga solo caratteri validi per la sua codifica (ad esempio, nessuna sequenza UTF-8 non valida).
  • Puoi limitare un nome utente a determinati caratteri, se questo ha senso per la tua base utente.
  • Una lunghezza minima per le password è, ovviamente, incredibilmente comune.

Come puoi vedere, questi controlli sono molto dipendenti dal contesto. E tutti loro servono ad aumentare le probabilità che si finisca con dati che hanno senso. Non devono proteggere la tua applicazione da input dannosi (SQL injection, XSS, command injection, ecc.), Perché questo non è il posto giusto per farlo.

Gli utenti dovrebbero essere liberi di digitare '; DROP TABLE users; -- senza che il loro post venga rifiutato o ridotto a \'; DROP TABLE users; -- . Tieni presente che sono in grado di includere contenuti "dannosi" su sec.SE!

Quindi, per rispondere alla tua domanda iniziale:

... is it still necessary and/or security-relevant to somehow sanitize input?

No, non lo è. Ma per favore fai in modo che i dati vengano correttamente rimossi prima di emetterli. E considera le convalide, se possibile.

I think of benign, but not-so-well-engineered 3rd party tools (maybe self-written scripts by the admin, or some fancy CrystalReports made by a non-technician) trying to consume unsanitized data from our database.

Quindi sfuggi o filtra i dati prima di emettere tali strumenti, ma non manipolare i dati nel tuo database.

Ma in realtà, quegli script dovrebbero essere corretti, o riscritti pensando alla sicurezza.

(MySQL seems to have problems with Emojis)

Poco fuori tema, ma dai un'occhiata a utfmb4 charset per MySQL;)

    
risposta data 27.10.2017 - 19:02
fonte
8

If I use fully parameterized queries everywhere, is it still necessary and/or security-relevant to somehow sanitize input?

Sì. È sempre una buona idea disinfettare l'input prima di inviarlo al database.

Le query parametrizzate potrebbero salvarti dagli attacchi di SQL injection, ma potrebbero non rivelarsi utili in caso di attacchi XSS archiviati. Se un utente invia un codice javascript dannoso nel modulo e lo memorizza correttamente nel database, e lo stesso campo viene visualizzato altrove, lo script dannoso potrebbe essere eseguito sul browser della vittima.

È sempre una buona idea disinfettare l'input prima di inviarlo in anticipo e disinfettare l'output prima di inviarlo al browser del client.

EDIT: Come indicato nei commenti, l'igienizzazione è diversa dai valori di codifica / escape. La sanificazione, qui, ha significato che gli input possono essere convalidati per alcuni controlli di base prima di trasmetterli al database (o qualsiasi altro livello). Ad esempio, un campo che si aspetta un indirizzo e-mail può essere convalidato per un indirizzo e-mail valido, un campo per età può essere convalidato solo per l'intero, ecc. Le espressioni regolari dimostrano di essere di grande aiuto qui. Va notato che questi controlli devono essere effettuati sul front-end (lato client) e sul back-end.

In caso di campi che prevedono il rich text, puoi implementare Policy di sicurezza del contenuto nelle pagine in cui verrà visualizzato l'input dell'utente. Puoi anche utilizzare un disinfettante HTML per disinfettare l'input dell'utente.

    
risposta data 27.10.2017 - 13:15
fonte
2

Sì, dovresti sempre disinfettare i dati di input. I servizi igienico-sanitari non servono solo a proteggerti dall'iniezione, ma anche a convalidare tipi, valori limitati (enumerazioni), intervalli, ecc. Mentre un utente malintenzionato potrebbe non essere in grado di manipolare il tuo sql, possono comunque causare un comportamento indesiderato nel resto di la tua applicazione.

Ad esempio, se un utente malintenzionato ha modificato un valore enum, potrebbe manipolare il sistema? Hanno appena cambiato un ruolo, tipo di utente, ecc ...? In alternativa, potrebbero immettere un valore maggiore di quello che può essere accettato nello schema o il tipo di dati (byte v int32, int64), ciò potrebbe causare l'arresto anomalo dell'applicazione che espone informazioni o lascia dati modificati (non transati).

    
risposta data 27.10.2017 - 15:49
fonte

Leggi altre domande sui tag