Files
cleveragents-core/.semgrep.yml
T
HAL9000 747513bc59 chore(testing): enforce semgrep gate for suppressed exceptions
Fix broken escape hatch mechanism and address reviewer feedback:

- Replace non-functional comment-based pattern-not clauses with Semgrep's native # nosemgrep mechanism for the escape hatch. Semgrep strips comments from the AST so pattern-not clauses matching inline comments never fire; # nosemgrep is the only reliable per-line suppression mechanism.

- Require both # nosemgrep: <rule-id> AND # error-propagation: allow on the same line: the former is the actual suppression, the latter is the mandatory human-readable audit annotation.

- Add raise $EXC from $CAUSE pattern-not entries for both Exception and BaseException variants to prevent false positives on legitimate exception chaining (raise ServiceError from e).

- Switch nox -s lint Semgrep invocation to audit mode (no --error) for the phased rollout: the codebase has ~337 existing suppressions that must be triaged before enforcement mode is enabled. A comment in noxfile.py documents the migration path and references #9103.

- Update CONTRIBUTING.md examples and enforcement description to reflect the dual-comment requirement.
2026-06-14 19:05:21 -04:00

187 lines
5.8 KiB
YAML

rules:
- id: no-eval
pattern: eval(...)
message: >
Use of eval() is a security risk. Do not use eval() in production code.
Consider using ast.literal_eval() for safe evaluation of literals.
languages: [python]
severity: ERROR
paths:
include:
- src/
- id: no-exec
pattern: exec(...)
message: >
Use of exec() is a security risk. Do not use exec() in production code.
Find an alternative approach that does not require dynamic code execution.
languages: [python]
severity: ERROR
paths:
include:
- src/
exclude:
# Intentional controlled-sandbox exec in transform pipeline.
- src/cleveragents/tool/wrapping.py
- id: no-compile-exec
pattern: compile(..., ..., "exec")
message: >
Using compile() with exec mode is a security risk.
Avoid dynamic code compilation in production code.
languages: [python]
severity: ERROR
paths:
include:
- src/
exclude:
# Intentional controlled-sandbox compile in transform pipeline.
- src/cleveragents/tool/wrapping.py
- id: no-os-system
pattern: os.system(...)
message: >
Use of os.system() is insecure. Use subprocess.run() with shell=False instead.
languages: [python]
severity: WARNING
paths:
include:
- src/
- id: no-pickle-loads
pattern: pickle.loads(...)
message: >
Use of pickle.loads() on untrusted data is a security risk.
Consider using json or a safe serialization format.
languages: [python]
severity: WARNING
paths:
include:
- src/
- id: python-no-suppressed-exception
patterns:
- pattern-either:
- patterns:
- pattern: |
try:
...
except Exception:
...
- pattern-not: |
try:
...
except Exception:
raise
- pattern-not: |
try:
...
except Exception:
raise $EXC
- pattern-not: |
try:
...
except Exception:
raise $EXC from $CAUSE
- pattern-not: |
try:
...
except Exception as $VAR:
raise
- pattern-not: |
try:
...
except Exception as $VAR:
raise $VAR
- pattern-not: |
try:
...
except Exception as $VAR:
raise $VAR from $CAUSE
- patterns:
- pattern: |
try:
...
except BaseException:
...
- pattern-not: |
try:
...
except BaseException:
raise
- pattern-not: |
try:
...
except BaseException:
raise $EXC
- pattern-not: |
try:
...
except BaseException:
raise $EXC from $CAUSE
- pattern-not: |
try:
...
except BaseException as $VAR:
raise
- pattern-not: |
try:
...
except BaseException as $VAR:
raise $VAR
- pattern-not: |
try:
...
except BaseException as $VAR:
raise $VAR from $CAUSE
message: >
Broad exception suppression detected. Do not suppress Exception or BaseException
without re-raising or narrowing to a specific exception type.
CRITICAL: Let exceptions propagate to top-level execution (see CONTRIBUTING.md).
To suppress this rule for a justified case, add the following inline comment on
the except line:
# nosemgrep: python-no-suppressed-exception # error-propagation: allow
The '# nosemgrep' comment is the actual suppression mechanism (Semgrep native).
The '# error-propagation: allow' annotation is required for human auditability.
Example of allowed suppression:
try:
resource.cleanup()
except Exception: # nosemgrep: python-no-suppressed-exception # error-propagation: allow
pass # Resource already cleaned up; safe to ignore
languages: [python]
severity: ERROR
paths:
include:
- src/
- id: python-no-suppress-exception
patterns:
- pattern-either:
- pattern: contextlib.suppress(Exception)
- pattern: contextlib.suppress(BaseException)
message: >
Use of contextlib.suppress(Exception) or contextlib.suppress(BaseException)
is not allowed. Do not suppress broad exception types.
CRITICAL: Let exceptions propagate to top-level execution (see CONTRIBUTING.md).
To suppress this rule for a justified case, add the following inline comment on
the same line as the suppress call:
# nosemgrep: python-no-suppress-exception # error-propagation: allow
The '# nosemgrep' comment is the actual suppression mechanism (Semgrep native).
The '# error-propagation: allow' annotation is required for human auditability.
Example of allowed suppression:
with contextlib.suppress(Exception): # nosemgrep: python-no-suppress-exception # error-propagation: allow
resource.cleanup() # Resource already cleaned up; safe to ignore
languages: [python]
severity: ERROR
paths:
include:
- src/