fix: handle empty JSON-LD framing responses and prevent log injection#40
Conversation
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
|
Thanks @kaiprodevops for tackling this issue. Here is Claude's feedback:
|
|
How to fix the tests:
|
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
Signed-off-by: kaiprodev <kaiprodevops@gmail.com>
|
Thanks @wiresio for the thorough review and detailed feedback! I've addressed all the issues you identified. Please review the changes and let me know if any adjustments are needed. |
|
Thanks @kaiprodevops! |
|
You're very welcome! @wiresio Thanks again for the excellent guidance during the code review. |
Summary
Fixes uncaught
JSONDecodeErrorwhen the JSON-LD framing process fails or returns empty output, and prevents log injection vulnerabilities in error handling.Problem
When
frame-jsonld.jsreturns an empty string (e.g., due to unreachable custom context URLs or malformed N-Triples), the call tojson.loads(jsonld_compacted)inframe_td_nt_content()raises an uncaughtjson.decoder.JSONDecodeError. Flask's default error handler converts this to an unstructured HTTP 500 Internal Server Error with no meaningful message.This affects any
GET /things/{id}request for a Thing Description whose custom context URL was unreachable at ingestion or framing time.Root Cause
write()/read()patternSolution
1. Improved Subprocess Communication (
tdd/common.py)communicate()instead ofwrite()/read()to prevent OS pipe buffer deadlocks (Python official recommendation)returncode) for reliable error detectionrepr()and truncate to 200 chars to prevent log injection attacks2. Enhanced Error Handling (
tdd/td.py)JSONDecodeErrorand convert to application-specific exception3. JavaScript Error Handling (
js-src/frame-jsonld.js)4. New Exception Type (
tdd/errors.py)ExternalDependencyErrorwith HTTP 502 status codeSecurity Improvements
Log Injection Prevention
Before (vulnerable):
After (secure):
Information Leakage Prevention
Before (exposes internals):
{ "detail": "Framing process failed: Error: Cannot resolve context https://attacker.com/probe", "status": 502 }After (generic):
{ "title": "External Dependency Error", "detail": "An upstream dependency failed to process the data. JSON-LD framing process failed.", "status": 502 }Changes
Modified Files
tdd/errors.py- AddExternalDependencyErrorexception classtdd/common.py- Improveframe_nt_content()with secure subprocess handlingtdd/td.py- Improveframe_td_nt_content()with input validation and error handlingjs-src/frame-jsonld.js- Add error handling and non-zero exit codesNew Files
tdd/tests/test_frame_error_handling.py- Comprehensive test suite (6 test cases)Testing
Test Coverage
Test Results
All existing tests pass, confirming backward compatibility.
Related Issues
Fixes #39