@@ -56,15 +56,47 @@ module CodeInjection {
5656 */
5757 class TemplateTagInScriptSink extends Sink {
5858 TemplateTagInScriptSink ( ) {
59- // Note: currently viewing all tags in code as sinks, but this can lead to
60- // some FPs when values are escaped correctly.
6159 exists ( Templating:: TemplatePlaceholderTag tag |
62- tag .isInCodeContext ( ) and
63- this = tag .asDataFlowNode ( )
60+ this = tag .asDataFlowNode ( ) and
61+ tag .isEscapingInterpolation ( ) // to avoid double reporting, raw interpolation is only flagged by the XSS query
62+ |
63+ // In an attribute, HTML entities are expanded prior to JS parsing, so the escaping performed by the
64+ // templating engine has no effect against code injection.
65+ tag .isInCodeAttribute ( )
66+ or
67+ // In a script tag, HTML entities are not expanded.
68+ // To reduce noise, we filter out a common pattern where a template tag occurs in a string literal,
69+ // since HTML escaping prevents breaking out of the string literal.
70+ //
71+ // var foo = "<%= foo %>";
72+ //
73+ // However, we still flag the special case where multiple such strings occur on the same line, as injection can sometimes
74+ // we obtained by injecting a backslash character at the end of the first one:
75+ //
76+ // init("<%= foo %">, "<%= bar %>");
77+ //
78+ // For example, setting foo to `\` and bar to `, alert(1));//`, code injection is obtained.
79+ tag .isInScriptTag ( ) and
80+ not tag .getEnclosingExpr ( ) = getLastStringWithPlaceholderOnLine ( tag .getLocation ( ) .getFile ( ) , tag .getLocation ( ) .getStartLine ( ) )
6481 )
6582 }
6683 }
6784
85+ /** Gets the last string literal containing a template placeholder on the given line. */
86+ pragma [ nomagic]
87+ private StringLiteral getLastStringWithPlaceholderOnLine ( File file , int line ) {
88+ result = max ( StringLiteral lit , Location loc |
89+ loc = lit .getLocation ( ) and
90+ loc .getFile ( ) = file and
91+ loc .getStartLine ( ) = line and
92+ lit = any ( Templating:: TemplatePlaceholderTag tag | tag .isEscapingInterpolation ( ) ) .getEnclosingExpr ( )
93+ |
94+ lit
95+ order by
96+ loc .getStartColumn ( )
97+ )
98+ }
99+
68100 /**
69101 * A server-side template tag occurring in the context of another template language.
70102 */
0 commit comments