encoding/json: add security section to doc

Add a section to the package doc which details the security
considerations of using encoding/json, in particular with respect to
parser misalignment issues.

Additionally, clarify previously ambiguous statement in the Unmarshal
doc about how case is used when matching keys in objects, and add a note
about how duplicate keys are handled.

Fixes #14750

Change-Id: I66f9b845efd98c86a684d7333b3aa8a456564922
Reviewed-on: https://go-review.googlesource.com/c/go/+/684315
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
Roland Shoemaker 2025-06-26 12:19:23 -07:00 committed by Gopher Robot
parent 742fda9524
commit 2a22aefa1f
2 changed files with 43 additions and 8 deletions

View file

@ -43,11 +43,14 @@ import (
// and the input is a JSON quoted string, Unmarshal calls
// [encoding.TextUnmarshaler.UnmarshalText] with the unquoted form of the string.
//
// To unmarshal JSON into a struct, Unmarshal matches incoming object
// keys to the keys used by [Marshal] (either the struct field name or its tag),
// preferring an exact match but also accepting a case-insensitive match. By
// default, object keys which don't have a corresponding struct field are
// ignored (see [Decoder.DisallowUnknownFields] for an alternative).
// To unmarshal JSON into a struct, Unmarshal matches incoming object keys to
// the keys used by [Marshal] (either the struct field name or its tag),
// ignoring case. If multiple struct fields match an object key, an exact case
// match is preferred over a case-insensitive one.
//
// Incoming object members are processed in the order observed. If an object
// includes duplicate keys, later duplicates will replace or be merged into
// prior values.
//
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:

View file

@ -4,12 +4,44 @@
//go:build !goexperiment.jsonv2
// Package json implements encoding and decoding of JSON as defined in
// RFC 7159. The mapping between JSON and Go values is described
// in the documentation for the Marshal and Unmarshal functions.
// Package json implements encoding and decoding of JSON as defined in RFC 7159.
// The mapping between JSON and Go values is described in the documentation for
// the Marshal and Unmarshal functions.
//
// See "JSON and Go" for an introduction to this package:
// https://golang.org/doc/articles/json_and_go.html
//
// # Security Considerations
//
// The JSON standard (RFC 7159) is lax in its definition of a number of parser
// behaviors. As such, many JSON parsers behave differently in various
// scenarios. These differences in parsers mean that systems that use multiple
// independent JSON parser implementations may parse the same JSON object in
// differing ways.
//
// Systems that rely on a JSON object being parsed consistently for security
// purposes should be careful to understand the behaviors of this parser, as
// well as how these behaviors may cause interoperability issues with other
// parser implementations.
//
// Due to the Go Backwards Compatibility promise (https://go.dev/doc/go1compat)
// there are a number of behaviors this package exhibits that may cause
// interopability issues, but cannot be changed. In particular the following
// parsing behaviors may cause issues:
//
// - If a JSON object contains duplicate keys, keys are processed in the order
// they are observed, meaning later values will replace or be merged into
// prior values, depending on the field type (in particular maps and structs
// will have values merged, while other types have values replaced).
// - When parsing a JSON object into a Go struct, keys are considered in a
// case-insensitive fashion.
// - When parsing a JSON object into a Go struct, unknown keys in the JSON
// object are ignored (unless a [Decoder] is used and
// [Decoder.DisallowUnknownFields] has been called).
// - Invalid UTF-8 bytes in JSON strings are replaced by the Unicode
// replacement character.
// - Large JSON number integers will lose precision when unmarshaled into
// floating-point types.
package json
import (