Skip to content
Open
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 @@ -7,3 +7,8 @@
**Vulnerability:** The static analyzer was missing `yaml.unsafe_load` and `yaml.full_load` in its `_SERIALISATION_SINKS` mapping, potentially leading to false negatives when tracking untrusted data flowing into these dangerous deserialization functions.
**Learning:** Even if functions are listed in rule specifications (like `_SINK_SPECS`), they also need to be properly categorized in the core taint propagation logic (`_SERIALISATION_SINKS`) to ensure the analyzer correctly sheds validation provenance (converting output to `UNKNOWN_RAW`).
**Prevention:** When adding new sinks to rule definitions, always verify if they need to be added to core propagation mappings like `_SERIALISATION_SINKS` or `_PROPAGATING_BUILTINS`.

## 2026-08-01 - Fix local code execution via git subprocess in tests
**Vulnerability:** The `tests/unit/core/test_gitignore.py` file invoked `git` via `subprocess` against the project root without disabling `core.fsmonitor`. This could allow local code execution via a malicious `.git/config` if a user ran tests in an untrusted cloned repository.
**Learning:** Even test files that run git commands against the repository root must apply safe git configurations, because developers might run tests on untrusted forks or PRs.
**Prevention:** Always apply `("-c", "core.fsmonitor=false")` as `_SAFE_GIT_CONFIG` when invoking `git` via `subprocess` against any directory not strictly created and controlled by the test itself.
6 changes: 4 additions & 2 deletions tests/unit/core/test_gitignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from wardline.core.gitignore import GitignoreMatcher

_SAFE_GIT_CONFIG = ("-c", "core.fsmonitor=false")


def test_comments_and_blanks_ignored() -> None:
m = GitignoreMatcher.from_text("# comment\n\n \nnode_modules/\n")
Expand Down Expand Up @@ -113,7 +115,7 @@ def test_repo_gitignore_tracks_wardline_suppression_state() -> None:
pytest.skip("git is required to validate repository ignore policy")
repo = Path(__file__).resolve().parents[3]
in_worktree = subprocess.run(
["git", "-C", str(repo), "rev-parse", "--is-inside-work-tree"],
["git", *_SAFE_GIT_CONFIG, "-C", str(repo), "rev-parse", "--is-inside-work-tree"],
check=False,
capture_output=True,
text=True,
Expand All @@ -123,7 +125,7 @@ def test_repo_gitignore_tracks_wardline_suppression_state() -> None:

def check_ignore(path: str) -> subprocess.CompletedProcess[str]:
return subprocess.run(
["git", "-C", str(repo), "check-ignore", "--no-index", "-v", path],
["git", *_SAFE_GIT_CONFIG, "-C", str(repo), "check-ignore", "--no-index", "-v", path],
check=False,
capture_output=True,
text=True,
Expand Down