26

Stiamo costruendo un'app, la nostra prima utilizzando Rails 3, e stiamo costruendo I18n dall'inizio. Essendo perfezionisti, vogliamo che la vera tipografia venga usata nelle nostre opinioni: trattini, virgolette incurvate, ellissi e altri.Prevenire le entità di caratteri HTML nei file delle impostazioni locali dall'ottenere la protezione xss da Rails3

Questo significa nelle nostre file/xx.yml locali abbiamo due scelte:

  1. reale utilizzo caratteri UTF-8 in linea. Dovrebbe funzionare, ma è difficile da scrivere, e mi spaventa a causa della quantità di software che fa ancora i cattivi cose da unicode.
  2. Utilizzare le entità di carattere HTML (& # 8217; & # 8212; ecc.). Più facile da digitare, e probabilmente più compatibile con il software di comportamento anomalo .

Preferisco prendere la seconda opzione, ma l'auto-fuga in Rails 3 rende questa problematica, in quanto i segni & del YAML ottenere automaticamente convertiti in entità carattere se stessi, con conseguente 'visibile' & 8217; s nel browser.

Ovviamente questo può essere aggirato utilizzando raw sulle corde, vale a dire:

raw t('views.signup.organisation_details') 

Ma non siamo felici di andare verso il basso il percorso di livello mondiale raw -ing ogni volta che t qualcosa come ci lascia aperta fare un errore e produrre un buco XSS.

Potremmo selettivamente le stringhe raw che sappiamo contenere entità di carattere, ma questo sarebbe difficile da ridimensionare, e semplicemente si sente sbagliato - inoltre, una stringa che contiene un'entità in una lingua non può in un'altra.

Qualche suggerimento su un modo intelligente per risolvere questo problema? O siamo condannati a fare schifo di tipografia, buchi xss, ore di sforzi inutili o tutto il tempo?

+2

che è una buona domanda specifica per caso :). in attesa di una buona risposta. –

risposta

32

C'è una ticket in lighthouse per questo problema, e la risoluzione è di aggiungere _html alla chiave i18n nel file locales/xx.yml e utilizzare le t alias per indicare una stringa html_safe. Ad esempio:

en: 
    hello: "This is a string with an accent: ó" 

diventa:

en: 
    hello_html: "This is a string with an accent: ó" 

Ed creerebbe il seguente output:

Questa è una stringa con un accento: & oacute;

Ciò eviterebbe di dover scrivere raw t('views.signup.organisation_details') e si tradurrebbe in una produzione più pulita di: t('views.signup.organisation_details_html'). E mentre lo scambio di raw per _html non sembra il più grande degli scambi, rende chiaro che stai trasmettendo ciò che si presume essere una stringa html_safe.


Ho testato il codice suggerito nel biglietto faro. Quello che ho trovato è stato che dovevi usare in modo specifico l'alias t. Se è stato utilizzato I18n.t o I18n.translate la traduzione non trattasse _html come html_safe:

I18n.t('hello_html') 
I18n.translate('hello_html') 
# Produces => "This is a string with an accent: ó" 

t('hello_html')  
# Produces => "This is a string with an accent: ó" 

non credo che questo è il comportamento previsto per il RoR TranslationHelper documentation.

8

Bene. Ho postato questa domanda ieri per via dell'angolo di i18n, ma non ho risposto perché sono una persona di Python che non ha mai usato Rails. Non ho ancora intenzione di rispondere, ma dato che non sei invaso da utili Railsiani che potrebbero indicarti un buon modo per aggirare le interiora di Rails, ecco comunque la mia prospettiva.

Prima di tutto penso che sia grande che stai pensando al problema sin dall'inizio. È piuttosto raro. In secondo luogo, sono completamente d'accordo sul fatto che usare stringhe grezze o selezionare selettivamente stringhe con entità per dare un trattamento speciale a suoni come un trucco fragile, brutto e soggetto a bug.

Ora se ho compreso correttamente Rails (ho letto), i file YAML contengono la stringa localizzata per ogni lingua. In questo caso, raccomando vivamente di utilizzare caratteri regolari al loro interno (in UTF-8). Altrimenti, mantenendo le localizzazioni, o anche leggendo attraverso un file di traduzione - pensa alle lingue in script non latini! - sta per essere un inferno.

Sì, vorrebbe dire che devi capire i metodi di input, ma la soluzione è semplice e pulita.

+0

sì, basta inserire tutti i caratteri codificati UTF-8 nel file. È ciò che i ragazzi di Java hanno fatto fin dai dinosauri - guarda in tutti i loro file .properties della loro lingua e vedrai le codifiche native. –

+0

+1, sono completamente d'accordo. –

+1

In retrospettiva, penso che questa sia forse la soluzione migliore. Non so perché ero così avverso ad esso 3 anni fa. –

0

Sei a conoscenza del metodo html_safe che può essere utilizzato negli helper? Non sono sicuro di aver capito completamente il problema poiché non ho mai lavorato con I18n, ma sarebbe possibile utilizzare un helper personalizzato che determina se i caratteri non devono essere sfuggiti e restituire "string" .html_safe, e se dovrebbe essere sfuggito, restituire "stringa".

O forse l'override del helper "t" e aggiungi le condizioni logiche che sfuggono + .html_safe

+0

Non ne so abbastanza del problema (e della 'Rails Way') per sapere se questo è un buon piano o un'altra strada da rovinare, ma grazie per il pensiero ... Potresti provarlo e farti sapere come va. –

0

penso che non è una buona idea quella di utilizzare l'uso "cruda", si potrebbe provare con lo spago yml come questo

en: 
    hello: 
    This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in 
    these lines, is being concatenated together to one single text node, and then put 
    into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 

HTML

This generates a text paragraph for HTML. &quot; &quot; à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the &lt;p&gt; ... &lt;/p&gt; tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 

vista del browser

This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 
1

Se non vuoi esporre alla possibilità di un errore aggiungendo semplicemente .html_safe (tramite alias_method_chain o w/e) a tutto, la soluzione migliore è semplicemente usarla quando è necessario.

Nel nostro sito viene utilizzato il linguaggio di markup per ottenere l'output HTML dai file locali i18n, poiché chi li traduce non è uno sviluppatore, ma solo un traduttore.

Se solo in alcuni punti è necessario che il codice HTML sia realmente HTML, utilizzare.html_safe

t('views.signup.organisation_details').html_safe 

La semplice linguaggio di markup che abbiamo funziona piuttosto bene per noi, ma che è in realtà

Problemi correlati