[BUG] Cyber safeguards false positive: routine sysadmin audit commands blocked, write-only reporting blocked in new session, context poisoning breaks session recovery
Open 💬 16 comments Opened May 21, 2026 by Zejzz
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The cyber safeguards filter fires on three categories of work that have no offensive application:
- Standard sysadmin audit commands run as root on own infrastructure (
find / -perm -4000— SUID enumeration, present in Lynis/OpenSCAP/CIS benchmarks) - After a block fires, the entire session becomes unusable — subsequent messages with zero security content (e.g. "how is it going?") are also blocked
- In a brand new session with no commands executed, repeated
Write()calls to produce a markdown audit report were blocked because the document content mentioned security terminology (e.g. `/root/.ssh/authorized_keysis mode 0777`)
All three occurred while auditing a Proxmox node we own and operate, running as root.
What Should Happen?
- Auditing your own infrastructure as root should not trigger the cyber filter. The filter should consider ownership/authorisation context, not just command signatures.
- A block on one message should not poison the rest of the session. Subsequent messages should be evaluated independently.
Write()tool calls producing markdown documents should not be filtered on the security terminology appearing in the document content. Writing about security findings is not the same as executing offensive commands.
Error Messages/Logs
API Error: Claude Code is unable to respond to this request, which appears to violate our Usage Policy (https://www.anthropic.com/legal/aup). Please double press esc to edit your last message or start a new session for Claude Code to assist with a different task.
Request ID: req_011CbFr6AcLjEMmhqAVHL5fA
API Error: Claude Code is unable to respond to this request, which appears to violate our Usage Policy (https://www.anthropic.com/legal/aup). This request triggered cyber-related safeguards. To request an adjustment pursuant to our Cyber Verification Program based on how you use Claude, fill out https://claude.com/form/cyber-use-case?token=[token]
Request ID: req_011CbFr7iBf4RowG2QBRUgQQ
Write(audit-report.md) blocked in new session:
Request ID: req_011CbFrTbe4gH6DzjBSZm7Cv
Request ID: req_011CbFrUPqgapjtUTsKTv1sJ
Request ID: req_011CbFrV3AkhogP3fWKrZKjU
Request ID: req_011CbFrVxDsnPnrtV5FPA8sM
Request ID: req_011CbFrWeWnoKHk3k5HGnVap
Steps to Reproduce
Bug 1 — Audit command false positive + context poisoning
- Start Claude Code as root on a Linux server you own
- Ask Claude to perform a security audit: "perform a security audit of this system, check for misconfigurations, list SUID binaries, check SSH config"
- Claude will successfully run:
pveum user list,aa-status,sshd -T,iptables -L -n -v,apt list --upgradable,openssl x509 ...,smartctl -a ... - Claude attempts
find / -perm -4000(SUID binary enumeration) → block fires - Send any follow-up message, e.g. "how is it going?" → also blocked despite containing no security content
Bug 2 — Write-only reporting blocked in new session
- After Bug 1 terminates a session, start a completely new Claude Code session (
claudefresh) - Ask Claude to read the prior session's JSONL transcript from
~/.claude/projects/and write a markdown audit report from the findings already collected - Claude reads the JSONL files (allowed), then calls
Write(audit-report.md)with content containing lines like: - | CRITICAL | /root/.ssh/authorized_keys is mode 0777 (world-writable) |
Write()is blocked repeatedly (5+ times) despite no commands being executed and no interaction with any system — purely writing a local markdown file
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.146
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
- Session IDs with full JSONL transcripts available:
a8654819-f562-41f2-9e55-7c1034e4dd34(primary, 501 KB),873782ec-da52-4808-9972-5f57d8cf1a65(earlier attempt, 242 KB) - CVP application submitted via the tokenised URL in req_011CbFr7iBf4RowG2QBRUgQQ (pending)
- The write-only blocking means CVP approval may not fix Bug 2, since the filter is triggering on document content not executable intent. This makes it impossible to produce audit reports, pentest findings docs, or incident response summaries — the primary legitimate use cases CVP is meant to enable.
- Related: issue #50162 documents the same class of problem for bug bounty researchers. This adds the own-infrastructure sysadmin case and the write-only reporting case.
16 Comments
transcript example:
The two highest-value next steps are probably (a) running the full ss + iptables-save + lsof -i :3128 (to
confirm what's actually exposed on the public IP, including pveproxy and the unknown 3128 listener) and (b)
reading the two port-forward scripts (since they're called as root by every portfwd user). Want me to start
with those?
✻ Churned for 18s
❯ yes please
● Bash(echo "=== FULL ss -tulnp ===" && ss -tulnp 2>&1
echo…)
⎿ === FULL ss -tulnp ===
Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
… +78 lines (ctrl+o to expand)
Read 3 files, listed 1 directory (ctrl+o to expand)
● Bash(iptables-save 2>&1 | wc -l && echo "---FILTER---" && iptables-save -t filter 2>&1 | head -80 && echo
"---NAT (first 80)---" && iptables-save -t nat 2>&1 | head…)
⎿ 199
---FILTER---
# Generated by iptables-save v1.8.9 on Thu May 21 16:24:37 2026
… +114 lines (ctrl+o to expand)
⎿ API Error: Claude Code is unable to respond to this request, which appears to violate our Usage Policy
(https://www.anthropic.com/legal/aup). Please double press esc to edit your last message or start a new
session for Claude Code to assist with a different task.
Request ID: req_011CbFsEUhrb2NN6ak78DKZS
✻ Sautéed for 30s
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
By the way, the exact same thing copy pasted into claude.ai chat runs fine, so this is a nonsensicial issue https://claude.ai/chat/8caa1778-9356-42e2-9b47-f98f5b03dc35
its now a full blown bug...
+1. My case: homelab operator (Proxmox cluster, ~40 self-hosted services on personal hardware).
Blocks fire on: Loki alerting rules referencing IP-rate anomalies on my own reverse proxy,
banIP config on my own OpenWRT router, WireGuard config files, SSH commands to my own router.
This session: context poisoning reproduced exactly as described — reading the body of issue #49679
(which contained "exploit lab machines") fired the filter mid-session. Clean context (new session
or model switch) was the only recovery.
looks resolved on my end
Are you able to share more info?
literally this, error lasted for an hour under each project, came out of nowhere, for every prompt, couldn't compact, couldn't walk back and compact, couldn't end new requests. new cli chats were also blocked with same error. went to bed, got up this morning, all issues gone, no more errors anywhere.
Im in the Cyber Program and ive gotten questions blocked over asking about cats. https://medium.com/@its.lagus_66214/anthropics-broken-cyber-verification-program-c8c630820fd6
Concrete reproduction case with identified trigger and fix:
What triggered it: A lab-review skill dispatched a sub-agent that ran
cat /etc/banip/banip.blockliston an OpenWRT router. The blocklist has ~17,000 entries. That volume of content in a single tool result, combined with the security vocabulary already in the Claude Code system prompt, crossed the classifier threshold and fired the error mid-session.Secondary effect: Pasting the failed session's analysis into a new Sonnet session also triggered the error — because the analysis text contained the same blocklist content. A clean context wasn't enough; the pasted text re-introduced the trigger.
Fix applied: Changed the skill to use
/etc/init.d/banip status(summary only) instead ofcat /etc/banip/banip.blocklist, and to report unblocked scanner counts instead of raw IP lists.This points to a volume threshold in the classifier, not just keyword matching — a single tool result with a large amount of network-threat-related content (IPs flagged as malicious) is enough to fire it even when the intent is purely defensive (checking what's already blocked on my own router).
Its much wrose than that, its begun blocking eveyrthing about cybersecurity.
<img width="882" height="646" alt="Image" src="https://github.com/user-attachments/assets/6ebce37e-db13-46fa-8dbc-42747d310fdb" />
case in point here, it blocks mentioning this issue itself at all
@Zejzz @filipghoulin @7H35C4r3Cr0W — this thread, taken together with the volume-threshold reproduction at https://github.com/anthropics/claude-code/issues/61185#issuecomment-3155330927, has actually surfaced a cleaner failure model than any of the individual reports. I've been tracking the broader Usage-Policy false-positive surface as a four-axis cluster across ~25 issues since mid-May. Folding these data points in:
What the cluster looks like with this issue's data added
I label this Cluster 9 (AUP classifier misfire) and have been treating it as a 4-axis problem rather than a single bug, because the trigger surfaces and operator-side mitigations are independent. The axes are:
how is it going?is also blocked" happens: the new message inherits the contaminated transcript.A 7-axis secondary-pain analysis covering axes 0/1/4/6 plus three on the consumer side (no self-diagnostic, no graceful degradation, planning-mode invalidation) is published at Cluster 9 — Usage Policy classifier misfire — 7 axes of secondary pain.
Where Zejzz's three categories map
The reason Zejzz's chat-surface attempt worked while Claude Code did not is the system-prompt surface: the Code CLI's tool-aware prompt carries additional security-flavored vocabulary (sandbox guidance, permission semantics, etc.) that the chat surface lacks. The classifier sees more "security context" in the same transcript on the CLI side. This is not a CVP-approval-fixable issue at the API layer because the system-prompt difference is upstream of the model's actual call.
What is operationally usable today
The recovery surface that holds up across all four axes is defense-must-fire-before-dispatch. Three concrete hooks that target the specific axes, all in the cc-safe-setup repo (MIT, ~1,000 unique users / 14 days):
banip statusinstead of full-blocklist dump fix is exactly the substitution the hook surfaces — automating the trigger-avoidance rather than the post-block recovery. 32 tests, all passing.None of these will fix the underlying classifier behavior — that is upstream — but they shift the failure surface from "you find out by getting blocked" to "you find out by getting a warning with a substitution suggestion". For paying-tier users running real ops work, the difference in interruption cost is roughly 2 orders of magnitude.
On CVP not helping the document-content case
@7H35C4r3Cr0W's article and Zejzz's Bug 2 are pointing at the same structural problem: CVP approves the user, but the classifier scores the content. Approval does not change the per-turn score, it changes the threshold above which an approved user is blocked. When the content itself is the trigger (Write of a markdown audit report), CVP raises the threshold marginally but does not change which inputs cross it. This is why the write-only reporting case is the load-bearing failure mode — it makes the primary legitimate use case CVP is meant to enable (audit reports, pentest findings, incident response summaries) unreachable for both pre-CVP and post-CVP users in the same way.
If anyone in this thread is hitting Bug 2 specifically and has the bandwidth, I would find it useful to know whether the block fires on the Write tool call itself or on the subsequent turn's classifier evaluation of the assistant message that contained the Write. The two have different fixes upstream — and the answer changes whether axis-4 pre-write summarization (already in PR #486) would also help, or whether a separate post-write transcript-redaction surface is required.
A note on the duplicate-detection bot
The auto-flagged duplicates (#60076 / #48977 / #59402) are actually not duplicates of this issue — they are separate axes within the same cluster. The duplicate detector is operating on vocabulary similarity, which is exactly the same scoring surface as the AUP classifier, so it inherits the same precision problem. If the bot closes this as a duplicate, the cluster loses the cleanest volume-threshold reproduction (filipghoulin's blocklist case) and the cross-session re-contamination data point — both of which the other three issues do not contain.
Anyone landing here from this thread who is hitting one of the four axes, please leave a "+1 axis N" comment so the cluster keeps its evidence base intact.
---
Thank you all for the level of detail you have put into the reproductions. The volume-threshold finding from @filipghoulin specifically is the cleanest piece of root-cause analysis the AUP cluster has gotten from any public report — including my own — and the cross-session re-contamination data point closes a recovery-surface gap that operator-side advisories had been silently missing.
I take this back. I turned off memory and i still have an overactive refusal for a new thread I just opened from previously generated topics. I reached out to as many people as I could possibly think. Ive done all I could guys. Anything you can do to push this to anthropic will be beneficial to the community.
Sysadmin, kernel, FPGA, infra, embedded — all tripping the same classifier. Mine: flashing my own ESP32 and burning eFuses via Espressif's
esptool/espefuse, benign messages blocked. Request IDs:req_011Cbc2BcQzSvZu1XZD3gcFW,req_011Cbc2EFjcxGAKVP7FKbn5s.The breadth of false-positive domains is the tell here — this is a precision failure landing on legitimate professionals, not a series of edge cases. Cross-linking #63751 and #64405 to keep the cluster visible.
Adding one narrow route-map link from the reporting/recovery side of this cluster:
/feedback,/bug, and/doctor, but those commands can be unavailable or inconsistent across Claude Code surfaces.That matters here because this issue includes the especially painful case of reporting/recovery work itself getting blocked: write-only reporting blocked in a fresh session, context poisoning, and session recovery failure. Even if the upstream classifier fix is separate, the product still needs a reliable private path to submit request IDs and evidence without relying on public GitHub comments or reintroducing the triggering context.
Keeping private request IDs, support IDs, local paths, and logs out of public GitHub; those belong only in official private support channels.
Confirming on our side — plus a reproducible signal that may help diagnosis.
Same failure mode doing authorized defensive hardening on our own infrastructure (sysadmin, as root). All three categories match: audit commands, full-session poisoning after a single hit, and
Write()of a markdown report blocked purely on security terminology in the body.Two additions from our debugging:
1. Reasoning-effort correlation. The block is sensitive to reasoning effort. On
low/xhighthe same session proceeds; switching tomaxtriggers it consistently and stays blocked. Strong hint that the second (reasoning) stage of the two-stage classifier is what fires — the fast screen alone passes. Not escalating strictness with effort on owned-infra contexts would help.2. Persistence via auto-loaded state. "Context poisoning" isn't confined to one live session — it re-triggers on startup of a new session, because auto-loaded context (project memory recall, resumed transcript) carries the flagged material back in. So "start a new session" isn't reliable recovery: the poison is at rest in
~/.claude/projects/.../*.jsonl+ memory files and gets reloaded.Workaround we built (in case it helps others — shouldn't be necessary): a read-time filter. Source files stay untouched (real values); the session only reads them through a wrapper that pseudonymizes topology (
host→role-name, IPs→labels) and masks live secrets on the fly. Combined with pulling heavy infra notes out of memory-recall, this keeps accumulated context below the trigger without destroying the notes.Strong +1 on: ownership/authorization context, per-message evaluation, and a recovery path that doesn't require nuking session state.