Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

html/template: URL path/fragment component not properly escaped #22498

Closed
stjj89 opened this issue Oct 30, 2017 · 4 comments
Closed

html/template: URL path/fragment component not properly escaped #22498

stjj89 opened this issue Oct 30, 2017 · 4 comments

Comments

@stjj89
Copy link
Contributor

stjj89 commented Oct 30, 2017

Given the following two templates:

<a href="http://www.foo.com/bar?{{.}}">link</a>
<a href="http://www.foo.com/bar%3F{{.}}">link</a>

When . is "hello#param1=value1&param2=value2", the templates produce the following HTML output:

<a href="http://www.foo.com/bar?hello%23param1%3dvalue1%26param2%3dvalue2">link</a>
<a href="http://www.foo.com/bar%3Fhello#param1=value1&amp;param2=value2">link</a>

Example at https://play.golang.org/p/pbdV0f9DdE.

Notice that the interpolated fragment separator #, and the & sub-delimiter is escaped (via percent-encoding) in the first template, but not the second, despite the fact that both URLs are equivalent (%3F is the percent encoding of ?). This allows parameters and fragments to be injected into the URL in the second template.

The problem is that the state machine only transitions into the URL query/frag component state when the # or ? rune is found. It does not account for their percent-encoded equivalents.

The fix for this is simple, but it would break users by changing html/template's URL-escaping behavior. I'm not sure if such a change would be worth it.

@stjj89
Copy link
Contributor Author

stjj89 commented Oct 30, 2017

@mikesamuel

@tv42
Copy link

tv42 commented Nov 1, 2017

Are the URLs really equivalent? I would not expect %3F to behave like the unquoted question mark -- how else would you quote a question mark that is part of the URL path?

Consider:

As far as I understand, /bar?{{.}} will quote as query, /bar%3F{{.}} will quote as URL path.

@ghost
Copy link

ghost commented Nov 1, 2017

@tv42 Yes, looks like they aren't equivalent.

node.js:

let url = require('url');
console.log(url.parse('http://www.foo.com/bar?x=y').pathname);
console.log(url.parse('http://www.foo.com/bar%3Fx=y').pathname);

Output:

/bar
/bar%3Fx=y

@stjj89
Copy link
Contributor Author

stjj89 commented Nov 1, 2017

@tv42 @opennota Thanks for pointing that out. I once again confused myself over how percent-encoded and HTML-escaped characters get interpreted by the browser.

My concern should have been if &#63; in <a href="http://www.foo.com/bar&#63;{{.}}">link</a> is properly un-escaped into ?, and interpreted by the URL parser. As it turns out, it is, and the action after the HTML-escaped question mark gets query-escaped properly.

@stjj89 stjj89 closed this as completed Nov 1, 2017
@golang golang locked and limited conversation to collaborators Nov 1, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants