2014-11-21 37 views
5

Ho letto sulla strada di angolare di sfuggire tutto per default e $sce, così I bianco-list dati con $sce.trustAsHtml() attraverso il filtro (dal $sce non sta funzionando in servizio), in questo modo:parziale stringa HTML fuga in Angular.js

<sup class="ng-binding" ng-bind-html="row|logEntry"></sup> 

Ma il problema è che non mi fido di alcune parti dell'HTML.

Per immergersi nei dettagli: ho translations che contiene HTML, ma in essi sono presenti token/variabili sostituibili. Quindi, translations support HTML, ma non voglio che i token forniti includano HTML.

mio filtro logEntry sembra internamente come questo:

var translated = $translate('Log.' + msg.context.entity_type) + '.' + msg.context.action, { 
     'object_name': msg.context.object_name, 
     'user': msg.context.user_name 
}); 
return $sce.trustAsHtml(translated); 

Per esempio posso avere traduzione su userX cambiare l'articolo, ma non voglio testo del risultato per attivare alert() se il nome di utente include <script>alert('evilname')</script>

$translate di per sé non è rilevante, può essere una stringa HTML in cui voglio sostituire alcune parti con il normale JS .replace() con contenuto che rimane "come testo".

Quindi la mia domanda è - come posso evitare parti di HTML? Devo ricorrere a affettarlo in parti all'interno di una vista? O devo ricorrere alla fuga personalizzata ( Fastest method to escape HTML tags as HTML entities?)? Esiste una pratica preferita per queste cose? inizio

risposta

5

Let ristrutturando il tuo logEntry per separare i interpolateParams

var translationId = 'Log.' + msg.context.entity_type) + '.' + msg.context.action; 
var interpolateParams = { 
     'object_name': msg.context.object_name, 
     'user': msg.context.user_name 
}; 
var translated = $translate(translationId, interpolateParams); 
return $sce.trustAsHtml(translated); 

Volete fuggire tutti HTML da interpolateParams ma lasciare alcun HTML nei modelli di traduzione. Usa questo codice per copiare l'oggetto, scorrere i suoi valori e sostituirlo con HTML in escape.

var safeParams = angular.copy(interpolateParams);  
angular.forEach(safeParams, function(value, key, obj) {  
    obj[key] = encodeEntities(value) 
    // if you want safe/sanitized HTML, use this instead 
    // obj[key] = $sanitize(value); 
}); 
var translated = $translate(translationId, safeParams); 

Infine, la funzionalità di encodeEntities angolare non è esposto, così abbiamo dovuto prendere in prestito la fonte da angular-sanitize.js

var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 
    // Match everything outside of normal chars and " (quote character) 
    NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; 
function encodeEntities(value) { 
    return value. 
    replace(/&/g, '&amp;'). 
    replace(SURROGATE_PAIR_REGEXP, function(value) { 
     var hi = value.charCodeAt(0); 
     var low = value.charCodeAt(1); 
     return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; 
    }). 
    replace(NON_ALPHANUMERIC_REGEXP, function(value) { 
     return '&#' + value.charCodeAt(0) + ';'; 
    }). 
    replace(/</g, '&lt;'). 
    replace(/>/g, '&gt;'); 
} 

Aggiornamento: Dopo l'aggiornamento a angolare-translate 2.7.0 questo messaggio apparsa:

pascalprecht.translate. $ translateSanitization: Nessuna sanificazione strategia è stata confi gurate. Questo può avere serie implicazioni sulla sicurezza . Vedi http://angular-translate.github.io/docs/#/guide/19_security per dettagli.

Sp invece del trustlate risposta di cui sopra, angolare-translate può raggiungere lo stesso risultato con:

$translateProvider.useSanitizeValueStrategy('escapeParameters'); 

Vedere la documentazione per più Sanitize Valore Strategie

2

Nella tua App Aggiungi

$translateProvider.useSanitizeValueStrategy('escapeParameters'); 

In modo che, il vostro codice assomiglia this:

myApp.config(function ($translateProvider) { 

    //...whatever 

    $translateProvider.useSanitizeValueStrategy('escapeParameters'); 

});