AngularJS Strict Contextual Escaping ($sce)
Upcoming SlideShare
Loading in...5
×
 

AngularJS Strict Contextual Escaping ($sce)

on

  • 4,200 views

What is $sce and how do I use it? ...

What is $sce and how do I use it?

Why did Angular eliminate ng-bind-html-unsafe? How can I emulate the old behavior? How can I do better than emulating the old behavior of html binding?

Presented at the Seattle AngularJS Meetup on March 19, 2014 - http://www.meetup.com/AngularJS-SEA/events/169192362/

Statistics

Views

Total Views
4,200
Views on SlideShare
4,158
Embed Views
42

Actions

Likes
1
Downloads
15
Comments
0

3 Embeds 42

http://www.slideee.com 27
http://10.1.5.31 12
https://twitter.com 3

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

AngularJS Strict Contextual Escaping ($sce) AngularJS Strict Contextual Escaping ($sce) Presentation Transcript

  • $ S C E A N G U L A R J S
  • J o s h S c h u m a c h e r @ j o s h s c h u m a c h e r h t t p s : / / p l u s . g o o g l e . c o m / + J o s h S c h u m a c h e r s H a s O ff e r s
  • S T R I C T C O N T E X T U A L E S C A P I N G
  • – N O O N E E V E R “We can trust our users and the input they provide.”
  • A N G U L A R 1 . 0 . 8 • ng-bind • ng-bind-html • ng-bind-html-unsafe <script> function snippetController($scope) { $scope.snippet = '<p style="color:blue">n an htmln' + ' <em onmouseover="this.textContent='PWN3D!'">click here</em>' + ' snippetn</p>'; } </script> ! <div ng-controller="snippetController" class="container"> <form> <h1>User Input</h1> <textarea class="form-control" rows="4" ng-model="snippet"></textarea> </form> ! <h2>ng-bind</h2> <pre ng-bind="snippet"></pre> ! ! <h2>ng-bind-html</h2> <div ng-bind-html="snippet"></div> ! ! <h2>ng-bind-html-unsafe</h2> <div ng-bind-html-unsafe="snippet"></div> ! </div> Demo…
  • G O O D B Y E N G - B I N D - H T M L - U N S A F E
  • A N G U L A R 1 . 2 • ng-bind • ng-bind-html • ng-bind-html-unsafe <script> function snippetController($scope) { $scope.snippet = '<p style="color:blue">n an htmln' + ' <em onmouseover="this.textContent='PWN3D!'">click here</em>' + ' snippetn</p>'; } </script> ! <div ng-controller="snippetController" class="container"> <form> <h1>User Input</h1> <textarea class="form-control" rows="4" ng-model="snippet"></textarea> </form> ! <h2>ng-bind</h2> <pre ng-bind="snippet"></pre> ! ! <h2>ng-bind-html</h2> <div ng-bind-html="snippet"></div> ! </div>
  • Y O U ’ R E N O T T H AT L U C K Y Error: [$sce:unsafe] http://errors.angularjs.org/1.2.14/$sce/unsafe at Error (native) at http://code.angularjs.org/1.2.14/angular.min.js:6:450 at e (http://code.angularjs.org/1.2.14/angular.min.js:110:34) at getTrusted (http://code.angularjs.org/1.2.14/angular.min.js:111:327) at Object.e.(anonymous function) [as getTrustedHtml] 
 (http://code.angularjs.org/1.2.14/angular.min.js:113:71) at Object.fn (http://code.angularjs.org/1.2.14/angular.min.js:182:71) at h.$digest (http://code.angularjs.org/1.2.14/angular.min.js:102:370) at h.$apply (http://code.angularjs.org/1.2.14/angular.min.js:105:173) at http://code.angularjs.org/1.2.14/angular.min.js:18:23 at Object.d [as invoke] (http://code.angularjs.org/1.2.14/angular.min.js:30:452)
  • L O N G L I V E n g S A N I T I Z E var app = angular.module('myApp', ['ngSanitize']); <script src="http://code.angularjs.org/1.2.14/angular-sanitize.min.js"></script> Demo…
  • var ngBindHtmlDirective = ['$sce', function($sce) { return function(scope, element, attr) { scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) { element.html($sce.getTrustedHtml(value) || ''); }); }; }]; Bread and Butter <div ng-bind-html="snippet"></div>
  • $sce.getTrustedHtml(value); → $sceDelegate.getTrusted($sce.HTML, value) → $sceDelegate.getTrusted($sce.URL, value) → $sceDelegate.getTrusted($sce.RESOURCE_URL, value) → $sceDelegate.getTrusted($sce.JS, value) → $sceDelegate.getTrusted($sce.CSS, value)
  • var ngBindHtmlDirective = ['$sce', function($sce) { return function(scope, element, attr) { scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) { element.html($sce.getTrustedHtml(value) || ''); }); }; }]; return value.$$unwrapTrustedValue(); if (type === SCE_CONTEXTS.HTML) { return htmlSanitizer(value); } {$sceDelegate. getTrusted()
  • S O W H Y WA S N ’ T I L U C K Y B E F O R E ? var htmlSanitizer = function htmlSanitizer(html) { throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.'); }; ! if ($injector.has('$sanitize')) { htmlSanitizer = $injector.get('$sanitize'); } $sceDelegateProvider
  • return value.$$unwrapTrustedValue(); ????? var app = angular.module('myApp'); ! app.controller('snippetController', function($scope, $sce) { $scope.$watch('snippet', function(value) { $scope.snippetHarmful = $sce.trustAsHtml(value); }); }); function TrustedValueHolderType(trustedValue) { this.$$unwrapTrustedValue = function() { return trustedValue; }; }; Demo…
  • Context Notes $sce.HTML HTML that is safe to render in application. $sce.CSS CSS that is safe to render in application. [currently unused by AngularJS core] $sce.URL URLs that are safe to follow as links. <a href= and <img src= don’t use $sce [currently unused by AngularJS core] $sce.RESOURCE_URL URLs whose contents are safe to include in your app. ng-include, ngSrc, iframe, object, etc $sce.JS JavaScript that is safe to render in application. [currently unused by AngularJS core]
  • C U S T O M N G - B I N D - H T M L <h2>ng-bind-html (trusted w/ filter)</h2> <div ng-bind-html="snippet|trustedHtml"></div> Generally a RISKY idea $scope.$watch('snippet', function(value) { value = value.replace(' onmouseover="this.textContent='PWN3D!'"', ''); $scope.snippetCustomSanitized = $sce.trustAsHtml(value); });
  • L O N G L I V E N G - B I N D - H T M L - U N S A F E Demo… var app = angular.module('myApp', ['ngSanitize']); ! app.filter('trustedHtml', ['$sce', function($sce) { return function(value) { return $sce.trustAsHtml(value); }; }]); ! <h2>ng-bind-html (trusted w/ filter)</h2> <div ng-bind-html="snippet|trustedHtml"></div> Generally a BAD idea
  • C U S T O M I Z I N G T H E H T M L PA R S E R • Not easy • Dart recently introduced an injectable dom.NodeValidator • Re-implement $sanitize htmlParser for global customization • Write new htmlParser that returns $sce.trustAsHtml(parsedValue) /** * HTML Parser By Misko Hevery (misko@hevery.com) * based on: HTML Parser By John Resig (ejohn.org) * Original code by Erik Arvidsson, Mozilla Public License */
  • S C E R E S O U R C E _ U R L app.config(function($sceDelegateProvider) { $sceDelegateProvider.resourceUrlWhitelist([ 'self', // Allow loading from our assets domain. Notice the difference between * and **. 'http://cdn*.assets.example.com/**' ]); }); ! ! ! ! ! ‘*’ matches 0 or more occurrences of any character EXCEPT ':', '/', '.', '?', '&' and ‘;' ! ‘**’ matches 0 or more of ANY character - be careful, generally only use at the end of a whitelist url