anthropics / anthropics/claude-code-security-review
False-positive filter silently disabled since 2026-02-19: preflight hardcodes retired claude-3-5-haiku-20241022
- Langage dominant
- Python
- Étoiles
- 6.2k
- Forks
- 683
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Description
The Claude-API false-positive filtering stage has been inoperative since
**2026-02-19** for every GitHub Action user. It fails open, so no findings are
lost — but the stage the action advertises and hardcodes on has not run in over
five months, and nothing surfaces that.
## Cause
`ClaudeAPIClient.validate_api_access()` hardcodes its preflight model:
https://github.com/anthropics/claude-code-security-review/blob/0c6a49f1fa56a1d472575da86a94dbc1edb78eda/claudecode/claude_api_client.py#L62
```python
# claudecode/claude_api_client.py:62
self.client.messages.create(
model="claude-3-5-haiku-20241022",
...
)
```
`claude-3-5-haiku-20241022` was retired on 2026-02-19 and now returns
`404 not_found_error`. Note this is independent of the `claude-model` action
input — that value reaches `DEFAULT_CLAUDE_MODEL` and is used for the audit and
for the filter's own calls, but the preflight ignores it.
The 404 is caught in `FindingsFilter.__init__`, which disables the stage:
```python
# claudecode/findings_filter.py:188-192
valid, error = self.claude_client.validate_api_access()
if not valid:
logger.warning(f"Claude API validation failed: {error}")
self.claude_client = None
self.use_claude_filtering = False
```
Since `action.yml:185` sets `ENABLE_CLAUDE_FILTERING: 'true'` unconditionally,
this affects **all** GitHub Action users, not just those who opted in.
## Observed
Two consecutive runs on a private repo, `claudecode-error.log`:
```
[claudecode.claude_api_client] Claude API client initialized successfully
[claudecode.claude_api_client] Claude API validation failed: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-3-5-haiku-20241022'}}
[claudecode.findings_filter] Claude API validation failed: API validation failed: Error code: 404 - ...
```
The corresponding `claudecode-results.json` reports
`"excluded_findings": 0` with an empty `exclusion_breakdown`, which is
indistinguishable from "the filter ran and excluded nothing".
## Why it is hard to notice
`action.yml` prints `claudecode-error.log` to the workflow log only when the
results file is smaller than 2 bytes:
```bash
if [ "$FILE_SIZE" -lt 2 ]; then
...
cat claudecode/claudecode-error.log
```
A run that produces valid JSON — the normal case here — never surfaces the
warning. You have to download the `security-review-results` artifact and read the
log to see it.
## Suggested fixes
1. **Use the configured model for the preflight** — `self.model` (or
`DEFAULT_CLAUDE_MODEL`) rather than a hardcoded ID, so the check cannot drift
out of support independently of the model actually in use. Removing the
preflight entirely would also work: `call_with_retry` already handles and
reports API failures, and `analyze_single_finding` keeps a finding when a call
fails.
2. **Surface the degradation.** When `use_claude_filtering` is requested but
disabled, emit a GitHub Actions `::warning::` and set a flag in
`filtering_summary` so `excluded_findings: 0` cannot be mistaken for a filter
that ran.
Happy to open a PR for either if useful.
Encountered on `0c6a49f`.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Évaluation
Cette issue n'a pas encore été évaluée.