Implicitly escaped $ (or not) in quasis?

Allen Wirfs-Brock allen at
Wed Jun 27 07:59:09 PDT 2012

On Jun 27, 2012, at 1:49 AM, gaz Heyes wrote:

> On 26 June 2012 17:19, Allen Wirfs-Brock <allen at> wrote:
> I'm working on incorporating quasis into the ES6 draft and there is an issue I want to discuss:
> In the wiki proposal[1]  $  is used as the prefix for substitutions that may be of two forms:
>    `xyz$foo 1234`      //$foo substitues the value of the variable foo
>    `xyz${foo} 1234`    ${expr} generally substitues the result of evaluating expr, so ${foo} substitutes the value of foo
> I have to say I disagree with the whole feature, this will introduce a new class of DOM based XSS attacks since developers in their infinite wisdom will use this feature to place user input inside multi-line strings. e.g. message = `USER_INPUT` and the attack being ${globalVariable}. A list of variable substitutions would mitigate that risk like how the printf function works but allowing any variable reference is a bad idea IMO. I would also like to see how the context aware escaping would work since in order to provide such a mechanism you would have to render the content at some point and the context could change and the user input could change when the content is rendered. The fact that CSS doesn't provide any way to safely escape user input in property names/values without fully white listing the whole specification I fail to see how a context aware escaping would work in that instance.

I don't see why the above issue would be a problem with this quasi proposal, as quasi do no implicit evals or implicit reevaluation of substitution  values.

Consider this code:

var USER_INPUT = getUserInput();  // assume the value returned is "${globalVariable}"

var message = `USER_INPUT`;   //The value of message is the string "USER_INPUT", no substitution occurred

var messageWithSub =  `${USER_INPUT}`;  //The value of messageWithSub is the string "${globalVariable}", literally.  No eval is performed.

The code would have to explicitly say something like:

eval(`${USER_INPUT}`);      //this means the same as eval("${globalVariable}") and will produce a syntax error

for the attach to be executed.

The other situations would be a quasi with an explicit substitution handler:

var messageWithMSGSub =  Msg`${USER_INPUT}`;  //The value of messageWithMsgSub is the result of calling Msg.

Here, Msg, is a application or library provided quasi substitution handler function. Think about  it as the DSL compiler. In this case Msg might be designed to do an explicit eval of the the substitution text containing the attach code.  However, that fact that Msg evals some of its inputs really should be documented as part of the its contract.  It essentially is just like any other function you might call and pass a string to as an argument.  If you don't know or don't trust the function to not do an eval of its parameters then you better not pass any strings into it that originated from untrusted sources.

The quasi proposal[1] looks quite extensive at the security implications of this feature and a number of mitigations are included in the design.  Any body with security concerns involving quasi should probably start with that proposal and then address where it is wrong in its conclusions or otherwise falls short.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list