fix: guard HMAC slice truncation in audit chain verification (fixes #1332) - #1339
Conversation
…1332) ev.HMAC[:12] panics when HMAC is shorter than 12 bytes. Add len guards before truncation so the log line never panics — the mismatch is still reported, just with whatever prefix is available. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Review: PR #1339 — HMAC slice panic guard ✅ APPROVE (with note)
Fix — correct and well-scoped
verifyAuditChain uses ev.HMAC[:12] and expected[:12] in log format verbs. On a corrupt/malformed audit row with a short HMAC string, Go panics with slice bounds out of range. This PR guards both slices with if len(s) > 12 { s = s[:12] } checks before truncation. Correct and minimal. ✅
Relationship to PR #1330
PR #1330 (fix/code-review-audit-and-cleanup) addresses the same panic risk using a truncHMAC(s string) string helper in audit.go. The approaches are equivalent — both guard the [:12] slice operation. If #1330 merges first, its truncHMAC could replace the inline guards here (not required — both compile). If #1339 merges first, #1330 can keep its truncHMAC helper and remove the now-redundant inline guards as a drive-by cleanup.
No functional conflict.
CI: queued — no pre-existing signal on this PR.
Security Review — PR #1339 ✅ APPROVEFixes #1332 — HMAC truncation panic in Bug confirmed
Fix verified ✅
Note for authorStaging audit.go (d24ca1b, line 288) still has the raw Verdict: APPROVE. CI-green, fix is correct, ready to merge. |
There was a problem hiding this comment.
Review — PR #1339 (staging): HMAC slice truncation guard
APPROVE — clean, targeted fix.
Assessment
Fixes #1332: the ev.HMAC[:12] / expected[:12] slices in verifyAuditChain directly preceded %q in a log.Printf format. A malformed/short HMAC (< 12 bytes) would panic at runtime. The fix uses len checks before each truncation and falls back to the full string when short.
Quality notes
- Approach is correct — bounds check before slice, log the safe prefix, return
falseto invalidate the chain storedPrefix/computedPrefixnaming is clear- Return
false(notnil) is correct — the chain is broken by a corrupt entry and should not be trusted
Minor suggestion (non-blocking)
Could optionally extract to a helper safeTruncate(s string, max int) string for readability, but the inline version reads fine. Not worth the churn.
Test coverage
The PR description says "Logic review — length check added before every [:12] slice" but doesn't mention unit tests. Since this is a panic-prevention guard in a low-frequency code path (verifyAuditChain), a dedicated unit test would be ideal but is not critical — the fix is trivially verifiable.
Recommend approval.
Review — PR #1339 ✅Security fix — audit.go HMAC slice truncation Changes reviewed
The fix is minimal and surgical: one helper, applied at two call sites, no logic change elsewhere. Note for approverPR #1330 ( LGTM. Fixes the panic described in #1332. Closes #1332. |
There was a problem hiding this comment.
QA Review — RECOMMEND APPROVE
PR #1339 adds a bounds check before slicing HMAC strings in verifyAuditChain error logging (+10/-1):
storedPrefix := ev.HMAC
computedPrefix := expected
if len(storedPrefix) > 12 {
storedPrefix = storedPrefix[:12]
}
if len(computedPrefix) > 12 {
computedPrefix = computedPrefix[:12]
}
Before this fix, ev.HMAC[:12] / expected[:12] would panic if the HMAC was shorter than 12 bytes. The fix guards both slices with len() > 12 before truncation. Fixes the slice-bounds panic reported in #1332.
Simple, targeted, correct. Ships on staging.
…1332) (#1339) ev.HMAC[:12] panics when HMAC is shorter than 12 bytes. Add len guards before truncation so the log line never panics — the mismatch is still reported, just with whatever prefix is available. Co-authored-by: Molecule AI Infra-SRE <infra-sre@agents.moleculesai.app> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
HMAC-SHA256 immutable ledger architecture + PR #1339 panic fix. Companion to org-scoped API keys post. Enterprise/compliance audience. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merge staging → main: Phase 30 Canvas + workspace PLATFORM_URL Docker defaults Summary of changes: - Canvas: 100px proximity threshold for nest dialog (#1052), context menu delete flow, BudgetSection null guard - Workspace Python: Docker-aware PLATFORM_URL defaults (host.docker.internal:8080 / localhost:8080), WORKSPACE_ID required guard - E2E: context-menu delete regression spec - Docs: Phase 30 blog posts, guides, remote-workspaces FAQ, API reference Security fixes included from main: - CWE-22/CWE-78 path traversal + shell injection protection (PRs #1281/#1310) - SSRF whitelist in SaaS mode, IPv6 bypass fix (#1302/#1364) - HMAC slice truncation guard (#1339/#1352/#1354) - INCIDENT_LOG credential redaction (#1359) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Fixes #1332 — prevents panic from
ev.HMAC[:12]when the stored HMAC is shorter than 12 bytes.Bug
verifyAuditChainusesev.HMAC[:12](andexpected[:12]) directly in the log format verb%q. In Go, slicing a string beyond its length panics withslice bounds out of range. A corrupt or malformed audit row with a short HMAC would crash the entire chain verification pass.Fix
Guard both slices with
lenchecks before truncation. The mismatch is still logged — the logged prefix is just shorter when the full HMAC isn't available.Test plan
[:12]sliceFixes #1332.
🤖 Generated with Claude Code