-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: escapes + to + #42506
Comments
/cc @empijei |
Hi, do you mind expanding on what is the issue? The browser should unescape the "+" in all HTML contexts so it everything should still work, right? Is this an issue on the efficiency of the escaper? |
The reason that gets escaped is that it is in the following map and the two defined below it: Lines 50 to 67 in 75e16f5
According to the doc the escape set should be a composition of special chars in these states: None of these includes a "+" sign. I don't honestly know why it was there in the first place and, to my knowledge, it should not be. But before we stop escaping it and we introduce XSS and break tests in the community I would like to do some additional checks on this. |
Digging through git blame shows it was first introduced 9 years ago in CL 4968058. This is the justification given at the time: go/src/pkg/exp/template/html/html.go Lines 16 to 29 in 4670d9e
|
This looks like it is an extra-cautious escaping to take into account URLs and such in html attributes and other contexts. I would be inclined to leave it as it is unless you think this is causing some misbehavior. |
Thanks for your time! Given a I ran into an issue when generating HTML with timestamps and where this character got escaped.
I'm not entirely sure about the behaviour similarities between the public and private variants, but it feels like these should at least be aligned. I understand that risking up XSS is undesirable. My work-around and expectations were that, if my test data would be wrapped by HTMLEscaper() that it would result in exactly the same result, so that I can rely on that in my tests, e.g.: patternsToMatch := []string{
data.DateCreated.String(),
}
for _, p := range patternsToMatch {
if !strings.Contains(tplResult, template.HTMLEscaper(p)) {
t.Errorf("expected %q to occur in the template, but it didn't", p)
}
} The work-around now is to if !strings.Contains(tplResult, func(p string) string {
return strings.ReplaceAll(template.HTMLEscaper(p), "+", "+")
}(p)) {
t.Errorf("expected %q to occur in the template, but it didn't", p)
} So I suppose it's one of:
|
I agree and I am leaning towards 1 and 3. Asking @kele for a second opinion. |
I'm leaning towards option 3 (leave as it is), because I think that the benefit of doing 1 (aligning If we had it documented somewhere that |
More generally than just Grouped by the same underlying implementation, I've found:
Every single one of these implementations has a slightly different set of escaped characters. As a user, particularly one unfamiliar with HTML safety, it is not at all clear which of these is "correct" or "safest" to use, or why they are different in the first place. |
This is an old issue, but I also recently ran into this. I had to construct a helper function to get a test working that would match the html/templates behavior. It would be good if the format was standardized across Go escaping functions. |
I can open a separate issue if needed, but this seems to be basically the same problem of multiple inconsistent implementations that @prattmic described above. I hit this in the context of URL escaping. This makes test code challenging because the (private) template escaping functions generate different content than the publicly available escaping functions -- namely lowercase vs uppercase. Rendering with Playground example: https://go.dev/play/p/jLK2bRuO8cL?v=gotip
|
As far as I know, the
+
character has no special meaning when used as:<p> This is a plus "+" sign</p>
. However html/template's escaping analysis thinks otherwise. What strikes me as odd is thattemplate.HTMLEscaper("+")
doesn't provide the same behaviour, even when skipping the allocation optimisation check.What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
It reproduces with 1.15.4, haven't tried tip.
What did you do?
Playground with the problem I'm having: https://play.golang.org/p/6rbaYLi9_Bt
(I've also tried variations of html elements to create a different escaping context (e.g.: surround the action with e.g.
<li>
tags), which I thought would be the problem initially. That produced the same result however.)What did you expect to see?
The same output as if the value ran through
template.HTMLEscaper()
What did you see instead?
The text was updated successfully, but these errors were encountered: