mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
encoding/json/v2: add security section to doc
This follows up CL 684315 with an expanded section in the v2 doc. Updates #14750 Updates #71845 Change-Id: I1ffa97e030f5f2b709e8142028e3c8e0e38b80ce Reviewed-on: https://go-review.googlesource.com/c/go/+/685195 Auto-Submit: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
6ebb5f56d9
commit
c6556b8eb3
4 changed files with 107 additions and 0 deletions
|
|
@ -103,6 +103,10 @@
|
|||
// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it.
|
||||
// In particular, it makes specific choices about behavior that RFC 8259
|
||||
// leaves as undefined in order to ensure greater interoperability.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// See the "Security Considerations" section in [encoding/json/v2].
|
||||
package jsontext
|
||||
|
||||
// requireKeyedLiterals can be embedded in a struct to require keyed literals.
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ func WithIndentPrefix(prefix string) Options {
|
|||
|
||||
/*
|
||||
// TODO(https://go.dev/issue/56733): Implement WithByteLimit and WithDepthLimit.
|
||||
// Remember to also update the "Security Considerations" section.
|
||||
|
||||
// WithByteLimit sets a limit on the number of bytes of input or output bytes
|
||||
// that may be consumed or produced for each top-level JSON value.
|
||||
|
|
|
|||
|
|
@ -166,6 +166,100 @@
|
|||
// Marshaling or unmarshaling a non-empty struct
|
||||
// without any JSON representable fields results in a [SemanticError].
|
||||
// Unexported fields must not have any `json` tags except for `json:"-"`.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// JSON is frequently used as a data interchange format to communicate
|
||||
// between different systems, possibly implemented in different languages.
|
||||
// For interoperability and security reasons, it is important that
|
||||
// all implementations agree upon the semantic meaning of the data.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]
|
||||
// The first service is responsible for authenticating a JSON request,
|
||||
// while the second service is responsible for executing the request
|
||||
// (having assumed that the prior service authenticated the request).
|
||||
// If an attacker were able to maliciously craft a JSON request such that
|
||||
// both services believe that the same request is from different users,
|
||||
// it could bypass the authenticator with valid credentials for one user,
|
||||
// but maliciously perform an action on behalf of a different user.
|
||||
//
|
||||
// According to RFC 8259, there unfortunately exist many JSON texts
|
||||
// that are syntactically valid but semantically ambiguous.
|
||||
// For example, the standard does not define how to interpret duplicate
|
||||
// names within an object.
|
||||
//
|
||||
// The v1 [encoding/json] and [encoding/json/v2] packages
|
||||
// interpret some inputs in different ways. In particular:
|
||||
//
|
||||
// - The standard specifies that JSON must be encoded using UTF-8.
|
||||
// By default, v1 replaces invalid bytes of UTF-8 in JSON strings
|
||||
// with the Unicode replacement character,
|
||||
// while v2 rejects inputs with invalid UTF-8.
|
||||
// To change the default, specify the [jsontext.AllowInvalidUTF8] option.
|
||||
// The replacement of invalid UTF-8 is a form of data corruption
|
||||
// that alters the precise meaning of strings.
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// duplicate names are encountered within a JSON object,
|
||||
// which means that different implementations may behave differently.
|
||||
// By default, v1 allows for the presence of duplicate names,
|
||||
// while v2 rejects duplicate names.
|
||||
// To change the default, specify the [jsontext.AllowDuplicateNames] option.
|
||||
// If allowed, object members are processed in the order they are observed,
|
||||
// meaning that later values will replace or be merged into prior values,
|
||||
// depending on the Go value type.
|
||||
//
|
||||
// - The standard defines a JSON object as an unordered collection of name/value pairs.
|
||||
// While ordering can be observed through the underlying [jsontext] API,
|
||||
// both v1 and v2 generally avoid exposing the ordering.
|
||||
// No application should semantically depend on the order of object members.
|
||||
// Allowing duplicate names is a vector through which ordering of members
|
||||
// can accidentally be observed and depended upon.
|
||||
//
|
||||
// - The standard suggests that JSON object names are typically compared
|
||||
// based on equality of the sequence of Unicode code points,
|
||||
// which implies that comparing names is often case-sensitive.
|
||||
// When unmarshaling a JSON object into a Go struct,
|
||||
// by default, v1 uses a (loose) case-insensitive match on the name,
|
||||
// while v2 uses a (strict) case-sensitive match on the name.
|
||||
// To change the default, specify the [MatchCaseInsensitiveNames] option.
|
||||
// The use of case-insensitive matching provides another vector through
|
||||
// which duplicate names can occur. Allowing case-insensitive matching
|
||||
// means that v1 or v2 might interpret JSON objects differently from most
|
||||
// other JSON implementations (which typically use a case-sensitive match).
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// an unknown name in a JSON object is encountered.
|
||||
// When unmarshaling a JSON object into a Go struct, by default
|
||||
// both v1 and v2 ignore unknown names and their corresponding values.
|
||||
// To change the default, specify the [RejectUnknownMembers] option.
|
||||
//
|
||||
// - The standard suggests that implementations may use a float64
|
||||
// to represent a JSON number. Consequently, large JSON integers
|
||||
// may lose precision when stored as a floating-point type.
|
||||
// Both v1 and v2 correctly preserve precision when marshaling and
|
||||
// unmarshaling a concrete integer type. However, even if v1 and v2
|
||||
// preserve precision for concrete types, other JSON implementations
|
||||
// may not be able to preserve precision for outputs produced by v1 or v2.
|
||||
// The `string` tag option can be used to specify that an integer type
|
||||
// is to be quoted within a JSON string to avoid loss of precision.
|
||||
// Furthermore, v1 and v2 may still lose precision when unmarshaling
|
||||
// into an any interface value, where unmarshal uses a float64
|
||||
// by default to represent a JSON number.
|
||||
// To change the default, specify the [WithUnmarshalers] option
|
||||
// with a custom unmarshaler that pre-populates the interface value
|
||||
// with a concrete Go type that can preserve precision.
|
||||
//
|
||||
// RFC 8785 specifies a canonical form for any JSON text,
|
||||
// which explicitly defines specific behaviors that RFC 8259 leaves undefined.
|
||||
// In theory, if a text can successfully [jsontext.Value.Canonicalize]
|
||||
// without changing the semantic meaning of the data, then it provides a
|
||||
// greater degree of confidence that the data is more secure and interoperable.
|
||||
//
|
||||
// The v2 API generally chooses more secure defaults than v1,
|
||||
// but care should still be taken with large integers or unknown members.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s
|
||||
package json
|
||||
|
||||
// requireKeyedLiterals can be embedded in a struct to require keyed literals.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@
|
|||
//
|
||||
// See "JSON and Go" for an introduction to this package:
|
||||
// https://golang.org/doc/articles/json_and_go.html
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// See the "Security Considerations" section in [encoding/json/v2].
|
||||
//
|
||||
// For historical reasons, the default behavior of v1 [encoding/json]
|
||||
// unfortunately operates with less secure defaults.
|
||||
// New usages of JSON in Go are encouraged to use [encoding/json/v2] instead.
|
||||
package json
|
||||
|
||||
import (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue