Skip to content

fix: security audit run-3 findings (escalate path normalization, question-answer redaction) - #103

Merged
dyoshikawa merged 7 commits into
mainfrom
fix/security-audit-run-3
Nov 7, 2026
Merged

dyoshikawa merged 7 commits into
mainfrom
fix/security-audit-run-3

Conversation

@dyoshikawa

Copy link
Copy Markdown
Owner

Summary

Fixes from security audit run-3 (two confirmed lows plus cheap needs-validation leads):

  • Escalate rules miss non-canonical paths (escalation-rules:path-candidates-not-host-normalized): in all-tools mode, .env/., .env/, sub/../.env/. (and the same in apply_patch headers) slipped past a *.env rule although OpenCode's path.resolve targets .env. Path-like candidates are now also matched in POSIX-normalized form (backslashes as separators, ./.. and repeated/trailing slashes removed). Adding candidates only escalates more.
  • Question answers redacted after JSON encoding (redaction:question-answer-turn-json-encoded-before-redaction): V2 question-answer turns are now decoded and each string redacted before re-encoding, so private key blocks and quoted KEY="..." / --password "..." answers no longer reach the reviewer provider.
  • Padded option label read as user-typed (conversation:question-answer-label-trim-provenance-mislabel): option labels are trimmed like the answers before classification.
  • Reason channel (hardening for claude-agent-reviewer:reason-channel-and-full-env-extraction / opencode-agent-reviewer:session-read-allow-overrides-host-env-ask-and-user-read-deny): RedactingReviewer now redacts the verdict reason, which reaches the agent as a tool error. The default OpenCode reviewer session keeps the host's .env read rules as deny (*.env, *.env.* deny; *.env.example allow) on V1 and V2. README documents that the reviewer is not bound by operator read denies.

Each fix has a regression test that fails before it.

Test plan

  • pnpm cicheck

🤖 Generated with Claude Code

https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth

A write, read or patch of '.env/.', '.env/' or 'sub/../.env/.' reaches the same file as '.env' after OpenCode's path.resolve, but slipped past a '*.env' rule. Path-like candidates are now also matched in POSIX-normalized form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
… verdict reason

Question-answer turns were redacted after JSON.stringify, so escaped newlines and quotes hid private key blocks and quoted assignments from the rules. Each answer string is now redacted before re-encoding. The reviewer's reason, which reaches the agent as a tool error, is redacted too. Option labels are trimmed like the answers, so a clicked padded label is no longer reported as user-typed text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
The reviewer's read-only permissions replaced the host defaults, dropping its '*.env' read ask. The reviewer now denies reading '*.env' and '*.env.*' (allowing '*.env.example') on V1 and V2. README documents the path normalization, reason redaction and the reviewer's read scope.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
The review rules leave a key block cut at the 300-character reason limit, short values and repeated names visible. The reason is output, not judged, so the generous log redaction now runs on top. README states that the reviewer's .env rule covers read only and that path rules are written without ./.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
…ecisely

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_0179ZomNiDQHCzgoxeRVmfth
@dyoshikawa
dyoshikawa merged commit 5ff3911 into main Nov 7, 2026
1 check passed
@dyoshikawa
dyoshikawa deleted the fix/security-audit-run-3 branch November 7, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant