From 2e9bb62bfed92ef24a6744fbdc3cf24eb672cd56 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Sat, 21 Jun 2025 21:27:09 -0700 Subject: encoding/json/v2: reject unquoted dash as a JSON field name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this blog: https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/ the concern was raised that whenever "-" is combined with other options, the "-" is intepreted as as a name, rather than an ignored field, which may go contrary to user expectation. Static analysis demonstrates that there are ~2k instances of `json:"-,omitempty" in the wild, where almost all of them intended for the field to be ignored. To prevent this footgun, reject any tags that has "-," as a prefix and warn the user to choose one of the reasonable alternatives. The documentation of json/v2 already suggests `json:"'-'"` as the recommended way to explicitly specify dash as the name. See Example_fieldNames for example usages of the single-quoted literal. Update the v1 json documentation to suggest the same thing. Updates #71497 Change-Id: I7687b6eecdf82a5d894d057c78a4a90af4f5a6e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/683175 LUCI-TryBot-Result: Go LUCI Reviewed-by: Johan Brandhorst-Satzkorn Reviewed-by: Damien Neil Auto-Submit: Joseph Tsai Reviewed-by: Daniel Martí Reviewed-by: Dmitri Shuralyov --- src/encoding/json/v2_decode_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/encoding/json/v2_decode_test.go') diff --git a/src/encoding/json/v2_decode_test.go b/src/encoding/json/v2_decode_test.go index fe814a3cfd..3ab20e2b5d 100644 --- a/src/encoding/json/v2_decode_test.go +++ b/src/encoding/json/v2_decode_test.go @@ -1195,6 +1195,27 @@ var unmarshalTests = []struct { out: []int{1, 2, 0, 4, 5}, err: &UnmarshalTypeError{Value: "bool", Type: reflect.TypeFor[int](), Field: "2", Offset: len64(`[1,2,`)}, }, + + { + CaseName: Name("DashComma"), + in: `{"-":"hello"}`, + ptr: new(struct { + F string `json:"-,"` + }), + out: struct { + F string `json:"-,"` + }{"hello"}, + }, + { + CaseName: Name("DashCommaOmitEmpty"), + in: `{"-":"hello"}`, + ptr: new(struct { + F string `json:"-,omitempty"` + }), + out: struct { + F string `json:"-,omitempty"` + }{"hello"}, + }, } func TestMarshal(t *testing.T) { -- cgit v1.3