Angular translate directive vs filter: is XSS possible?

I have a translation key, which is actually HTML code, both encoded and unencoded.

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

When I use these values ​​to display translated text in the field of view, I use two methods:

  • As a directive <span translate>{{translations.html_code}}</span>
  • How to filter {{translations.html_code|translate}}

I try the same for translations.html_code_full . Here is the code to view:

 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> 

This is the result I get:

 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 = 

It is clear that the directory implementation encodes the translation key in HTML, but there is no filter. Why is this difference in the conclusion between the implementation of the directive and the filters? And why am I not getting a warning if it renders HTML?

Here is the panel I created for the demo.

+7
angularjs xss angular-translate
source share
2 answers

The operation of the AngularJS radar protects your application from XSS attacks.

Cross-site scripting on sites accounted for approximately 84% of all Symantec-documented security vulnerabilities as of 2007.

- Wikipedia - Crossite scripting

So what are you trying to do really ? Perhaps we can show you how to do this in a safe way.

+1
source share

For me, the translation library did not cover all instances. So I needed to cover a regular script attack and an Angular attack. We read part of the URL as a key, and then display it as an attack-open message in the URL.

2 URLs I tested:

 /mypage.html#/{{{}.")));alert(1)//";}} mypage.html#/%3Cscript%3Ealert('foo')%20%3C/script%3E 

For me, the first one will be reset correctly if you use the translate directive on the page, but not the filter. The second is a successful attack when using the directive on the page, but when using the filter it was escaped correctly.

In the end, I escaped, translated, and checked in the controller before assigning the value to the scope variable. So, there is no translation directive or filter on the page.

  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'); 

You need to enter $ q, $ sce and $ translate. For me, this is the safest and most reliable solution.

0
source share

All Articles