(Az Angular Translate online útmutató “Escaping of variable content” cikkének fordítása)
Változó tartalmak megfelelő kezelése (escape-elése)
Hagyományos kimenet esetében az AngularJS helyesen kezeli a tartalmakat, a megfelelő escape-elést alkalmazza. Ha viszont az angular-translate-et használjuk változó tartalommal az eredmény nem lesz helyesen kezelve. Ez azt jelenti, hogy az alkalmazás súlyos támadási felületet hagy szabadon. (Lásd OWASP).
Általános használat
A useSanitizeValueStrategy(strategy) metódus határozza meg, hogy az escape-elésnél milyen stratégia hajtódik végre, ez globálisan érvényesül.
Jelenleg az alábbi stratégiák vannak beépítve:
- sanitize: a fordítandó szövegben a $sanitize segítségével tisztítja ki a HTML-t
- escape: a fordítandó szövegből kiveszi a HTML-t
- sanitizeParameters: az interpolációs paraméterek értékei alapján tisztítja ki a HTML-t a $sanitize segítségével
- escapeParameters: az interpolációs paraméterek értékei alapján veszi ki a HTML-t
Jelenleg a sanitize móddal az a probléma, hogy duplán kódolja az UTF-8 karaktereket és a speciális karaktereket. Javaslat: az “escape” stratégiát használd, amíg ez a probléma meg nem oldódik.
Mindezek mellett az alábbi alapértelmezett értékek csak a 2-es verziónál érvényesek:
- null: semmi, nem biztonságos alapértelmezés (a 3.0-ban ez el lesz távolítva)
- escaped: ez az “escapeParameters” alias-a a visszafelé működő kompatibilitás miatt (a 2.7.0-tól kezdve, a 3.0-ban ez el lesz törölve)
Hogy megfeleljünk a visszafelé menő teljes kompatibilitásnak az escape-elés alapértelmezett esetben kikapcsolt állapotban van.
$translateProvider.useSanitizeValueStrategy(null);
A jövőben azonban a sokkal biztonságosabb “sanitize”-ot alapértelmezettként bekapcsoljuk.
$translateProvider.useSanitizeValueStrategy(‘sanitize’);
Javaslatunk, hogy nagyon biztonságos stratégiát használj. Ezért, ha nincs kiválasztott stratégia, hibaüzenetet adunk.
Bemutatók
Nem escape-elt és nem is kitisztított változat
Források
<!doctype html> <html ng-app="myApp_not_escaped"> <head> <script src="http://cdn.rawgit.com/SlexAxton/messageformat.js/v1.0.2/messageformat.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-cookies.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate/2.15.2/angular-translate.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-interpolation-messageformat/2.15.2/angular-translate-interpolation-messageformat.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-cookie/2.15.2/angular-translate-storage-cookie.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-local/2.15.2/angular-translate-storage-local.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-url/2.15.2/angular-translate-loader-url.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-static-files/2.15.2/angular-translate-loader-static-files.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-handler-log/2.15.2/angular-translate-handler-log.js"></script> <script src="script.js"></script> </head> <body> <div ng-controller="Ctrl"> <p>{{ 'HEADLINE' | translate }}</p> <p translate="PARAGRAPH" translate-values="{username: '<span style='color:red;'>HACKED</span>'}"></p> </div> </body> </html>
var translations = { HEADLINE: 'XSS possible!', PARAGRAPH: 'Hello {{username}}!', }; var app = angular.module('myApp_not_escaped', ['pascalprecht.translate']); app.config(['$translateProvider', function ($translateProvider) { $translateProvider.translations('en', translations); $translateProvider.preferredLanguage('en'); // Using standard escaping (nothing) }]); app.controller('Ctrl', ['$scope', function ($scope) { }]);
Az eredmény:
XSS possible!
Hello HACKED!
Escape-elt változat
Források
<!doctype html> <html ng-app="myApp_escaped"> <head> <script src="http://cdn.rawgit.com/SlexAxton/messageformat.js/v1.0.2/messageformat.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-cookies.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate/2.15.2/angular-translate.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-interpolation-messageformat/2.15.2/angular-translate-interpolation-messageformat.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-cookie/2.15.2/angular-translate-storage-cookie.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-local/2.15.2/angular-translate-storage-local.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-url/2.15.2/angular-translate-loader-url.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-static-files/2.15.2/angular-translate-loader-static-files.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-handler-log/2.15.2/angular-translate-handler-log.js"></script> <script src="script.js"></script> </head> <body> <div ng-controller="Ctrl"> <p>{{ 'HEADLINE' | translate }}</p> <p translate="PARAGRAPH" translate-values="{username: '<span style='color:red;'>HACKED</span>'}"></p> </div> </body> </html>
var translations = { HEADLINE: 'XSS possible!', PARAGRAPH: 'Hello {{username}}!', }; var app = angular.module('myApp_escaped', ['pascalprecht.translate']); app.config(['$translateProvider', function ($translateProvider) { $translateProvider.translations('en', translations); $translateProvider.preferredLanguage('en'); // Enable escaping of HTML $translateProvider.useSanitizeValueStrategy('escape'); }]); app.controller('Ctrl', ['$scope', function ($scope) { }]);
Az eredmény:
XSS possible!
Hello <span style=’color:red;’>HACKED</span>!
Escape-elt változat (csak paraméterekkel)
Források
<!doctype html> <html ng-app="myApp_escape_params"> <head> <script src="http://cdn.rawgit.com/SlexAxton/messageformat.js/v1.0.2/messageformat.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-cookies.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate/2.15.2/angular-translate.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-interpolation-messageformat/2.15.2/angular-translate-interpolation-messageformat.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-cookie/2.15.2/angular-translate-storage-cookie.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-local/2.15.2/angular-translate-storage-local.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-url/2.15.2/angular-translate-loader-url.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-static-files/2.15.2/angular-translate-loader-static-files.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-handler-log/2.15.2/angular-translate-handler-log.js"></script> <script src="script.js"></script> </head> <body> <div ng-controller="Ctrl"> <p>{{ 'HEADLINE' | translate }}</p> <p translate="PARAGRAPH" translate-values="{username: '<span style='color:red;'>HACKED</span>'}"></p> </div> </body> </html>
var translations = { HEADLINE: 'XSS possible!', PARAGRAPH: '<span style='color:green'>Hello</span> {{username}}!', }; var app = angular.module('myApp_escape_params', ['pascalprecht.translate']); app.config(['$translateProvider', function ($translateProvider) { $translateProvider.translations('en', translations); $translateProvider.preferredLanguage('en'); // Enable escaping of HTML $translateProvider.useSanitizeValueStrategy('escapeParameters'); }]); app.controller('Ctrl', ['$scope', function ($scope) { }]);
Az eredmény:
XSS possible!
Hello <span style=’color:red;’>HACKED</span>!
A “kitisztított” változat
Források
<!doctype html> <html ng-app="myApp_sanitize"> <head> <script src="http://cdn.rawgit.com/SlexAxton/messageformat.js/v1.0.2/messageformat.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-cookies.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate/2.15.2/angular-translate.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-interpolation-messageformat/2.15.2/angular-translate-interpolation-messageformat.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-cookie/2.15.2/angular-translate-storage-cookie.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-storage-local/2.15.2/angular-translate-storage-local.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-url/2.15.2/angular-translate-loader-url.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-loader-static-files/2.15.2/angular-translate-loader-static-files.js"></script> <script src="http://cdn.rawgit.com/angular-translate/bower-angular-translate-handler-log/2.15.2/angular-translate-handler-log.js"></script> <script src="script.js"></script> </head> <body> <div ng-controller="Ctrl"> <p>{{ 'HEADLINE' | translate }}</p> <p translate="PARAGRAPH" translate-values="{username: '<span style='color:red;'>HACKED</span>'}"></p> </div> </body> </html>
var translations = { HEADLINE: 'XSS possible!', PARAGRAPH: 'Hello {{username}}!', }; var app = angular.module('myApp_sanitize', ['pascalprecht.translate', 'ngSanitize']); app.config(['$translateProvider', function ($translateProvider) { $translateProvider.translations('en', translations); $translateProvider.preferredLanguage('en'); // Enable escaping of HTML $translateProvider.useSanitizeValueStrategy('sanitize'); }]); app.controller('Ctrl', ['$scope', function ($scope) { }]);
Az eredmény:
XSS possible!
Hello HACKED!