|
166 | 166 | // Marshaling or unmarshaling a non-empty struct
|
167 | 167 | // without any JSON representable fields results in a [SemanticError].
|
168 | 168 | // Unexported fields must not have any `json` tags except for `json:"-"`.
|
| 169 | +// |
| 170 | +// # Security Considerations |
| 171 | +// |
| 172 | +// JSON is frequently used as a data interchange format to communicate |
| 173 | +// between different systems, possibly implemented in different languages. |
| 174 | +// For interoperability and security reasons, it is important that |
| 175 | +// all implementations agree upon the semantic meaning of the data. |
| 176 | +// |
| 177 | +// [For example, suppose we have two micro-services.] |
| 178 | +// The first service is responsible for authenticating a JSON request, |
| 179 | +// while the second service is responsible for executing the request |
| 180 | +// (having assumed that the prior service authenticated the request). |
| 181 | +// If an attacker were able to maliciously craft a JSON request such that |
| 182 | +// both services believe that the same request is from different users, |
| 183 | +// it could bypass the authenticator with valid credentials for one user, |
| 184 | +// but maliciously perform an action on behalf of a different user. |
| 185 | +// |
| 186 | +// According to RFC 8259, there unfortunately exist many JSON texts |
| 187 | +// that are syntactically valid but semantically ambiguous. |
| 188 | +// For example, the standard does not define how to interpret duplicate |
| 189 | +// names within an object. |
| 190 | +// |
| 191 | +// The v1 [encoding/json] and [encoding/json/v2] packages |
| 192 | +// interpret some inputs in different ways. In particular: |
| 193 | +// |
| 194 | +// - The standard specifies that JSON must be encoded using UTF-8. |
| 195 | +// By default, v1 replaces invalid bytes of UTF-8 in JSON strings |
| 196 | +// with the Unicode replacement character, |
| 197 | +// while v2 rejects inputs with invalid UTF-8. |
| 198 | +// To change the default, specify the [jsontext.AllowInvalidUTF8] option. |
| 199 | +// The replacement of invalid UTF-8 is a form of data corruption |
| 200 | +// that alters the precise meaning of strings. |
| 201 | +// |
| 202 | +// - The standard does not specify a particular behavior when |
| 203 | +// duplicate names are encountered within a JSON object, |
| 204 | +// which means that different implementations may behave differently. |
| 205 | +// By default, v1 allows for the presence of duplicate names, |
| 206 | +// while v2 rejects duplicate names. |
| 207 | +// To change the default, specify the [jsontext.AllowDuplicateNames] option. |
| 208 | +// If allowed, object members are processed in the order they are observed, |
| 209 | +// meaning that later values will replace or be merged into prior values, |
| 210 | +// depending on the Go value type. |
| 211 | +// |
| 212 | +// - The standard defines a JSON object as an unordered collection of name/value pairs. |
| 213 | +// While ordering can be observed through the underlying [jsontext] API, |
| 214 | +// both v1 and v2 generally avoid exposing the ordering. |
| 215 | +// No application should semantically depend on the order of object members. |
| 216 | +// Allowing duplicate names is a vector through which ordering of members |
| 217 | +// can accidentally be observed and depended upon. |
| 218 | +// |
| 219 | +// - The standard suggests that JSON object names are typically compared |
| 220 | +// based on equality of the sequence of Unicode code points, |
| 221 | +// which implies that comparing names is often case-sensitive. |
| 222 | +// When unmarshaling a JSON object into a Go struct, |
| 223 | +// by default, v1 uses a (loose) case-insensitive match on the name, |
| 224 | +// while v2 uses a (strict) case-sensitive match on the name. |
| 225 | +// To change the default, specify the [MatchCaseInsensitiveNames] option. |
| 226 | +// The use of case-insensitive matching provides another vector through |
| 227 | +// which duplicate names can occur. Allowing case-insensitive matching |
| 228 | +// means that v1 or v2 might interpret JSON objects differently from most |
| 229 | +// other JSON implementations (which typically use a case-sensitive match). |
| 230 | +// |
| 231 | +// - The standard does not specify a particular behavior when |
| 232 | +// an unknown name in a JSON object is encountered. |
| 233 | +// When unmarshaling a JSON object into a Go struct, by default |
| 234 | +// both v1 and v2 ignore unknown names and their corresponding values. |
| 235 | +// To change the default, specify the [RejectUnknownMembers] option. |
| 236 | +// |
| 237 | +// - The standard suggests that implementations may use a float64 |
| 238 | +// to represent a JSON number. Consequently, large JSON integers |
| 239 | +// may lose precision when stored as a floating-point type. |
| 240 | +// Both v1 and v2 correctly preserve precision when marshaling and |
| 241 | +// unmarshaling a concrete integer type. However, even if v1 and v2 |
| 242 | +// preserve precision for concrete types, other JSON implementations |
| 243 | +// may not be able to preserve precision for outputs produced by v1 or v2. |
| 244 | +// The `string` tag option can be used to specify that an integer type |
| 245 | +// is to be quoted within a JSON string to avoid loss of precision. |
| 246 | +// Furthermore, v1 and v2 may still lose precision when unmarshaling |
| 247 | +// into an any interface value, where unmarshal uses a float64 |
| 248 | +// by default to represent a JSON number. |
| 249 | +// To change the default, specify the [WithUnmarshalers] option |
| 250 | +// with a custom unmarshaler that pre-populates the interface value |
| 251 | +// with a concrete Go type that can preserve precision. |
| 252 | +// |
| 253 | +// RFC 8785 specifies a canonical form for any JSON text, |
| 254 | +// which explicitly defines specific behaviors that RFC 8259 leaves undefined. |
| 255 | +// In theory, if a text can successfully [jsontext.Value.Canonicalize] |
| 256 | +// without changing the semantic meaning of the data, then it provides a |
| 257 | +// greater degree of confidence that the data is more secure and interoperable. |
| 258 | +// |
| 259 | +// The v2 API generally chooses more secure defaults than v1, |
| 260 | +// but care should still be taken with large integers or unknown members. |
| 261 | +// |
| 262 | +// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s |
169 | 263 | package json
|
170 | 264 |
|
171 | 265 | // requireKeyedLiterals can be embedded in a struct to require keyed literals.
|
|
0 commit comments