Files
json/docs/mkdocs/docs/community/assurance_case.md
T
Niels Lohmann 6197341a21 Clean up non-code files (#5801)
* Clean up README, contribution guide, and repository metadata

- REUSE.toml: fix the Hedley path and SPDX id (CC0-1.0), mark the docset
  icons as the public-domain JSON logo
- CITATION.cff: v3.12.0 was released on 2025-04-11
- FILES.md: list all workflows, describe the Meson option defaults
- README: ctest -LE, table of contents, typos, stale Android/MinGW advice,
  moved links, merge duplicate Thanks entries, list the analysis tools
  used in CI
- CONTRIBUTING: iterative parser, json_literals.hpp is generated, links
- .gitignore: backups and release outputs; .gitattributes: mark
  generated files
- labeler: label other build systems and .github documentation
- MODULE.bazel: add the module version

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Clean up CI, CMake, Makefile, and Bazel files

- CMakeLists.txt: avoid VERSION_GREATER_EQUAL, which CMake < 3.7 lacks
- ci.cmake: test JSON_DisableTupleReferenceConversion in ci_cmake_flags,
  remove unused variables and unreachable per-compiler targets, look up
  Clang tools consistently, forward CMAKE_CXX_FLAGS to ci_module_cpp20,
  format json_literals.hpp and remove backups in ci_test_amalgamation
- BUILD.bazel: add json_literals.hpp to the single-header target
- workflows: format json_literals.hpp before copying it, drop the obsolete
  natvis --version plumbing, name natvis and macro_builder in failure
  messages, drop the duplicate amalgamation job, install Valgrind only
  where needed, republish docs on version bumps, fix stale names
- Makefile: complete .PHONY and help, check-amalgamation always restores
  the checked-in files, natvis uses its own venv, macro_builder_check
  installs astyle, clean removes the fuzzer binaries
- remove tools/amalgamate/config_json_view.json (json_view.hpp is not on
  develop yet)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix inaccuracies in the documentation

- version history: json_base_class_t (3.11.3), JSON_HAS_CPP_11 (3.10.0),
  JSON_HAS_RANGES exclusions, define-type macros, ABI tags
- releases: 3.12.0 raised the minimum CMake version
- from_*: the (ptr, len) overloads are deleted, not removed, in 4.0.0
- contains/count/find: document the deleted integral overloads
- add JSON_HAS_RANGE_VIEW_CONVERSION and list the JSON_HAS_* macros in
  the macro overview
- mention BON8 and error_handler where binary formats are listed
- broken links, outdated URLs, warning count, Hunter v0.26.12
- copy_markdown_source hook: expand snippets in the Markdown copies

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Pass /EHsc to the Windows C++20 module build

ci_module_cpp20 now forwards CMAKE_CXX_FLAGS to the module build. The
Windows workflow sets CMAKE_CXX_FLAGS, which replaces CMake's MSVC
defaults including /EHsc, so <chrono> failed with C4530 under /WX.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-11 08:21:51 +02:00

6.3 KiB

Assurance case

This page argues why the library meets its security requirements. It describes the threats the library faces, where the trust boundaries lie, and how the library's design and the quality assurance counter these threats. To report a vulnerability, see the security policy.

Threat model

The library parses, stores, and serializes JSON values in memory. It does not open network connections, does not open files (it only reads from streams or std::FILE* handles that the caller has already opened), does not read environment variables, and does not implement cryptography or handle credentials.

The primary threat is therefore untrusted input: JSON text or binary data (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) that an attacker controls, passed to parse, accept, sax_parse, or one of the from_* functions such as from_cbor. Such input may try to

  • make the library read or write out of bounds (malformed lengths, truncated input, invalid UTF-8),
  • trigger undefined behavior (integer overflow in sizes or numbers, invalid casts),
  • exhaust memory (huge announced sizes), or
  • exhaust the call stack (deeply nested arrays and objects).

Trust boundaries

  • Untrusted: all serialized input read by the parser, the SAX interface, and the binary readers. The library must handle every possible input by either producing a value or throwing a parse_error (or returning false when exceptions are disabled for the call).
  • Trusted: the C++ code that calls the library. Calling a function with violated preconditions, for instance accessing an array with operator[] out of range, is a programming error and not a security boundary. Such preconditions are checked with runtime assertions in debug builds; functions such as at offer checked access with exceptions.
flowchart LR
    A[Untrusted input] --> B[Parser]
    A --> C[SAX interface]
    A --> D[Binary readers]
    B --> E["Value tree (basic_json)"]
    C --> E
    D --> E
    E --> F[Trusted caller]

Secure design

  • Strict parsing. The parser accepts exactly the JSON grammar of RFC 8259. Extensions such as comments and trailing commas must be enabled explicitly. Invalid UTF-8 is rejected.
  • Errors are reported, not ignored. Malformed input results in a parse_error with the byte position of the error. Binary readers do not trust announced sizes: strings and binary values grow only as bytes are actually read, arrays reserve at most a fixed number of elements up front, and sizes that no container can hold are rejected.
  • Memory is owned by values. Each basic_json value owns its content, and there is no manual memory management in user code. The destructor does not recurse, so destroying a deeply nested value does not exhaust the stack.
  • Bounded recursion. The JSON parser and the binary readers keep their state in explicit stacks instead of recursing per nesting level. Operations that walk a value, such as dump, copying, comparison, hashing, and merge_patch, recurse only up to a fixed depth and continue with an explicit stack below it. Some operations, such as diff, flatten, and the binary writers, still recurse once per nesting level; work on them is in progress. Applications that process untrusted input can limit its nesting depth with a parser callback.
  • Invariants are checked. The class invariant (for instance, that the pointer for the stored type is never null) is checked with runtime assertions throughout the test suite.

Common weaknesses

The following table maps the relevant classes of the Common Weakness Enumeration to the measures that counter them. The measures are described in detail in Quality assurance.

Weakness Countermeasures
Out-of-bounds read/write (CWE-125, CWE-787) bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz
Integer overflow (CWE-190) UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck
Use after free, double free (CWE-416, CWE-415) ownership of all memory by values; AddressSanitizer and Valgrind; Clang Static Analyzer
Memory leaks (CWE-401) Valgrind (Memcheck) on the test suite
Uncontrolled recursion (CWE-674) iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs
Uncontrolled resource consumption (CWE-400) allocations based on announced sizes are capped; OSS-Fuzz with memory limits
Undefined behavior in general (CWE-758) UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy, Cppcheck, Clang Static Analyzer, Infer

In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock by OSS-Fuzz.