---------- Forwarded message ----------
From: Mike Samuel <mikesamuel@...>
Date: Jan 29, 2008 8:15 PM
Subject: [Caja] secure string interpolation in javascript
To: Google Caja Discuss <google-caja-discuss@googlegroups.com>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to http://groups.google.com/group/google-caja-discuss
To unsubscribe, email google-caja-discuss-unsubscribe@googlegroups.com
-~----------~----~----~----~------~----~------~--~---
--
Text by me above is hereby placed in the public domain
On Jan 29, 2008 9:12 PM, Mark Miller <erights@...> wrote:
> Like quasiliterals for JavaScript, but better.
Very nice. I like the context scanning mechanism. I'll be curious to
see what the fsm.txt looks like for SQL. It wasn't clear to me how
the interpolator comes up with (1,2,3,4) for a list for the IN clause.
Given the nature of the scanner, I'm guessing that it is based on the
type of the argument passed in. You don't have enough context to know
it's in the IN clause, I assume. So, anywhere a list is redered
un-escaped, it will be in (1,2,3,4) form, right? If I have a list of
literals to chain together with OR x LIKE $y[1] OR x LIKE $y[2] ... I
need to do that in code, right?
I know you explicitly described looping as a non-goal, but your
imaginary sql interpolator (I didn't see code for it) handles a list
where I would have expected to need to code that explicitly. Was your
intention only to show different contexts, or do you actually have in
mind a strategy for dealing with lists?
On 30/01/2008, Monty Zukowski <monty@...> wrote:
>
> On Jan 29, 2008 9:12 PM, Mark Miller <erights@...> wrote:
> > Like quasiliterals for JavaScript, but better.
>
> Very nice. I like the context scanning mechanism. I'll be curious to
> see what the fsm.txt looks like for SQL. It wasn't clear to me how
> the interpolator comes up with (1,2,3,4) for a list for the IN clause.
> Given the nature of the scanner, I'm guessing that it is based on the
> type of the argument passed in. You don't have enough context to know
> it's in the IN clause, I assume. So, anywhere a list
Escapers can use the runtime type of the substitution values. If the
SQL escaper sees an array, then it iterates over elements, and if it
sees a Date, it renders it in a form that SQL will recognize, and it
can output a SQL NULL for the javascript counterpart.
I have a first stab at a SQL that does have enough context based on
last keyword and whether you've seen an open parenthesis since the IN.
I may have to abandon deferred parentheses though, since there's no
way to deal with WHERE FOO IN (1, 2, (SELECT COUNT(*) FROM BAR), $baz)
with a constant amount of state.
> is redered
> un-escaped, it will be in (1,2,3,4) form, right? If I have a list of
> literals to chain together with OR x LIKE $y[1] OR x LIKE $y[2] ... I
> need to do that in code, right?
>
> I know you explicitly described looping as a non-goal, but your
> imaginary sql interpolator (I didn't see code for it) handles a list
> where I would have expected to need to code that explicitly. Was your
> intention only to show different contexts, or do you actually have in
> mind a strategy for dealing with lists?
For lists, and other collections, I can see a number of strategies:
For e.g.
var attribs = { 'id': 'foo', 'class': 'bar' };
open(Template("<b ${attribs}>"))
might yield
'<b id="foo" class="bar">'
This is strictly a template in code approach, so you can use the
containing languages looping constructs. StringInterpolation objects
nest, so
var rows = [];
for (var i = 0; i < names.length; ++i) {
rows.push(open(Template("<tr><td>${names[i]}</td></tr>")));
}
var table = open(Template("<table>$rows</table>"));
And the security guarantee:
Literal portions will be tokenized the same way regardless of
substitution values.
assumes that nested StringInterpolations have been flattened to a
single list of alternating literals & substitutions.
As a user, I'd rather see the SQL problem solved right by having a parser that's more sophisticated than a finite state machine than to not have it solved right.
In the paper, every result from Template is immediately passed to open. Did I miss one? If not, then why make people write both? I'd expect to have "openedTemplate(...blah...)" as an abbreviation for "open(Template(...blah...))", although maybe a name shorter than "openedTemplate" should be selected.
----- Tim Freeman Email: tim.freeman@... Desk in Palo Alto: (650) 857-2581 Home: (408) 774-1298 Cell: (408) 348-7536
From: caplet@yahoogroups.com [mailto:caplet@yahoogroups.com] On Behalf Of Mark Miller Sent: Tuesday, January 29, 2008 21:08 To: The Caplet Group Subject: [caplet] Fwd: [Caja] secure string interpolation in javascript
---------- Forwarded message ---------- From: Mike Samuel <mikesamuel@gmail.com> Date: Jan 29, 2008 8:15 PM Subject: [Caja] secure string interpolation in javascript To: Google Caja Discuss <google-caja-discuss@googlegroups.com>
On 30/01/2008, Freeman, Tim <tim.freeman@...> wrote:
>
>
>
>
>
>
>
> Seems like a good idea.
>
> As a user, I'd rather see the SQL problem solved right by having a parser
that's more sophisticated than a finite state machine than to not have it
solved right.
Fair enough. It's tough to implement sophisticated and efficient
parsers in javascript, but I'm sure that it's worthwhile in some
contexts.
Perhaps if StringInterpolation.interpolate instead of taking a
contextScanner and an escaper published events like ('Literal, "foo")
or ('Substitution bar) to an interpolationEventSink then the current
contextScanner&escaper could be built on top of it, or an
implementation could route those events to an AST builder instead.
> In the paper, every result from Template is immediately passed to open. Did
I miss one? If not, then why make people write both? I'd expect to have
"openedTemplate(...blah...)" as an abbreviation for
"open(Template(...blah...))", although maybe a name shorter than
"openedTemplate" should be selected.
You didn't miss anything. This is an implementation detail leaking
out through the API.
The `Template` part converts the "Hello $name_of_planet!" to "new
StringInterpolation(['Hello ', name_of_planet, '!'])" and the `open`
part is really `eval` in disguise which parses the string and invokes
the constructor. Thus, two function calls are needed for this macro
expansion to work in javascript.
On Jan 30, 2008 2:42 PM, Mike Samuel <mikesamuel@...> wrote:
> > As a user, I'd rather see the SQL problem solved right by having a parser
> that's more sophisticated than a finite state machine than to not have it
> solved right.
>
> Fair enough. It's tough to implement sophisticated and efficient
> parsers in javascript, but I'm sure that it's worthwhile in some
> contexts.
...
Now that ANTLR 3 has a retargetable backend, this might be a good
motivation to get a JavaScript backend implemented. ActionScript,
perl, Python & Ruby are all implemented as examples to draw upon. See
antlr.org