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
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2026-05-27 - Resolved Bandit Warnings
**Vulnerability:** Static analysis warnings from Bandit highlighting insecure usage of pseudo-random generators and missing explicit verification of subprocesses without `shell=True`.
**Learning:** `random` module usage triggers B311 and `subprocess` triggers B603/B606 unless suppressed.
**Prevention:** Use `secrets.SystemRandom()` for any random jitter/generation, and document subprocess safety with `# nosec B603` inline pragmas to keep automated security scans clean.
6 changes: 3 additions & 3 deletions ralph_loop/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ def _spawn_child(
time.strftime("%Y-%m-%d %H:%M:%S"), shlex.join(cmd)
).encode("utf-8", errors="replace")
)
proc = subprocess.Popen(
proc = subprocess.Popen( # nosec B603
cmd,
stdin=subprocess.DEVNULL,
stdout=log_handle,
Expand Down Expand Up @@ -822,7 +822,7 @@ def _request_reload(_signum, _frame):
signal.signal(signal.SIGHUP, previous_hup)
sys.stdout.flush()
sys.stderr.flush()
os.execv(
os.execv( # nosec B606
sys.executable, [sys.executable, script_path] + sys.argv[1:]
)
for pr, (proc, _log_path, log_handle, _spawned_at) in list(children.items()):
Expand Down Expand Up @@ -945,7 +945,7 @@ def _fan_out_across_directories(
_print_step(
"Launched repo supervisor for {} (log: {})".format(target_dir, log_path)
)
proc = subprocess.Popen(
proc = subprocess.Popen( # nosec B603
cmd,
stdin=subprocess.DEVNULL,
stdout=log_handle,
Expand Down
4 changes: 2 additions & 2 deletions ralph_loop/git_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def _reset_generated_changes(target_sha: Optional[str] = None):


def _fetch_with_retry(remote: str, ref: str):
import random as _random
import secrets as _secrets
import time as _time

last_exc: Optional[CommandError] = None
Expand All @@ -127,7 +127,7 @@ def _fetch_with_retry(remote: str, ref: str):
raise
last_exc = exc
delay = 0.5 * (2 ** attempt)
_time.sleep(delay + _random.uniform(0, delay))
_time.sleep(delay + _secrets.SystemRandom().uniform(0, delay))
assert last_exc is not None
raise last_exc

Expand Down
4 changes: 2 additions & 2 deletions ralph_loop/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

import os
import random
import secrets
import re
import time

Expand Down Expand Up @@ -51,7 +51,7 @@ def _set_git_config_if_changed(key: str, value: str) -> None:
raise
last_error = exc
delay = _GIT_CONFIG_LOCK_BASE_DELAY * (2 ** attempt)
time.sleep(delay + random.uniform(0, delay))
time.sleep(delay + secrets.SystemRandom().uniform(0, delay))
if _git_config_get(key) == value:
return
raise last_error
Expand Down