我认为保留字符百分比编码没有按照RFC 3986规范进行。
你使用的Go版本是什么(go version
)?
1.21
你做了什么?
dict := make(map[string]interface{})
dict["link"] = `https://example.com/()"`
tag := `<a href="{{ $.link }}"></a>`
t, _ := template.New("tag").Parse(tag)
var tpl bytes.Buffer
e := t.Execute(&tpl, dict)
if e != nil {
fmt.Println(e)
}
fmt.Println(tpl.String())
你想看到什么?
<a href="https://example.com/()"></a>
你看到了什么?
<a href="https://example.com/%28%29%22"></a>
6条答案
按热度按时间abithluo1#
cc @golang/security
pb3s4cty2#
从html/template/url.go文件中:
whitzsjs3#
Format (webp) is incorrectly encoded to format%28webp%29, and the browser will not encode Format (webp)
js81xvg64#
我相信服务器正确地使用了')'作为分隔符,转义的URI用于另一个(不存在的)资源。
https://www.rfc-editor.org/%72%66%63/%72%66%63%33%39%38%36#%73%65%63%74%69%6F%6E%2D%32.%32
2.2
因此,保留字符集中的字符受到规范化保护,因此可以安全地由特定于方案和生产者算法用于在URI中分隔数据子组件。更改分隔符的编码可能无法通过规范化撤销。
2.3
URI中不同之处在于将非保留字符替换为其相应的百分比编码的US-ASCII八位字节,它们是等价的:它们标识相同的资源。
只提到了非保留字符。
3.3
除了层次结构路径中的点段外,路径段在通用语法中被认为是不透明的。URI生成应用程序通常使用段中允许的保留字符来分隔特定于方案或解引用处理程序的子组件。
'('可以是分隔符(路径、子分隔符、保留)或八位字节/字符。
'%28'可以是没有特殊含义的百分比编码八位字节。
'('和'&'在同一类中,对'&'进行百分比编码会破坏大多数查询。
看起来'('并不等于'%28',尽管许多实现不将'('用作分隔符。
Go http库在解析URL时将'('转义为'%28',并将';'反转义为';'。两者都是子分隔符。
sz81bmfz5#
浏览器和html/模板有时在所需的转义程度上存在分歧。
我不认为转义( )是错误的,并且在某些情况下需要转义它们。
在asuracomics URL中,使用格式:%28webp)可以正常工作,但格式:%28webp%29不行。
有趣的是,服务器可以解码%28,但不能解码%。
请注意,维基百科没有问题提供https://en.wikipedia.org/wiki/Comma_%28disambiguation%29。
在我看来,将此宣布为服务器错误并让html/模板保持原样是合理的。
vktxenjb6#
我今天遇到了一个我认为更通用的这个bug的情况,那就是
html/template
似乎是在锚点 href 属性内的字符中逃逸,这使得生成包含链接的模板变得困难。一个简单的复现是在 go1.22.5 在Playground上运行的 here