2016-01-20 5 views
7

Ich habe einen Übersetzungsschlüssel, der eigentlich ein HTML-Code ist, sowohl codiert als auch uncodiert.Angular translate richtlinie vs filter: ist XSS möglich?

$scope.translations = { 
    "html_code" : "<script>alert('Alert!');</script>", 
    "html_code_full" : "<script>alert('Alert!');</script>", 
    "greeting" : "Welcome!" 
    } 

Wenn ich diese Werte verwenden, den übersetzten Text in Ansicht anzuzeigen, verwende ich zwei Methoden:

  1. Als Richtlinie <span translate>{{translations.html_code}}</span>
  2. als Filter {{translations.html_code|translate}}

ich das gleiche versuchen für translations.html_code_full. Hier ist der Code für die Ansicht:

translations.html_code = {{translations.html_code|translate}} 
translations.html_code = <span translate>{{translations.html_code}}</span> 

translations.html_code_full = {{translations.html_code_full|translate}} 
translations.html_code_full = <span translate>{{translations.html_code_full}}</span> 

Dies ist die Ausgabe erhalte ich:

translations.html_code = &lt;script&gt;alert('Alert!');&lt;/script&gt; 
translations.html_code = <script>alert('Alert!');</script> 


translations.html_code_full = <script>alert('Alert!');</script> 
translations.html_code_full = 

Wie es klar ist, dass die Richtlinie die Umsetzung der Übersetzungsschlüssel auf HTML codiert, aber Filter nicht. Warum ist der Unterschied in der Ausgabe zwischen Direktive und Filterimplementierung? Und warum erhalte ich keine Warnung, wenn der HTML-Code gerendert wird?

Here is the plunk ich für Demo erstellt.

Antwort

1

Der AngularJS-Rahmen schützt Ihre Anwendung vor XSS-Angriffen.

Cross-Site-Scripting auf Websites durchgeführt entfielen rund 84% aller von Symantec dokumentierten Sicherheitslücken ab 2007.

- Wikipedia - Cross-site scripting

Also, was Sie sind wirklich versuchen zu tun? Vielleicht können wir Ihnen zeigen, wie Sie es auf sichere Weise tun können.

+0

Genau das habe ich versucht. In einer anderen Web-App konnte ich die Warnung erhalten, aber irgendwie konnte ich in der Demo nicht reproduzieren. Ich wollte nur den * sichereren Weg wissen, um translate zu verwenden, d. H. Filter vs directive, um XSS zu verhindern. –

+0

Ein guter Einstieg ist der [AngularJS Developer Guide - Sicherheit] (https://docs.angularjs.org/guide/security). Sehen Sie sich dann die [AngularJS $ sce API-Referenz] (https://docs.angularjs.org/api/ng/service/$sce) an. SCE hilft dabei, Code so zu schreiben, dass (a) standardmäßig sicher ist, und (b) das Auditing auf Sicherheitslücken wie XSS, Clickjacking usw. viel einfacher macht. – georgeawg

+2

Ich habe das gleiche Problem. Ich kann einen CSS-Angriff lokal in meiner App mit der Translate-Richtlinie reproduzieren, während der Filter sicher zu sein scheint - aber wenn ich versuche, ein Plunkr zu machen, das dieses Problem widerspiegelt, funktioniert das CSS nicht und das Skript wird korrekt herausgefiltert. versuchte Versionen 2.8.1 und 2.9.0 von ng-translate. versuchte verschiedene Sanitaze-Strategien, aber auch nicht funktioniert. Ich frage mich, ob es da draußen ein Sicherheitsloch für die Übersetzungsrichtlinie gibt. –

0

Für mich umfasste die Übersetzungsbibliothek nicht alle Instanzen. Also musste ich einen normalen Skriptangriff und einen gezielten Angularangriff behandeln. Wir lesen einen Teil einer URL als Schlüssel und zeigen ihn dann als Nachricht an, die in der URL angreifbar ist.

Die 2 URLs, die ich gegen getestet:

/mypage.html#/{{{}.")));alert(1)//";}} 

mypage.html#/%3Cscript%3Ealert('foo')%20%3C/script%3E 

Für mich ist die erste richtig entgangen wäre, wenn die Richtlinie in der Seite übersetzen verwenden, aber nicht den Filter. Der zweite war ein erfolgreicher Angriff, wenn die Direktive auf der Seite verwendet wurde, aber bei der Verwendung des Filters korrekt gemasked wurde.

Am Ende habe ich geflutet, übersetzt und in den Controller eingecheckt, bevor Sie den Wert der Scope-Variable zuweisen. Jetzt gibt es keine Übersetzungsdirektive oder Filter auf der Seite.

function translateParam(paramData, defaultKey){ 
     var deferred = $q.defer(); 
     var trusted = $sce.trustAsHtml(paramData); 
     $translate(trusted).then(
      function(translatedString){ 
       if(translatedString == trusted){ 
        //no key has been found so show a default 
        deferred.resolve($translate.instant(defaultKey)); 
       } 
       else{ 
        //the key has been found correclty 
        deferred.resolve(translatedString); 
       } 
      } 
     ); 
     return deferred.promise; 
    } 

//called like this 
    $scope.error = translateParam('keyFromURL','defaultKeyInTranslateFile'); 

Sie müssen $ q, $ sce und $ translate injizieren. Für mich ist dies die sicherste und zuverlässigste Lösung.

Verwandte Themen