Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ Explicitly defining `allow_pickle=False` is a robust defense-in-depth practice.
**Vulnerability:** MD5 hashing in `fast_mlsirm/report.py` triggered a high severity warning by Bandit, because by default it is assumed to be used for security purposes which is unsafe due to weak hashing.
**Learning:** For non-security purposes like generating unique dom ids, `hashlib.md5()` triggers a vulnerability warning unless `usedforsecurity=False` is passed. This allows bypassing FIPS compliance limitations as well as suppressing false positive warnings.
**Prevention:** Always add `usedforsecurity=False` parameter to `hashlib.md5` and other weak hashing functions unless they are genuinely used for secure cryptography (which they shouldn't be).

## 2024-07-25 - [JSON Parsing DoS via Unbounded Recursion/Memory Allocation]
**Vulnerability:** The HTML report generation in `fast_mlsirm/report.py` (`render_diagnostics_report`) read the entire diagnostics JSON file into memory using `Path.read_text()` and parsed it unconditionally using `json.loads()`. A maliciously crafted input file (e.g., highly nested arrays like `[[...]]`) could easily cause a `RecursionError` or Out-of-Memory (OOM) crash, resulting in a Denial of Service.
**Learning:** `json.loads` does not natively bound recursion depth or input size, making it vulnerable to parsing DoS attacks.
**Prevention:** Always use the existing, hardened `_load_json_bounded` internal utility (from `.io`) instead of raw `json.loads` to enforce input byte limits and nesting limits on untrusted data.
5 changes: 3 additions & 2 deletions python/fast_mlsirm/report.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from __future__ import annotations

import hashlib
import json
import math
from html import escape
from pathlib import Path
from typing import Any

from .io import _load_json_bounded


def render_diagnostics_report(
diagnostics_path: str | Path,
Expand All @@ -17,7 +18,7 @@ def render_diagnostics_report(
"""Render saved diagnostics JSON as a standalone HTML report."""

source = Path(diagnostics_path)
payload = json.loads(source.read_text(encoding="utf-8"))
payload = _load_json_bounded(source, source="diagnostics JSON")
if not isinstance(payload, dict):
raise ValueError("diagnostics JSON must contain an object")

Expand Down
Loading