Skip to content

Commit 074fd91

Browse files
committed
fix: allow_patterns audit log, risk_level recalc, redirect/background mapping, W605
- _scanner: allow_patterns upgrade logs warning + [auto_allowed] in summary - _scanner: risk_level recalculated after blocklist findings appended - _scanner: bash redirect/background findings mapped to SafetyFinding - _bash_scanner: remove raw docstring $(...) causing W605
1 parent fee73a2 commit 074fd91

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

trpc_agent_sdk/tools/safety/_bash_scanner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def _dispatch_commands(self, line_no: int, raw_line: str, tokens: List[str]) ->
259259
self._analyse_one_command_with_dynamic_scan(line_no, raw_line, tokens[seg_start:])
260260

261261
def _analyse_one_command_with_dynamic_scan(self, line_no: int, raw_line: str, cmd_tokens: List[str]) -> None:
262-
r"""Analyse a command segment AND scan all tokens for eval/exec inside \$(...)."""
262+
"""Analyse a command segment AND scan all tokens for eval/exec inside $(...)."""
263263
self._analyse_one_command(line_no, raw_line, cmd_tokens)
264264
# Scan for dynamic commands that appear anywhere in the token stream
265265
# (not just as the head command), so that $(eval "rm -rf /") and

trpc_agent_sdk/tools/safety/_scanner.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,17 @@ def scan(self, scan_input: SafetyScanInput) -> SafetyScanReport:
249249
# Also refuses to upgrade when any CRITICAL finding exists, regardless
250250
# of how the policy maps CRITICAL → decision.
251251
has_critical = any(f.risk_level == RiskLevel.CRITICAL for f in all_findings)
252+
allow_upgraded = False
252253
if (decision == Decision.NEEDS_HUMAN_REVIEW and not has_critical and self._check_allow_patterns(script)):
254+
logger.info("allow_patterns upgraded NEEDS_HUMAN_REVIEW → ALLOW for '%s'", scan_input.tool_name)
253255
decision = Decision.ALLOW
256+
allow_upgraded = True
257+
258+
# ══════════════════════════════════════════════════════════════
259+
# Recompute max_risk after blocklist findings may have been appended
260+
# ══════════════════════════════════════════════════════════════
261+
if all_findings:
262+
max_risk = max(f.risk_level for f in all_findings)
254263

255264
# ══════════════════════════════════════════════════════════════
256265
# Multi-layer evidence redaction (improved from single-layer)
@@ -273,7 +282,8 @@ def scan(self, scan_input: SafetyScanInput) -> SafetyScanReport:
273282
denied = sum(1 for f in all_findings if f.risk_level in (RiskLevel.CRITICAL, RiskLevel.HIGH))
274283
total = len(all_findings)
275284
summary = (f"Scan of '{scan_input.tool_name or 'unnamed tool'}' found {total} issue(s) "
276-
f"({denied} high/critical). Decision: {decision.value}.")
285+
f"({denied} high/critical). Decision: {decision.value}." +
286+
(" [auto_allowed by allow_patterns]" if allow_upgraded else ""))
277287

278288
return SafetyScanReport(
279289
tool_name=scan_input.tool_name,
@@ -676,6 +686,37 @@ def _scan_bash_tokens(self, script: str, scan_input: SafetyScanInput) -> List[Sa
676686
path,
677687
))
678688

689+
# Redirect to sensitive paths (e.g. > /etc/passwd, 2>/dev/sda)
690+
for f in bash_findings:
691+
if f.kind == "redirect":
692+
target = f.extra.get("target", "?")
693+
findings.append(
694+
self._make_finding(
695+
"BASH-FILE-003",
696+
RiskCategory.DANGEROUS_FILE_OPS,
697+
RiskLevel.CRITICAL,
698+
f.evidence,
699+
f"Bash: redirect to sensitive path '{target}'",
700+
"Do not redirect output to sensitive system files.",
701+
f.line_number,
702+
target,
703+
))
704+
705+
# Background execution
706+
for f in bash_findings:
707+
if f.kind == "background":
708+
findings.append(
709+
self._make_finding(
710+
"BASH-PROC-004",
711+
RiskCategory.PROCESS_AND_SYSTEM,
712+
RiskLevel.MEDIUM,
713+
f.evidence,
714+
"Bash: background execution operator &",
715+
"Background execution in tool scripts may indicate persistence or resource abuse.",
716+
f.line_number,
717+
"&",
718+
))
719+
679720
except ImportError:
680721
logger.debug("Bash shlex scanner not available; skipping.")
681722
except Exception:

0 commit comments

Comments
 (0)