Fix DoS vulnerability and resource leak in from_json() and save2file() - #247
Open
lilu5458 wants to merge 1 commit into
Open
Fix DoS vulnerability and resource leak in from_json() and save2file()#247lilu5458 wants to merge 1 commit into
lilu5458 wants to merge 1 commit into
Conversation
- from_json(): Add recursion depth limit (max_depth=500) to prevent RecursionError DoS when parsing deeply nested JSON (CWE-400) - from_json(): Catch RecursionError from json.loads and raise ValueError with a meaningful message - from_json(): Validate root JSON is a dict before processing - from_json(): Handle non-dict node_info gracefully instead of raising AttributeError (input validation) - save2file(): Fix file descriptor leak by opening file once instead of per-line (CWE-404)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes two security issues identified during a white-box audit of
treelib/tree.py:Denial-of-Service via deeply nested JSON (CWE-400) —
Tree.from_json()relied on unbounded recursion in_append_node(). A malicious JSON payload with deep nesting causedRecursionError(crash) and could be used to exhaust the interpreter stack.File descriptor leak in
save2file()(CWE-404) — the innerhandler()callback opened the target file on every emitted line and never closed it, leaking one file descriptor per line. Saving a large tree would exhaust the process file-descriptor limit.Changes
treelib/tree.pyonly (1 file, +29/-9):from_json():RecursionErrorfromjson.loads()and raise a clearValueError.dict; raiseValueErrorotherwise.max_depth(500) guard to_append_node()so traversal depth is bounded.node_infogracefully (treat as leafdata).save2file():Validation
python -m pytest tests/— all 210 tests pass.poc_recursion_dos.py: a 600-level nested payload now raisesValueErrorinstead ofRecursionError.poc_fd_leak.py: large-tree save no longer leaks file descriptors.Backward Compatibility
Behavior is unchanged for well-formed inputs. Only malformed/malicious inputs that previously raised
RecursionErrororAttributeError, or leaked file descriptors, now raiseValueError/ close the handle. Themax_depthof 500 is well above any realistic tree depth.