Sorry, it took me some time but I went read the StreamHtmlParser code to
better understand how it works, and how it's used here in the generator.

I thus found that there's a special-case for "meta refresh" that this
patch doesn't handle (see comments below), and that the ATTR_TYPE.URI is
based on HTML4 attributes only [1], while HTML5 added a few more:
 - formaction
 - icon (<command icon="">)
 - manifest (<html manifest="">)
 - poster (<video poster="">)
Given that we're interested in security here, I thought I'd bring this
issue. You might want to talk to the team behind JSilver (as they're all
Googlers too) so they update the code, and/or patch the version of the
StreamHtmlParser used in GWT, and/or handle it in the generator (instead
of, or in addition to, testing isUrlStart, add a test for
HTML5_URI_ATTRIBUTES.contains(streamHtmlParser.getAttribute()).

LGTM otherwise.

[1]
http://code.google.com/p/jsilver/source/browse/trunk/src/com/google/streamhtmlparser/util/HtmlUtils.java?r=10#137


http://gwt-code-reviews.appspot.com/1396803/diff/1/user/src/com/google/gwt/safehtml/rebind/HtmlTemplateParser.java
File user/src/com/google/gwt/safehtml/rebind/HtmlTemplateParser.java
(right):

http://gwt-code-reviews.appspot.com/1396803/diff/1/user/src/com/google/gwt/safehtml/rebind/HtmlTemplateParser.java#newcode282
user/src/com/google/gwt/safehtml/rebind/HtmlTemplateParser.java:282:
Preconditions.checkState(lookBehind == '"' || lookBehind == '\'',
This will fail if someone includes <meta content="0;URL={0}"> in a
template, while isUrlStart will be true. This is the single case where
isUrlStart() should be used instead of getValueIndex()==0 (the other
special case is if insertText() was called in a ATTR_TYPE.URI, but we
never call insertText()).

Replacing the above isUrlStart() with getAttributeType()==ATTR_TYPE.URI
&& getValueIndex()==0 would make the <meta> example above fall into the
HtmlContext.Type.ATTRIBUTE_VALUE case where the URL wouldn't be treated
as a URL and sanitized, so it's not acceptable.

The only solution seems to be to keep the isUrlStart() test but look at
the char preceeding the attribute value in the template for the quote
char. Something like:
 template.charAt(parsePosition - streamHtmlParser.getValueIndex() - 1);
In most cases, getValueIndex() would be 0 so it will be equivalent to
lookBehind, and in the <meta> case it would still work OK to "find" the
end of the attribute value (in the <meta> case, the URL should end the
attribute value, so it's OK to then compare with the 'lookAhead' char).

Other solution: explicitly test for the <meta content=> case
("meta".equals(getTag()) && "content".equals(getAttribute())) and throw
an UnableToCompleteException().

http://gwt-code-reviews.appspot.com/1396803/diff/1/user/test/com/google/gwt/safehtml/rebind/HtmlTemplateParserTest.java
File
user/test/com/google/gwt/safehtml/rebind/HtmlTemplateParserTest.java
(right):

http://gwt-code-reviews.appspot.com/1396803/diff/1/user/test/com/google/gwt/safehtml/rebind/HtmlTemplateParserTest.java#newcode122
user/test/com/google/gwt/safehtml/rebind/HtmlTemplateParserTest.java:122:
"<a href='{0}'>{1}</a>");
Add a test for the <meta content='0;URL={0}'> case?

http://gwt-code-reviews.appspot.com/1396803/

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to