首页 > 解决方案 > Golang结构解组xss

问题描述

我有一个结构,其中注入了 XSS。为了删除它,我 json.Marshal 它,然后运行 ​​json.HTMLEscape。然后我 json.Unmarshal 将其转换为一个新结构。

问题是新结构仍然注入了 XSS。

我根本不知道如何从结构中删除 XSS。我可以编写一个函数在现场执行此操作,但考虑到有 json.HTMLEscape 并且我们可以将其解组,它应该可以正常工作,但事实并非如此。

type Person struct {
    Name string `json:"name"`
}
func main() {
    var p, p2 Person
     // p.Name has XSS
    p.Name = "<script>alert(1)</script>"
    var tBytes bytes.Buffer

    // I marshal it so I can use json.HTMLEscape
    marshalledJson, _ := json.Marshal(p)
    json.HTMLEscape(&tBytes, marshalledJson)

    // here I insert it into a new struct, sadly the p2 struct has the XSS still 
    err := json.Unmarshal(tBytes.Bytes(), &p2)
    if err != nil {
        fmt.Printf(err.Error())
    }
    fmt.Print(p2)

} 

预期结果是 p2.Name 要像&lt;script&gt;alert(1)&lt;/script&gt;

标签: jsongogolang-migrate

解决方案


首先,json.HTMLEscape不做你想做的事:

HTMLEscape 将 JSON 编码的 src 附加到 dst,其中字符串文字中的 <、>、&、U+2028 和 U+2029 字符更改为 \u003c、\u003e、\u0026、\u2028、\u2029,以便 JSON 是安全的嵌入 HTML <script> 标签。

但你想要的是:

p2.Name 要像&lt;script&gt;alert(1)&lt;/script&gt;

您可以通过调用获得html.EscapeString,但不能通过任何 json 编码器例程获得。1

其次,如果你检查结果,json.Marshal你会发现它已经被替换<\u003c等等——它已经完成了json.HTMLEscape,所以json.HTMLEscape没有任何字符要替换!有关示例,请参见https://play.golang.org/p/Zergs3bwElY 。

正如 Ahmed Hashem 所指出的,如果你真的想做这种事情,你可以使用反射来查找字符串字段(如在 Golang 中实现 XSS 保护)——但一般来说,在输入点这样做可能更明智。请注意,那里的答案不会递归到可能包含字符串的内部对象中。


1 JSON 不是 HTML,也不是 XML 等。在您的头脑和代码中将它们分开。

另请参阅https://medium.com/@oazzat19/what-is-the-difference-between-html-vs-xml-vs-json-254864972bbb,据我所知,这是我们如何到达这里的简短摘要没有错误,这对于随机的网络文章来说非常好。:-) 当使用 JSON 时,我们得到非常简单的类型化数据:对象、字符串、数字、列表/数组、布尔值和 null;请参阅https://www.w3schools.com/js/js_json_syntax.asphttps://www.w3schools.com/js/js_json_objects.asphttps://cswr.github.io/JsonSchema/spec/basic_types/例如。


推荐阅读