| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {Injectable} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												feat: security implementation in Angular 2.
Summary:
This adds basic security hooks to Angular 2.
* `SecurityContext` is a private API between core, compiler, and
  platform-browser. `SecurityContext` communicates what context a value is used
  in across template parser, compiler, and sanitization at runtime.
* `SanitizationService` is the bare bones interface to sanitize values for a
  particular context.
* `SchemaElementRegistry.securityContext(tagName, attributeOrPropertyName)`
  determines the security context for an attribute or property (it turns out
  attributes and properties match for the purposes of sanitization).
Based on these hooks:
* `DomSchemaElementRegistry` decides what sanitization applies in a particular
  context.
* `DomSanitizationService` implements `SanitizationService` and adds *Safe
  Value*s, i.e. the ability to mark a value as safe and not requiring further
  sanitization.
* `url_sanitizer` and `style_sanitizer` sanitize URLs and Styles, respectively
  (surprise!).
`DomSanitizationService` is the default implementation bound for browser
applications, in the three contexts (browser rendering, web worker rendering,
server side rendering).
BREAKING CHANGES:
*** SECURITY WARNING ***
Angular 2 Release Candidates do not implement proper contextual escaping yet.
Make sure to correctly escape all values that go into the DOM.
*** SECURITY WARNING ***
Reviewers: IgorMinar
Differential Revision: https://reviews.angular.io/D103
											
										 
											2016-04-29 16:04:08 -07:00
										 |  |  | import {SecurityContext} from '../../core_private'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {StringMapWrapper} from '../facade/collection'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {isPresent} from '../facade/lang'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  | import {SECURITY_SCHEMA} from './dom_security_schema'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {ElementSchemaRegistry} from './element_schema_registry'; | 
					
						
							| 
									
										
										
										
											2016-04-21 15:11:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | const EVENT = 'event'; | 
					
						
							|  |  |  | const BOOLEAN = 'boolean'; | 
					
						
							|  |  |  | const NUMBER = 'number'; | 
					
						
							|  |  |  | const STRING = 'string'; | 
					
						
							|  |  |  | const OBJECT = 'object'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * This array represents the DOM schema. It encodes inheritance, properties, and events. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ## Overview | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Each line represents one kind of element. The `element_inheritance` and properties are joined | 
					
						
							|  |  |  |  * using `element_inheritance|preperties` syntax. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ## Element Inheritance | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The `element_inheritance` can be further subdivided as `element1,element2,...^parentElement`. | 
					
						
							|  |  |  |  * Here the individual elements are separated by `,` (commas). Every element in the list | 
					
						
							|  |  |  |  * has identical properties. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * An `element` may inherit additional properties from `parentElement` If no `^parentElement` is | 
					
						
							|  |  |  |  * specified then `""` (blank) element is assumed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NOTE: The blank element inherits from root `*` element, the super element of all elements. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-05-26 16:17:35 -07:00
										 |  |  |  * NOTE an element prefix such as `:svg:` has no special meaning to the schema. | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * ## Properties | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Each element has a set of properties separated by `,` (commas). Each property can be prefixed | 
					
						
							|  |  |  |  * by a special character designating its type: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - (no prefix): property is a string. | 
					
						
							|  |  |  |  * - `*`: property represents an event. | 
					
						
							|  |  |  |  * - `!`: property is a boolean. | 
					
						
							|  |  |  |  * - `#`: property is a number. | 
					
						
							|  |  |  |  * - `%`: property is an object. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ## Query | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The class creates an internal squas representaino which allows to easily answer the query of | 
					
						
							|  |  |  |  * if a given property exist on a given element. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NOTE: We don't yet support querying for types or events. | 
					
						
							| 
									
										
										
										
											2016-05-26 16:17:35 -07:00
										 |  |  |  * NOTE: This schema is auto extracted from `schema_extractor.ts` located in the test folder, | 
					
						
							|  |  |  |  *       see dom_element_schema_registry_spec.ts | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // =================================================================================================
 | 
					
						
							|  |  |  | // =================================================================================================
 | 
					
						
							|  |  |  | // =========== S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P   -  S T O P  ===========
 | 
					
						
							|  |  |  | // =================================================================================================
 | 
					
						
							|  |  |  | // =================================================================================================
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //                       DO NOT EDIT THIS DOM SCHEMA WITHOUT A SECURITY REVIEW!
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Newly added properties must be security reviewed and assigned an appropriate SecurityContext in
 | 
					
						
							| 
									
										
										
										
											2016-06-02 10:27:33 -07:00
										 |  |  | // dom_security_schema.ts. Reach out to mprobst & rjamet for details.
 | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  | //
 | 
					
						
							|  |  |  | // =================================================================================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | const SCHEMA: string[] = | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  |     /*@ts2dart_const*/ ([ | 
					
						
							| 
									
										
										
										
											2016-06-02 10:27:33 -07:00
										 |  |  |       '*|textContent,%classList,className,id,innerHTML,*beforecopy,*beforecut,*beforepaste,*copy,*cut,*paste,*search,*selectstart,*webkitfullscreenchange,*webkitfullscreenerror,*wheel,outerHTML,#scrollLeft,#scrollTop', | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  |       '^*|accessKey,contentEditable,dir,!draggable,!hidden,innerText,lang,*abort,*autocomplete,*autocompleteerror,*beforecopy,*beforecut,*beforepaste,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*copy,*cuechange,*cut,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*message,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*mozfullscreenchange,*mozfullscreenerror,*mozpointerlockchange,*mozpointerlockerror,*paste,*pause,*play,*playing,*progress,*ratechange,*reset,*resize,*scroll,*search,*seeked,*seeking,*select,*selectstart,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,*webglcontextcreationerror,*webglcontextlost,*webglcontextrestored,*webkitfullscreenchange,*webkitfullscreenerror,*wheel,outerText,!spellcheck,%style,#tabIndex,title,!translate', | 
					
						
							|  |  |  |       'media|!autoplay,!controls,%crossOrigin,#currentTime,!defaultMuted,#defaultPlaybackRate,!disableRemotePlayback,!loop,!muted,*encrypted,#playbackRate,preload,src,#volume', | 
					
						
							| 
									
										
										
										
											2016-05-26 16:17:35 -07:00
										 |  |  |       ':svg:^*|*abort,*autocomplete,*autocompleteerror,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,%style,#tabIndex', | 
					
						
							|  |  |  |       ':svg:graphics^:svg:|', | 
					
						
							|  |  |  |       ':svg:animation^:svg:|*begin,*end,*repeat', | 
					
						
							|  |  |  |       ':svg:geometry^:svg:|', | 
					
						
							|  |  |  |       ':svg:componentTransferFunction^:svg:|', | 
					
						
							|  |  |  |       ':svg:gradient^:svg:|', | 
					
						
							|  |  |  |       ':svg:textContent^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:textPositioning^:svg:textContent|', | 
					
						
							|  |  |  |       'a|charset,coords,download,hash,host,hostname,href,hreflang,name,password,pathname,ping,port,protocol,referrerpolicy,rel,rev,search,shape,target,text,type,username', | 
					
						
							|  |  |  |       'area|alt,coords,hash,host,hostname,href,!noHref,password,pathname,ping,port,protocol,referrerpolicy,search,shape,target,username', | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  |       'audio^media|', | 
					
						
							|  |  |  |       'br|clear', | 
					
						
							|  |  |  |       'base|href,target', | 
					
						
							|  |  |  |       'body|aLink,background,bgColor,link,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,text,vLink', | 
					
						
							|  |  |  |       'button|!autofocus,!disabled,formAction,formEnctype,formMethod,!formNoValidate,formTarget,name,type,value', | 
					
						
							|  |  |  |       'canvas|#height,#width', | 
					
						
							|  |  |  |       'content|select', | 
					
						
							|  |  |  |       'dl|!compact', | 
					
						
							|  |  |  |       'datalist|', | 
					
						
							|  |  |  |       'details|!open', | 
					
						
							|  |  |  |       'dialog|!open,returnValue', | 
					
						
							|  |  |  |       'dir|!compact', | 
					
						
							|  |  |  |       'div|align', | 
					
						
							|  |  |  |       'embed|align,height,name,src,type,width', | 
					
						
							|  |  |  |       'fieldset|!disabled,name', | 
					
						
							|  |  |  |       'font|color,face,size', | 
					
						
							|  |  |  |       'form|acceptCharset,action,autocomplete,encoding,enctype,method,name,!noValidate,target', | 
					
						
							|  |  |  |       'frame|frameBorder,longDesc,marginHeight,marginWidth,name,!noResize,scrolling,src', | 
					
						
							|  |  |  |       'frameset|cols,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,rows', | 
					
						
							|  |  |  |       'hr|align,color,!noShade,size,width', | 
					
						
							|  |  |  |       'head|', | 
					
						
							|  |  |  |       'h1,h2,h3,h4,h5,h6|align', | 
					
						
							|  |  |  |       'html|version', | 
					
						
							| 
									
										
										
										
											2016-05-26 16:17:35 -07:00
										 |  |  |       'iframe|align,!allowFullscreen,frameBorder,height,longDesc,marginHeight,marginWidth,name,referrerpolicy,%sandbox,scrolling,src,srcdoc,width', | 
					
						
							|  |  |  |       'img|align,alt,border,%crossOrigin,#height,#hspace,!isMap,longDesc,lowsrc,name,referrerpolicy,sizes,src,srcset,useMap,#vspace,#width', | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  |       'input|accept,align,alt,autocapitalize,autocomplete,!autofocus,!checked,!defaultChecked,defaultValue,dirName,!disabled,%files,formAction,formEnctype,formMethod,!formNoValidate,formTarget,#height,!incremental,!indeterminate,max,#maxLength,min,#minLength,!multiple,name,pattern,placeholder,!readOnly,!required,selectionDirection,#selectionEnd,#selectionStart,#size,src,step,type,useMap,value,%valueAsDate,#valueAsNumber,#width', | 
					
						
							|  |  |  |       'keygen|!autofocus,challenge,!disabled,keytype,name', | 
					
						
							|  |  |  |       'li|type,#value', | 
					
						
							|  |  |  |       'label|htmlFor', | 
					
						
							|  |  |  |       'legend|align', | 
					
						
							|  |  |  |       'link|as,charset,%crossOrigin,!disabled,href,hreflang,integrity,media,rel,%relList,rev,%sizes,target,type', | 
					
						
							|  |  |  |       'map|name', | 
					
						
							|  |  |  |       'marquee|behavior,bgColor,direction,height,#hspace,#loop,#scrollAmount,#scrollDelay,!trueSpeed,#vspace,width', | 
					
						
							|  |  |  |       'menu|!compact', | 
					
						
							|  |  |  |       'meta|content,httpEquiv,name,scheme', | 
					
						
							|  |  |  |       'meter|#high,#low,#max,#min,#optimum,#value', | 
					
						
							|  |  |  |       'ins,del|cite,dateTime', | 
					
						
							|  |  |  |       'ol|!compact,!reversed,#start,type', | 
					
						
							|  |  |  |       'object|align,archive,border,code,codeBase,codeType,data,!declare,height,#hspace,name,standby,type,useMap,#vspace,width', | 
					
						
							|  |  |  |       'optgroup|!disabled,label', | 
					
						
							|  |  |  |       'option|!defaultSelected,!disabled,label,!selected,text,value', | 
					
						
							|  |  |  |       'output|defaultValue,%htmlFor,name,value', | 
					
						
							|  |  |  |       'p|align', | 
					
						
							|  |  |  |       'param|name,type,value,valueType', | 
					
						
							|  |  |  |       'picture|', | 
					
						
							|  |  |  |       'pre|#width', | 
					
						
							|  |  |  |       'progress|#max,#value', | 
					
						
							|  |  |  |       'q,blockquote,cite|', | 
					
						
							|  |  |  |       'script|!async,charset,%crossOrigin,!defer,event,htmlFor,integrity,src,text,type', | 
					
						
							|  |  |  |       'select|!autofocus,!disabled,#length,!multiple,name,!required,#selectedIndex,#size,value', | 
					
						
							|  |  |  |       'shadow|', | 
					
						
							|  |  |  |       'source|media,sizes,src,srcset,type', | 
					
						
							|  |  |  |       'span|', | 
					
						
							|  |  |  |       'style|!disabled,media,type', | 
					
						
							|  |  |  |       'caption|align', | 
					
						
							|  |  |  |       'th,td|abbr,align,axis,bgColor,ch,chOff,#colSpan,headers,height,!noWrap,#rowSpan,scope,vAlign,width', | 
					
						
							|  |  |  |       'col,colgroup|align,ch,chOff,#span,vAlign,width', | 
					
						
							|  |  |  |       'table|align,bgColor,border,%caption,cellPadding,cellSpacing,frame,rules,summary,%tFoot,%tHead,width', | 
					
						
							|  |  |  |       'tr|align,bgColor,ch,chOff,vAlign', | 
					
						
							|  |  |  |       'tfoot,thead,tbody|align,ch,chOff,vAlign', | 
					
						
							|  |  |  |       'template|', | 
					
						
							|  |  |  |       'textarea|autocapitalize,!autofocus,#cols,defaultValue,dirName,!disabled,#maxLength,#minLength,name,placeholder,!readOnly,!required,#rows,selectionDirection,#selectionEnd,#selectionStart,value,wrap', | 
					
						
							|  |  |  |       'title|text', | 
					
						
							|  |  |  |       'track|!default,kind,label,src,srclang', | 
					
						
							|  |  |  |       'ul|!compact,type', | 
					
						
							|  |  |  |       'unknown|', | 
					
						
							|  |  |  |       'video^media|#height,poster,#width', | 
					
						
							| 
									
										
										
										
											2016-05-26 16:17:35 -07:00
										 |  |  |       ':svg:a^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:animate^:svg:animation|', | 
					
						
							|  |  |  |       ':svg:animateMotion^:svg:animation|', | 
					
						
							|  |  |  |       ':svg:animateTransform^:svg:animation|', | 
					
						
							|  |  |  |       ':svg:circle^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:clipPath^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:cursor^:svg:|', | 
					
						
							|  |  |  |       ':svg:defs^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:desc^:svg:|', | 
					
						
							|  |  |  |       ':svg:discard^:svg:|', | 
					
						
							|  |  |  |       ':svg:ellipse^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:feBlend^:svg:|', | 
					
						
							|  |  |  |       ':svg:feColorMatrix^:svg:|', | 
					
						
							|  |  |  |       ':svg:feComponentTransfer^:svg:|', | 
					
						
							|  |  |  |       ':svg:feComposite^:svg:|', | 
					
						
							|  |  |  |       ':svg:feConvolveMatrix^:svg:|', | 
					
						
							|  |  |  |       ':svg:feDiffuseLighting^:svg:|', | 
					
						
							|  |  |  |       ':svg:feDisplacementMap^:svg:|', | 
					
						
							|  |  |  |       ':svg:feDistantLight^:svg:|', | 
					
						
							|  |  |  |       ':svg:feDropShadow^:svg:|', | 
					
						
							|  |  |  |       ':svg:feFlood^:svg:|', | 
					
						
							|  |  |  |       ':svg:feFuncA^:svg:componentTransferFunction|', | 
					
						
							|  |  |  |       ':svg:feFuncB^:svg:componentTransferFunction|', | 
					
						
							|  |  |  |       ':svg:feFuncG^:svg:componentTransferFunction|', | 
					
						
							|  |  |  |       ':svg:feFuncR^:svg:componentTransferFunction|', | 
					
						
							|  |  |  |       ':svg:feGaussianBlur^:svg:|', | 
					
						
							|  |  |  |       ':svg:feImage^:svg:|', | 
					
						
							|  |  |  |       ':svg:feMerge^:svg:|', | 
					
						
							|  |  |  |       ':svg:feMergeNode^:svg:|', | 
					
						
							|  |  |  |       ':svg:feMorphology^:svg:|', | 
					
						
							|  |  |  |       ':svg:feOffset^:svg:|', | 
					
						
							|  |  |  |       ':svg:fePointLight^:svg:|', | 
					
						
							|  |  |  |       ':svg:feSpecularLighting^:svg:|', | 
					
						
							|  |  |  |       ':svg:feSpotLight^:svg:|', | 
					
						
							|  |  |  |       ':svg:feTile^:svg:|', | 
					
						
							|  |  |  |       ':svg:feTurbulence^:svg:|', | 
					
						
							|  |  |  |       ':svg:filter^:svg:|', | 
					
						
							|  |  |  |       ':svg:foreignObject^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:g^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:image^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:line^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:linearGradient^:svg:gradient|', | 
					
						
							|  |  |  |       ':svg:mpath^:svg:|', | 
					
						
							|  |  |  |       ':svg:marker^:svg:|', | 
					
						
							|  |  |  |       ':svg:mask^:svg:|', | 
					
						
							|  |  |  |       ':svg:metadata^:svg:|', | 
					
						
							|  |  |  |       ':svg:path^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:pattern^:svg:|', | 
					
						
							|  |  |  |       ':svg:polygon^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:polyline^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:radialGradient^:svg:gradient|', | 
					
						
							|  |  |  |       ':svg:rect^:svg:geometry|', | 
					
						
							|  |  |  |       ':svg:svg^:svg:graphics|#currentScale,#zoomAndPan', | 
					
						
							|  |  |  |       ':svg:script^:svg:|type', | 
					
						
							|  |  |  |       ':svg:set^:svg:animation|', | 
					
						
							|  |  |  |       ':svg:stop^:svg:|', | 
					
						
							|  |  |  |       ':svg:style^:svg:|!disabled,media,title,type', | 
					
						
							|  |  |  |       ':svg:switch^:svg:graphics|', | 
					
						
							|  |  |  |       ':svg:symbol^:svg:|', | 
					
						
							|  |  |  |       ':svg:tspan^:svg:textPositioning|', | 
					
						
							|  |  |  |       ':svg:text^:svg:textPositioning|', | 
					
						
							|  |  |  |       ':svg:textPath^:svg:textContent|', | 
					
						
							|  |  |  |       ':svg:title^:svg:|', | 
					
						
							|  |  |  |       ':svg:use^:svg:graphics|', | 
					
						
							| 
									
										
										
										
											2016-06-02 10:27:33 -07:00
										 |  |  |       ':svg:view^:svg:|#zoomAndPan', | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  |     ]); | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | var attrToPropMap: {[name: string]: string} = <any>{ | 
					
						
							|  |  |  |   'class': 'className', | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  |   'formaction': 'formAction', | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   'innerHtml': 'innerHTML', | 
					
						
							|  |  |  |   'readonly': 'readOnly', | 
					
						
							|  |  |  |   'tabindex': 'tabIndex' | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-01 10:07:49 -07:00
										 |  |  | @Injectable() | 
					
						
							| 
									
										
											  
											
												feat: security implementation in Angular 2.
Summary:
This adds basic security hooks to Angular 2.
* `SecurityContext` is a private API between core, compiler, and
  platform-browser. `SecurityContext` communicates what context a value is used
  in across template parser, compiler, and sanitization at runtime.
* `SanitizationService` is the bare bones interface to sanitize values for a
  particular context.
* `SchemaElementRegistry.securityContext(tagName, attributeOrPropertyName)`
  determines the security context for an attribute or property (it turns out
  attributes and properties match for the purposes of sanitization).
Based on these hooks:
* `DomSchemaElementRegistry` decides what sanitization applies in a particular
  context.
* `DomSanitizationService` implements `SanitizationService` and adds *Safe
  Value*s, i.e. the ability to mark a value as safe and not requiring further
  sanitization.
* `url_sanitizer` and `style_sanitizer` sanitize URLs and Styles, respectively
  (surprise!).
`DomSanitizationService` is the default implementation bound for browser
applications, in the three contexts (browser rendering, web worker rendering,
server side rendering).
BREAKING CHANGES:
*** SECURITY WARNING ***
Angular 2 Release Candidates do not implement proper contextual escaping yet.
Make sure to correctly escape all values that go into the DOM.
*** SECURITY WARNING ***
Reviewers: IgorMinar
Differential Revision: https://reviews.angular.io/D103
											
										 
											2016-04-29 16:04:08 -07:00
										 |  |  | export class DomElementSchemaRegistry extends ElementSchemaRegistry { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   schema = <{[element: string]: {[property: string]: string}}>{}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							| 
									
										
											  
											
												feat: security implementation in Angular 2.
Summary:
This adds basic security hooks to Angular 2.
* `SecurityContext` is a private API between core, compiler, and
  platform-browser. `SecurityContext` communicates what context a value is used
  in across template parser, compiler, and sanitization at runtime.
* `SanitizationService` is the bare bones interface to sanitize values for a
  particular context.
* `SchemaElementRegistry.securityContext(tagName, attributeOrPropertyName)`
  determines the security context for an attribute or property (it turns out
  attributes and properties match for the purposes of sanitization).
Based on these hooks:
* `DomSchemaElementRegistry` decides what sanitization applies in a particular
  context.
* `DomSanitizationService` implements `SanitizationService` and adds *Safe
  Value*s, i.e. the ability to mark a value as safe and not requiring further
  sanitization.
* `url_sanitizer` and `style_sanitizer` sanitize URLs and Styles, respectively
  (surprise!).
`DomSanitizationService` is the default implementation bound for browser
applications, in the three contexts (browser rendering, web worker rendering,
server side rendering).
BREAKING CHANGES:
*** SECURITY WARNING ***
Angular 2 Release Candidates do not implement proper contextual escaping yet.
Make sure to correctly escape all values that go into the DOM.
*** SECURITY WARNING ***
Reviewers: IgorMinar
Differential Revision: https://reviews.angular.io/D103
											
										 
											2016-04-29 16:04:08 -07:00
										 |  |  |     super(); | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |     SCHEMA.forEach(encodedType => { | 
					
						
							|  |  |  |       var parts = encodedType.split('|'); | 
					
						
							|  |  |  |       var properties = parts[1].split(','); | 
					
						
							|  |  |  |       var typeParts = (parts[0] + '^').split('^'); | 
					
						
							|  |  |  |       var typeName = typeParts[0]; | 
					
						
							|  |  |  |       var type = <{[property: string]: string}>{}; | 
					
						
							|  |  |  |       typeName.split(',').forEach(tag => this.schema[tag] = type); | 
					
						
							|  |  |  |       var superType = this.schema[typeParts[1]]; | 
					
						
							|  |  |  |       if (isPresent(superType)) { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         StringMapWrapper.forEach( | 
					
						
							|  |  |  |             superType, (v: any /** TODO #9100 */, k: any /** TODO #9100 */) => type[k] = v); | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |       properties.forEach((property: string) => { | 
					
						
							|  |  |  |         if (property == '') { | 
					
						
							|  |  |  |         } else if (property.startsWith('*')) { | 
					
						
							|  |  |  |           // We don't yet support events.
 | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  |           // If ever allowing to bind to events, GO THROUGH A SECURITY REVIEW, allowing events will
 | 
					
						
							|  |  |  |           // almost certainly introduce bad XSS vulnerabilities.
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |           // type[property.substring(1)] = EVENT;
 | 
					
						
							|  |  |  |         } else if (property.startsWith('!')) { | 
					
						
							|  |  |  |           type[property.substring(1)] = BOOLEAN; | 
					
						
							|  |  |  |         } else if (property.startsWith('#')) { | 
					
						
							|  |  |  |           type[property.substring(1)] = NUMBER; | 
					
						
							|  |  |  |         } else if (property.startsWith('%')) { | 
					
						
							|  |  |  |           type[property.substring(1)] = OBJECT; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           type[property] = STRING; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasProperty(tagName: string, propName: string): boolean { | 
					
						
							| 
									
										
										
										
											2015-07-29 14:01:18 +02:00
										 |  |  |     if (tagName.indexOf('-') !== -1) { | 
					
						
							| 
									
										
										
										
											2016-06-15 09:57:58 -07:00
										 |  |  |       if (tagName === 'ng-container' || tagName === 'ng-content') { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Can't tell now as we don't know which properties a custom element will get
 | 
					
						
							| 
									
										
										
										
											2015-07-29 14:01:18 +02:00
										 |  |  |       // once it is instantiated
 | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |       var elementProperties = this.schema[tagName.toLowerCase()]; | 
					
						
							|  |  |  |       if (!isPresent(elementProperties)) { | 
					
						
							|  |  |  |         elementProperties = this.schema['unknown']; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return isPresent(elementProperties[propName]); | 
					
						
							| 
									
										
										
										
											2015-07-29 14:01:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												feat: security implementation in Angular 2.
Summary:
This adds basic security hooks to Angular 2.
* `SecurityContext` is a private API between core, compiler, and
  platform-browser. `SecurityContext` communicates what context a value is used
  in across template parser, compiler, and sanitization at runtime.
* `SanitizationService` is the bare bones interface to sanitize values for a
  particular context.
* `SchemaElementRegistry.securityContext(tagName, attributeOrPropertyName)`
  determines the security context for an attribute or property (it turns out
  attributes and properties match for the purposes of sanitization).
Based on these hooks:
* `DomSchemaElementRegistry` decides what sanitization applies in a particular
  context.
* `DomSanitizationService` implements `SanitizationService` and adds *Safe
  Value*s, i.e. the ability to mark a value as safe and not requiring further
  sanitization.
* `url_sanitizer` and `style_sanitizer` sanitize URLs and Styles, respectively
  (surprise!).
`DomSanitizationService` is the default implementation bound for browser
applications, in the three contexts (browser rendering, web worker rendering,
server side rendering).
BREAKING CHANGES:
*** SECURITY WARNING ***
Angular 2 Release Candidates do not implement proper contextual escaping yet.
Make sure to correctly escape all values that go into the DOM.
*** SECURITY WARNING ***
Reviewers: IgorMinar
Differential Revision: https://reviews.angular.io/D103
											
										 
											2016-04-29 16:04:08 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * securityContext returns the security context for the given property on the given DOM tag. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Tag and property name are statically known and cannot change at runtime, i.e. it is not | 
					
						
							|  |  |  |    * possible to bind a value into a changing attribute or tag name. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The filtering is white list based. All attributes in the schema above are assumed to have the | 
					
						
							|  |  |  |    * 'NONE' security context, i.e. that they are safe inert string values. Only specific well known | 
					
						
							|  |  |  |    * attack vectors are assigned their appropriate context. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   securityContext(tagName: string, propName: string): SecurityContext { | 
					
						
							| 
									
										
										
										
											2016-05-26 14:35:27 -07:00
										 |  |  |     // Make sure comparisons are case insensitive, so that case differences between attribute and
 | 
					
						
							|  |  |  |     // property names do not have a security impact.
 | 
					
						
							|  |  |  |     tagName = tagName.toLowerCase(); | 
					
						
							|  |  |  |     propName = propName.toLowerCase(); | 
					
						
							| 
									
										
										
										
											2016-05-04 10:26:17 -07:00
										 |  |  |     let ctx = SECURITY_SCHEMA[tagName + '|' + propName]; | 
					
						
							|  |  |  |     if (ctx !== undefined) return ctx; | 
					
						
							|  |  |  |     ctx = SECURITY_SCHEMA['*|' + propName]; | 
					
						
							|  |  |  |     return ctx !== undefined ? ctx : SecurityContext.NONE; | 
					
						
							| 
									
										
											  
											
												feat: security implementation in Angular 2.
Summary:
This adds basic security hooks to Angular 2.
* `SecurityContext` is a private API between core, compiler, and
  platform-browser. `SecurityContext` communicates what context a value is used
  in across template parser, compiler, and sanitization at runtime.
* `SanitizationService` is the bare bones interface to sanitize values for a
  particular context.
* `SchemaElementRegistry.securityContext(tagName, attributeOrPropertyName)`
  determines the security context for an attribute or property (it turns out
  attributes and properties match for the purposes of sanitization).
Based on these hooks:
* `DomSchemaElementRegistry` decides what sanitization applies in a particular
  context.
* `DomSanitizationService` implements `SanitizationService` and adds *Safe
  Value*s, i.e. the ability to mark a value as safe and not requiring further
  sanitization.
* `url_sanitizer` and `style_sanitizer` sanitize URLs and Styles, respectively
  (surprise!).
`DomSanitizationService` is the default implementation bound for browser
applications, in the three contexts (browser rendering, web worker rendering,
server side rendering).
BREAKING CHANGES:
*** SECURITY WARNING ***
Angular 2 Release Candidates do not implement proper contextual escaping yet.
Make sure to correctly escape all values that go into the DOM.
*** SECURITY WARNING ***
Reviewers: IgorMinar
Differential Revision: https://reviews.angular.io/D103
											
										 
											2016-04-29 16:04:08 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-29 14:01:18 +02:00
										 |  |  |   getMappedPropName(propName: string): string { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |     var mappedPropName = StringMapWrapper.get(attrToPropMap, propName); | 
					
						
							| 
									
										
										
										
											2015-07-29 14:01:18 +02:00
										 |  |  |     return isPresent(mappedPropName) ? mappedPropName : propName; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |