JSON parsing as a security boundary.
Thesis: if JSON comes from an untrusted source, parsing is not just deserialization. It is a resource-control and policy boundary.
python -m pip install -e ".[dev]" && python examples/security_boundary.pyPython's json.loads is fast and useful, but it accepts NaN, silently
overwrites duplicate keys, has no input-size policy, and relies on recursive
container construction. safejson keeps the stdlib decoder but adds a strict
pre-scan and semantic hooks.
from safejson import Limits, loads
policy = Limits(max_depth=8, max_string_length=4096, max_total_nodes=10000)
value = loads(payload, limits=policy, allowed_types=(dict, list, str, int, float, bool, type(None)))- Depth, string length, array length, object key count, and total node count can be bounded.
- Duplicate keys are rejected by default.
NaNand infinities are rejected by default.- Errors are typed so callers can distinguish syntax, limit, duplicate-key, and type-policy failures.
| Behavior | json.loads |
safejson.loads |
|---|---|---|
| Resource limits | Caller must add them | Built in |
| Duplicate keys | Last value wins | Rejected by default |
NaN/Infinity |
Accepted | Rejected by default |
| Schema validation | No | No; compose with a schema validator |
The tests include RFC 8259 conformance cases, adversarial limits, duplicate-key checks, type policy checks, and branch coverage.
python -m pip install -e ".[dev]"
ruff check .
mypy --strict src/safejson
pytest --cov=safejson --cov-branch --cov-fail-under=100
python scripts/benchmark.pySee ARCHITECTURE.md, TECHNICAL_ARTICLE.md, and RELEASE.md.