T09 · Insecure Skill Coding Practices
- Location
scripts/claims-validator.py:35- Finding
Malformed JSONL Records Are Silently Discarded
- Content
View full analysis
Vulnerability Details
File Locations:
scripts/claims-validator.py:35-42scripts/round-controller.py:66-73scripts/stopping-detector.py:34-41
Vulnerability Type: Fail-open parsing of security-relevant state
Risk Level: MediumVulnerable Code
From
scripts/claims-validator.py:python with path.open('r', encoding='utf-8') as f: for line_num, line in enumerate(f, 1): line = line.strip() if not line: continue try: entries.append(json.loads(line)) except json.JSONDecodeError as e: print(f"ERROR {path}:{line_num} — invalid JSON: {e}", file=sys.stderr) return entriesFrom
scripts/round-controller.py:python with path.open('r', encoding='utf-8') as f: for line in f: line = line.strip() if line: try: entries.append(json.loads(line)) except json.JSONDecodeError: pass return entriesFrom
scripts/stopping-detector.py:python with path.open('r', encoding='utf-8') as f: for line in f: line = line.strip() if line: try: entries.append(json.loads(line)) except json.JSONDecodeError: pass return entriesTechnical Analysis
The three JSONL loaders continue after encountering malformed records. The controller and stopping detector discard malformed records without even reporting them. Although the validator prints an error, it does not append the parse failure to the list returned by
validate(). The validator can therefore exit successfully after processing an incomplete representation of the state.This is a fail-open integrity defect because claims, verifications, decisions, and lead history are security-relevant inputs to validation and stopping decisions. A malformed or deliberately corrupted record is treated as absent rather than causing the operation to fail.
The append-only design al ...[truncated 1514 chars]
- Remediation
View remediation
Remediation Suggestions
- Make all JSON parsing errors fatal for validation and decision-making.
- Return both parsed entries and parse errors from a shared strict loader.
- Add every malformed line to the validator's error list and force a nonzero exit.
- Include the file path and line number in every parsing error.
- Do not run stopping calculations when any required state file is malformed.
- Consider safely recovering only a demonstrably truncated final line, and require explicit operator confirmation before ignoring it.
- Add tests covering malformed records at the beginning, middle, and end of every JSONL file.
A strict loader could follow this pattern:
python def load_jsonl_strict(path: Path) -> List[Dict]: entries = [] errors = [] if not path.exists(): return entries with path.open("r", encoding="utf-8") as stream: for line_number, line in enumerate(stream, 1): if not line.strip(): continue try: value = json.loads(line) except json.JSONDecodeError as exc: errors.append(f"{path}:{line_number}: {exc}") continue if not isinstance(value, dict): errors.append(f"{path}:{line_number}: expected a JSON object") continue entries.append(value) if errors: raise ValueError("Invalid JSONL state:\n" + "\n".join(errors)) return entries
