2009-03-30 3 views
24

Qual è il modo consigliato per evitare l'HTML per evitare le vulnerabilità XSS nelle app Rails?Escaping HTML in Rails

Se si consente all'utente di inserire qualsiasi testo nel database ma di evaderlo durante la visualizzazione? Dovresti aggiungere i filtri before_save per evitare l'input?

risposta

22

Esistono tre approcci di base a questo problema.

  1. utilizzare h() nelle visualizzazioni. Il rovescio della medaglia qui è che se ti dimentichi, ottieni pwnd.
  2. Utilizzare un plug-in che sfugge al contenuto quando viene salvato. Il mio plugin xss_terminate fa questo. Quindi non è necessario utilizzare h() nelle visualizzazioni (principalmente). Ce ne sono altri che funzionano a livello di controller. Gli svantaggi qui sono (a) se c'è un bug nel codice di escape, potresti ottenere XSS nel tuo database; e (b) Ci sono casi d'angolo in cui si vorrà comunque utilizzare h().
  3. Utilizzare un plug-in che sfugge al contenuto quando viene visualizzato. CrossSiteSniper è probabilmente il più noto di questi. Questo alias i tuoi attributi in modo che quando chiami foo.name sfugge al contenuto. C'è un modo per ovviare a questo se hai bisogno del contenuto senza caratteri di escape. Mi piace questo plugin, ma non mi preoccupo di lasciare XSS nel mio database in primo luogo ...

Poi ci sono alcuni approcci ibridi.

Non c'è motivo per cui non è possibile utilizzare xss_terminate e CrossSiteSniper allo stesso tempo.

Esiste anche un'implementazione ERb denominata Erubis che può essere configurata in modo che venga evitata qualsiasi chiamata come <%= foo.name %> - l'equivalente di <%= h(foo.name) %>. Sfortunatamente, Erubis sembra sempre in ritardo rispetto a Rails e quindi usarlo può rallentare.

Se si desidera leggere di più, ho scritto un post sul blog (che Xavor ha gentilmente collegato a) su using xss_terminate.

+0

Il tuo plugin funziona alla grande. Grazie! – djburdick

+0

Potrebbe voler aggiornare questo per Rails 3? – slhck

+1

Yuck. I dati sfuggiti nel tuo database sono una cattiva idea per la sanità mentale. – Ashe

5

Utilizzare il metodo h nel modello di visualizzazione. Diciamo che avete un oggetto post con un commento di proprietà:

<div class="comment"> 
    <%= h post.comment %> 
</div> 
13

Il h è un alias per html_escape, che è un metodo di utilità per l'escape di tutti i caratteri tag HTML:

html_escape('<script src=http://ha.ckers.org/xss.js></script>') 
# => &lt;script src=http://ha.ckers.org/xss.js&gt;&lt;/script&gt; 

Se hai bisogno di più controllo, vai con il metodo sanitize, che può essere usato come un bianco-lista di tag e attributi per consentire:

sanitize(@article.body, :tags => %w(table tr td), :attributes => %w(id class style)) 

mi permetterebbe all'utente di nulla di ingresso, conservarla così com'è nel database, e la fuga quando visualizzarlo . In questo modo non perderai nessuna informazione inserita. È sempre possibile modificare la logica di escape in seguito ...

+0

In secondo luogo, il movimento di consentire agli utenti di inserire qualcosa e di uscire solo nei display. xss_terminate è bello ma può essere lento e rende molto più difficile l'aggiornamento a Rails 3. – simianarmy

0

Ho appena rilasciato un plug-in chiamato ActsAsSanitiled utilizzando la gemma Sanitize che può garantire una buona formazione e molto configurabile a quale tipo di HTML è consentito, tutto senza input utente munging o che richiede qualcosa da ricordare nel modello livello.