@@ -489,7 +489,9 @@ export interface CompiledTemplate extends Omit<Template, 'el'> {
489489 el ?: HTMLTemplateElement ;
490490
491491 // The prepared HTML string to create a template element from.
492- h : TrustedHTML ;
492+ // The type is a TemplateStringsArray to guarantee that the value came from
493+ // source code, preventing a JSON injection attack.
494+ h : TemplateStringsArray ;
493495}
494496
495497/**
@@ -652,6 +654,39 @@ export interface DirectiveParent {
652654 __directives ?: Array < Directive | undefined > ;
653655}
654656
657+ function trustFromTemplateString (
658+ tsa : TemplateStringsArray ,
659+ stringFromTSA : string
660+ ) : TrustedHTML {
661+ // A security check to prevent spoofing of Lit template results.
662+ // In the future, we may be able to replace this with Array.isTemplateObject,
663+ // though we might need to make that check inside of the html and svg
664+ // functions, because precompiled templates don't come in as
665+ // TemplateStringArray objects.
666+ if ( ! Array . isArray ( tsa ) || ! tsa . hasOwnProperty ( 'raw' ) ) {
667+ let message = 'invalid template strings array' ;
668+ if ( DEV_MODE ) {
669+ message = `
670+ Internal Error: expected template strings to be an array
671+ with a 'raw' field. Faking a template strings array by
672+ calling html or svg like an ordinary function is effectively
673+ the same as calling unsafeHtml and can lead to major security
674+ issues, e.g. opening your code up to XSS attacks.
675+ If you're using the html or svg tagged template functions normally
676+ and still seeing this error, please file a bug at
677+ https://github.com/lit/lit/issues/new?template=bug_report.md
678+ and include information about your build tooling, if any.
679+ `
680+ . trim ( )
681+ . replace ( / \n * / g, '\n' ) ;
682+ }
683+ throw new Error ( message ) ;
684+ }
685+ return policy !== undefined
686+ ? policy . createHTML ( stringFromTSA )
687+ : ( stringFromTSA as unknown as TrustedHTML ) ;
688+ }
689+
655690/**
656691 * Returns an HTML string for the given TemplateStringsArray and result type
657692 * (HTML or SVG), along with the case-sensitive bound attribute names in
@@ -816,38 +851,8 @@ const getTemplateHtml = (
816851 const htmlResult : string | TrustedHTML =
817852 html + ( strings [ l ] || '<?>' ) + ( type === SVG_RESULT ? '</svg>' : '' ) ;
818853
819- // A security check to prevent spoofing of Lit template results.
820- // In the future, we may be able to replace this with Array.isTemplateObject,
821- // though we might need to make that check inside of the html and svg
822- // functions, because precompiled templates don't come in as
823- // TemplateStringArray objects.
824- if ( ! Array . isArray ( strings ) || ! strings . hasOwnProperty ( 'raw' ) ) {
825- let message = 'invalid template strings array' ;
826- if ( DEV_MODE ) {
827- message = `
828- Internal Error: expected template strings to be an array
829- with a 'raw' field. Faking a template strings array by
830- calling html or svg like an ordinary function is effectively
831- the same as calling unsafeHtml and can lead to major security
832- issues, e.g. opening your code up to XSS attacks.
833-
834- If you're using the html or svg tagged template functions normally
835- and still seeing this error, please file a bug at
836- https://github.com/lit/lit/issues/new?template=bug_report.md
837- and include information about your build tooling, if any.
838- `
839- . trim ( )
840- . replace ( / \n * / g, '\n' ) ;
841- }
842- throw new Error ( message ) ;
843- }
844854 // Returned as an array for terseness
845- return [
846- policy !== undefined
847- ? policy . createHTML ( htmlResult )
848- : ( htmlResult as unknown as TrustedHTML ) ,
849- attrNames ,
850- ] ;
855+ return [ trustFromTemplateString ( strings , htmlResult ) , attrNames ] ;
851856} ;
852857
853858/** @internal */
@@ -1517,7 +1522,10 @@ class ChildPart implements Disconnectable {
15171522 typeof type === 'number'
15181523 ? this . _$getTemplate ( result as TemplateResult )
15191524 : ( type . el === undefined &&
1520- ( type . el = Template . createElement ( type . h , this . options ) ) ,
1525+ ( type . el = Template . createElement (
1526+ trustFromTemplateString ( type . h , type . h [ 0 ] ) ,
1527+ this . options
1528+ ) ) ,
15211529 type ) ;
15221530
15231531 if ( ( this . _$committedValue as TemplateInstance ) ?. _$template === template ) {
0 commit comments