Quali sono alcuni concetti importanti per insegnare agli sviluppatori sullo scripting cross-site (XSS)?

41

Sto aiutando con una formazione di un'ora per gli sviluppatori (circa 100 di loro) sullo scripting cross-site. Quali sono alcuni concetti che ritieni indispensabili per comunicare con loro? In questo momento abbiamo:

  • Differenza tra riflessi e memorizzati
  • Strati di difesa ( WAF , difese del browser, intestazioni del server e codifica sicura)
  • Codifica sicura e contesto dei parametri di codifica

E soprattutto, il potenziale impatto delle vulnerabilità.

    
posta mcgyver5 31.08.2016 - 20:56
fonte

7 risposte

77

Dal punto di vista dello sviluppatore, i primi due punti che hai non sono molto pertinenti. Gli XSS archiviati e riflessi hanno la stessa attenuazione: evadono correttamente le cose che si producono in base al loro contesto. Gli strati di difesa saranno probabilmente considerati solo una scusa per implementare male questa mitigazione: "Il WAF lo prenderà per me."

Concentrati invece su queste pratiche di igiene del codice:

  • Convalida, non esci, all'input. La convalida dell'input dovrebbe essere solo per garantire che l'input abbia senso, non che sia "sicuro". È impossibile sapere a questo punto se è sicuro, dal momento che non conosci tutti i posti in cui verrà utilizzato.
  • Supponiamo che tutti i dati non siano sicuri. Non presumere mai che alcuni dati siano stati sfuggiti o che non includano tag o citazioni, entità o altro. Comprendi che l'input non sicuro può provenire da qualsiasi luogo: intestazioni HTTP, cookie, parametri URL, dati di importazione bulk, ecc.
  • Escape at point of use. Escape dei dati per il contesto in cui viene utilizzato, quando viene utilizzato. Vuoi solo scappare una volta per migliorare le prestazioni? Assegna un nome alla variabile di destinazione in base a dove è sicuro: jsstringsafeEmail , htmlattrsafeColor , htmltextsafeFullName , ecc.
risposta data 31.08.2016 - 21:22
fonte
19

What are some concepts you think are indispensable to get across to them?

  • Differenza tra riflessa e archiviata - A me non interessa davvero
  • Strati di difesa - Sì. Molti sviluppatori non capiscono la "difesa in profondità". Supponiamo che ogni altra mitigazione sia fallita e che il tuo codice sia la ultima cosa che si trova tra l'attaccante e la risorsa vulnerabile. Cosa puoi fare per mitigare l'attacco?
  • Codifica sicura e contesto dei parametri di codifica - assolutamente.
  • e soprattutto, il potenziale impatto delle vulnerabilità. - assolutamente

Cos'altro? La cosa più importante che manca alla tua lista è: ci sono molti strumenti e tecniche che possono essere tutti usati per mitigare questi potenziali vulns; la difesa in profondità suggerisce che ne usiamo il maggior numero possibile.

  • Sii sicuro in base alla progettazione, sicuro per impostazione predefinita. Pensa alle vulnerabilità in tutte le fasi di progettazione e implementazione. Assicurati di scegliere fuori di essere sicuro quando necessario, senza optare in quando necessario.
  • Realizza modelli di minacce formali. Dove possono entrare i dati ostili in un sistema e dove possono andarsene? Quali sottosistemi si fidano l'un l'altro e quali no? Se non sai dove sono i confini, è difficile indurli contro gli attacchi.
  • Le stringhe sono il nemico. I dati dovrebbero fluire in oggetti intelligenti che possono essere composti in modo intelligente, non stringhe che possono essere concatenate e divise.
  • Se si utilizza una lingua con un sistema di tipi, acquisire se i dati sono macchiati o non contaminati nel sistema di tipi. Fai in modo che il compilatore ti dica che stai assegnando dati contaminati in un contesto che si aspetta dati non contaminati.
  • Se non hai un compilatore che trova i tuoi bug per te, emula un sistema di tipi nella disciplina dei nomi. Se una variabile contiene dati contaminati, è "contaminata" da qualche parte nel suo nome. Se assegni un valore alterato a una variabile che non ha "alterato" nel suo nome, hai appena riscontrato un problema durante la revisione del codice anziché quando l'autore dell'attacco ha avuto successo.
  • Utilizzare gli strumenti di analisi statici progettati dai professionisti della sicurezza per trovare questo tipo di problemi; prestare molta attenzione all'output, anche i falsi positivi . Un falso positivo indica che il codice non può essere visto come corretto da un analizzatore; ciò significa che probabilmente non può essere visto come corretto da un essere umano. Correggi il codice in modo che lo strumento non trovi più il falso positivo.
  • Metti alla prova tutto come un attaccante, non un utente. Se c'è un codice che disinfetta l'input, incaricare un membro della tua squadra di attaccarlo. I bug disinfettanti sono una fonte comune di vulnerabilità difficili da individuare.
  • Effettua test per errori di configurazione in produzione. I vulns XSS possono essere causati spegnendo accidentalmente alcune convalide o disinfezione per scopi di debug o di test e dimenticando di riaccenderlo, spingendo la configurazione sbagliata alla produzione e così via.
  • E così via.
risposta data 31.08.2016 - 23:28
fonte
9

Hai coperto gran parte delle nozioni di base. Per estendere un po 'i tuoi punti (alcuni di questi sembreranno ovvi per la maggior parte dei lettori qui, ma potrebbero non essere necessariamente ovvi per tutti gli sviluppatori):

  • XSS può avvenire tramite GET e POST.
  • XSS è anche un problema nei backend di amministrazione.
  • Esiste XSS basato su DOM.
  • Esistono difese del browser, ma si dovrebbe fare affidamento su non . Lo stesso vale per i WAF e le intestazioni del server.
  • La codifica dovrebbe avvenire quando si stampa, non quando si riceve l'input.
  • Il contesto è davvero importante. La codifica HTML non è sufficiente in alcune situazioni.
  • JavaScript e CSS che escaping / encoding sono difficili. Si consiglia l'utilizzo di una libreria esistente.
  • Tutti i parametri dovrebbero essere codificati. Non è un buon approccio solo codificare parametri che sembrano non sicuri.
  • È altamente raccomandato un ulteriore filtraggio degli input (es. se hai bisogno di un intero, controlla che sia effettivamente un numero intero, idealmente localizzato in alcune classi di Input), ma non dovrebbe mai essere l'unica linea di difesa.

Ma il punto più importante a mio parere: La codifica HTML dovrebbe avvenire automaticamente , utilizzando un motore di template che codifica per impostazione predefinita tutti i parametri.

Se la codifica avviene ovunque, è troppo facile dimenticarla solo una volta. Ovviamente è ancora importante occuparsi di tutte le situazioni in cui la codifica HTML non è sufficiente, ma la maggior parte delle vulnerabilità XSS sarà impedita dalla codifica predefinita.

    
risposta data 31.08.2016 - 21:18
fonte
6

Penso che le due lezioni più importanti da insegnare siano queste:

  1. Se stai generando markup o qualsiasi altra rappresentazione testuale strutturata (ad esempio, JSON, SQL, stringhe di query URL) in un modo ad hoc concatenando insieme le stringhe, quindi interrompi ciò che stai facendo immediatamente , e trova o crea una libreria centralizzata e sicura per la generazione di markup o DOM.
  2. Non fidarti delle strategie di prevenzione XSS che richiedono di eseguire una delle seguenti azioni:
    • Indovina cosa tenterà l'aggressore o tenterà in altro modo di superare in astuzia l'attaccante. In particolare, i filtri sul lato input hanno una storia di essere superati in astuzia dagli aggressori e dovrebbero essere considerati con sospetto.
    • Identifica, di volta in volta in contesti diversi, quali variabili sono input "non attendibili" che devi quindi trattare in modo eccezionale. (Piuttosto, tutti gli input dovrebbero essere non attendibili per impostazione predefinita: dovresti dover disattivare la protezione XSS , non optare per l'opzione.)

Sul mio primo punto: quasi tutti i problemi di iniezione derivano dal lavorare al livello di astrazione errato : i programmatori concatenano stringhe in situazioni in cui dovrebbero utilizzare operazioni di livello superiore che si allontanano dal modo corretto di fare le cose. E questo significa che:

  1. I programmatori finiscono per affrontare ripetutamente lo stesso problema complicato (correggere l'escape dei valori di stringa nel contesto in cui sono inseriti). Anche se l'hanno fatto bene ogni volta (non probabile!), Le soluzioni non sarebbero mai state riutilizzate.
  2. Poiché la responsabilità di eseguire correttamente l'escape dei valori di stringa è diffusa su tutta la base del codice anziché essere concentrata in un punto, l'auditing del codice per la sicurezza e la risoluzione dei problemi diventa più difficile di alcuni ordini di grandezza.

Sul secondo punto: una buona lezione sui pericoli derivanti dall'appoggiare il filtro sul lato input potrebbe essere la ricerca di XSS di OWASP Foglio filtrante Evasion Filter . Pensa a quella pagina come a documentare un tentativo fallito dopo l'altro e un altro a risolvere XSS attraverso il filtraggio del lato input e l'intelligenza che gli aggressori sono stati in grado di usare per aggirarlo.

Spesso vedi anche molti consigli che parlano di input "non attendibili" e di come elaborarli, che è pieno di pericoli perché:

  • Capire quali input ci si può fidare è un sacco di lavoro, in particolare quando devi farlo più e più volte;
  • potresti giudicare erroneamente quali input sono affidabili;
  • Gli input che possono essere considerati affidabili oggi potrebbero non essere affidabili domani.

Il XS Prevention Cheat Sheet di OWASP è un altro documento davvero eccellente che segue i miei due punti. Si concentra su come tranquillamente inserire stringhe arbitrarie in documenti HTML, CSS e Javascript generati dinamicamente. Se risolvi il problema in un posto (in una libreria di terze parti o nella tua base di codice) e applichi questa soluzione in modo coerente, farai molto bene - avrai "tagliato la giugulare" delle vulnerabilità XSS.

    
risposta data 31.08.2016 - 21:38
fonte
1

Hai già elencato alcuni dei concetti più importanti - l'unica cosa che aggiungerei è l'ubiquità e la facilità di test per i vulns XSS. XSS è spesso la prima vulnerabilità che viene insegnata e, dopo l'iniezione SQL, forse la più famosa. È anche banale da scannerizzare e molti scanner di applicazioni come burp e w3af saranno in grado di rilevare automaticamente XSS.

Capire questo importante perché delinea il motivo per cui xss esiste ancora: praticamente tutti i siti hanno una sorta di protezioni xss, ma sono ancora vulnerabili quando un tester o uno scanner intelligente è in grado di trovare input dell'utente di cui lo sviluppatore ha dimenticato. Per sviluppare in modo sicuro il software senza xss, gli sviluppatori devono essere consapevoli degli aggressori che utilizzano vettori dispari per inviare payload - ad es. Intestazioni HTTP, menu a discesa, tutto ciò che può essere modificato in un proxy HTTP.

    
risposta data 31.08.2016 - 21:30
fonte
1

Il punto più importante da fare, IMHO, è che dovresti sapere che cosa contiene una variabile (o un campo del database). Devi sapere se è testo (e quale charset / codifica è, in quel caso), o è HTML (o un attributo HTML, che è ancora un altro tipo di dati), o SQL, ecc.

Quindi, devi applicare alle conversioni corrette quando devi spostarti da una posizione all'altra.

Il grosso problema è che in molti casi, la rappresentazione di un pezzo di testo (probabilmente il tipo più comune di dati che è possibile manipolare) è la stessa sia che si tratti di testo, HTML, SQL, ecc. (il testo "abc" è uguale a HTML abc o SQL 'abc' ) e per questo motivo le persone tendono a concatenare i bit insieme senza alcuna conversione.

Ma ciò si interromperà non appena incontri personaggi che hanno un significato speciale in uno dei contesti. Ciò non solo porta a problemi di sicurezza (sia iniezioni XSS e SQL), ma anche a problemi di formattazione (tutti abbiamo visto siti che iniziano a mostrare entità HTML come &lt; quando dovrebbero visualizzare < ), poiché le persone dimenticano la conversione, o fallo più volte.

È abbastanza raro che sia effettivamente necessario consentire l'inserimento di un vero e proprio codice HTML. Nella maggior parte dei casi, vuoi il testo. Basta mantenere il testo così com'è, manipolarlo così com'è. Ma una volta che vuoi visualizzarlo (su una pagina HTML), convertilo in HTML (usando le librerie / framework standard e testati , non la tua ricerca e sostituzione improvvisata basata su espressioni regolari).

Allo stesso modo, lo si converte quando si vuole costruire una richiesta SQL (usando le query parametrizzate, preferibilmente). Ma lo memorizzi esattamente così com'è.

Molti framework aggiungeranno livelli di astrazione che "nasconderanno" tutto ciò se effettivamente li utilizzi. Ma sappiamo tutti che anche con gli strumenti migliori, finirai sempre con qualcuno che cerca di costruire un po 'di HTML, quindi devono sapere cosa deve essere fatto se lo fanno.

Se desideri / devi manipolare l'HTML effettivo, inserisci una dimensione completamente diversa in termini di problemi XSS. Si noti che può essere coperto in un'ora ...

    
risposta data 01.09.2016 - 16:13
fonte
0

XSS è serio

Realizza una dimostrazione di XSS per dimostrare che ha un impatto reale, oltre alert('xss') .

XSS ci influenza

Fornisci alcune statistiche, ad es. 17 difetti XSS nei nostri prodotti sono stati identificati nei test di penetrazione durante l'anno scorso.

La soluzione sta sfuggendo

Mostra loro la differenza tra codice che non sfugge, ed è vulnerabile e codice che sfugge. Tenta di nuovo la dimostrazione e vedi come fallisce.

Buona pratica di codifica

Mostra loro i modi migliori per eseguire l'escape con le lingue e i framework in uso nella tua azienda. Idealmente un motore di template che esegue l'escape automatico. Se hai una singola lingua / struttura in tutta l'azienda, questo è più facile. Altrimenti, mostra un esempio e di 'loro di leggere il particolare framework che stanno utilizzando.

Errori comuni

Contesto pagina. Anche se disponi di un motore di template di escape, i dati non attendibili all'interno di un tag <script> possono causare XSS.

Quali dati non sono attendibili? ad esempio, se recuperi un feed RSS da un sito esterno, rimane comunque un rischio XSS, anche se non è un input diretto dell'utente.

DOM XSS - utilizzando JavaScript eval e document.write può causare XSS.

Difesa in profondità

CSP è un'eccellente difesa in profondità, ma potrebbe essere difficile da implementare.

Le opzioni cookie e la convalida delle richieste possono essere facilmente implementate, ma sono solo difese parziali.

Chiedi aiuto

Quando fai qualcosa di difficile - come permettere agli utenti di usare tag HTML limitati nei commenti - chiedi aiuto a uno specialista della sicurezza.

    
risposta data 02.09.2016 - 09:44
fonte

Leggi altre domande sui tag