Files
rengine/shared/utils
Yogesh OjhaandClaude Opus 5 5cb5d03a9f fix: a 379-byte YAML document took the API down for half a minute
Every place that accepts user-supplied YAML — engine import, an
engine's stored yaml_source, nuclei template upload and report theme
upload — could be handed a billion-laughs document. Measured on engine
import: 379 bytes of nested aliases blocked the event loop for 36
seconds. A request issued alongside it timed out at 20s and the next
took 13s, against a 4ms baseline. Any authenticated user could do it,
repeatedly.

The cost is not in the parser. PyYAML shares an aliased node rather
than copying it, so safe_load returns in 2ms; the expansion happens in
whatever walks the result as a tree, which for us is pydantic — it has
no node cache, so nine levels of nine aliases is 43 million visits.
Bounding the parser would have missed this entirely.

load_document() now measures the document the way a consumer will walk
it and stops at 100,000 values, which is four times the largest thing
reNgine ships (a 24,133-node nuclei template, still indexed in 0.67s)
and far below the bomb. All four call sites use it and each reports the
limit in its own idiom — an HTTP 400, a template rejection reason, a
theme error.

Same payload after: 0.03s and refused, with API latency during the
attack at 36ms.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K6LcH8uUddjJbKrahf34ys
2026-09-07 07:41:52 +05:30
..