HOME SKILLS BLOG GITHUB
// SECURITY RELEASE

CLAUDE BLOG V1.7.1
SECURITY HARDENING ARC

DANIEL AGRICI // // 8 MIN READ // SECURITY CHANGELOG
Claude Blog v1.7.1 security hardening: 1 CRITICAL and 5 HIGH vulnerabilities closed

v1.7.1 shipped on the same day as v1.7.0. That is not a coincidence. The v1.7.0 community release triggered a security audit pass that surfaced 1 CRITICAL and 5 HIGH vulnerabilities, and v1.7.1 closed every one of them within 24 hours. This is the story of the security debt that was hiding under v1.7.0's release celebrations, and how it got paid down before anyone noticed it was overdue.

The Trigger: Expanded Surface Area, Expanded Threat Model

v1.7.0 was the largest community release in the history of the project. New translation API integrations, NotebookLM workflows, Drive credential flows, and contributor-submitted skills doubled the third-party-code surface in a single release. Independently of those contributions, the v1.6.x credential-handling code had quietly accumulated subtle issues. They were the kind of issues that any individual code review would miss, but a focused pre-release audit catches in 20 minutes.

The audit ran against the v1.7.0 release candidate. Six findings came out of it: one CRITICAL, five HIGH. Every fix shipped in v1.7.1 the next day. Here is what was wrong and how it got fixed.

VULN-001 (CRITICAL): API Key Exposure via .mcp.json Tracking

The bug: setup_image_mcp.py wrote the user's Google AI API key to .mcp.json in the user's project directory. .mcp.json is not in the default .gitignore on most setups. If the user ran git add . and committed the file, the key landed in public repo history the moment they pushed.

The fix: setup_image_mcp.py now defaults to a --global flag that writes the key to ~/.claude/settings.json with file mode 0600 (owner read and write only, no group, no other). Project-local config is still available behind an explicit --local flag, which prints a warning and a suggested .gitignore entry on every invocation. The default is safe.

Who is affected: any user who ran image setup on v1.6.5 through v1.7.0 and committed .mcp.json. The advisory mitigation is rotate the Google AI key, scrub git history (the file may live in old commits even if it is gitignored now), and re-run setup on v1.7.1.

VULN-002 (HIGH): OAuth CSRF Without State Token

NotebookLM and Google API setup used standard OAuth web flows but did not validate the state parameter on callback. RFC 6749 section 10.12 is explicit: state is the canonical CSRF defense for OAuth. Without it, a malicious page could trigger a callback to localhost:port with attacker-supplied code, and the token-exchange code would proceed without checking that the callback corresponded to a request the user actually initiated.

The fix: generate a cryptographically random state token before constructing the auth URL, store it locally, and validate strictly on callback. Mismatches reject the token exchange with a clear error. The local listener is also now bound to 127.0.0.1 instead of 0.0.0.0, which prevents callback hijacking from other machines on the same network.

VULN-003 (HIGH): Hash-Pinned Dependencies Across 4 Lock Files

Supply-chain risk. pip install trusts whatever PyPI serves at install time. A compromised mirror, a typosquat that ships under a real package name briefly, or a hijacked maintainer account can ship malicious code that runs at install time.

The fix: hash-pin every dependency in requirements.txt and 3 nested skill requirements files. CI uses pip install --require-hashes. Hash mismatches now fail loud rather than silently installing whatever PyPI happens to serve. This closes the v1.6.x supply-chain attack surface entirely.

VULN-004 (HIGH): PowerShell 5.1 Compatibility Regression

Not a vulnerability in the classic sense, but a hardening reliability fix. install.ps1 used the PowerShell 7+ three-argument form of Join-Path, which silently fails on the Windows 10 and Windows 11 default of PowerShell 5.1. Users got truncated installs without errors. The skill appeared to install, then silently broke at first run.

The fix: rewrote the installer to use the two-argument Join-Path form plus explicit path validation after every join. Works correctly on PowerShell 5.1 and up across every install path. Verified on a clean Windows 11 image with PowerShell 5.1 only.

VULN-005 (HIGH): Frontmatter Completeness Enforcement

Discovered during the audit: 15 of 27 user-invokable SKILL.md files were missing one or more of description, argument-hint, or license in frontmatter. Not exploitable directly. But a missing license field creates ambiguous redistribution rights, which is a real legal-exposure issue when contributors fork and bundle skills.

The fix: a pytest invariant now requires all three fields on every user-invokable skill. CI blocks merges that violate. Existing skills were brought into compliance in the same PR that introduced the invariant.

VULN-006 (HIGH): Credentials File Permissions

Token cache files at ~/.cache/claude-blog/*.json were created with the default umask. On most Linux and macOS systems, the default umask produces mode 0644, which is world-readable. OAuth tokens are sensitive credentials. World-readable is the wrong choice.

The fix: explicit chmod 0600 after every credential write. Writes are now atomic via tempfile plus shutil.move, which closes the partial-write window where a token file could exist on disk with the wrong permissions for a few milliseconds before the chmod ran.

The 24-Hour Turnaround

Mechanical guardrails enforced via pytest invariants meant that any security-affecting change had to clear an automated bar before merge. The four invariants that made the turnaround possible:

  • No agent grants Bash. Preserves the prompt-injection containment line. If an agent could shell out, prompt injection escalates to remote code execution.
  • No invalid allowed-tools field. Catches typos that silently grant Bash. A field name typo would silently fall back to default, which is overly permissive.
  • Unique skill names. Prevents shadowing attacks where a malicious contribution registers under the same name as a trusted skill.
  • FLOW sync integrity. SHA-256 lockfile validates before write. Any unauthorized modification of the lockfile fails the invariant.

All v1.7.1 fixes passed the invariants on the first try, because the invariants existed before the audit. The lesson: write the guardrails before you need them. A security audit becomes a 24-hour fix sprint instead of a multi-week rewrite when the mechanical bar is already in place.

What This Means For Users

Update to v1.7.1. Specifically:

  • Rotate any Google API key that may have been committed to git via .mcp.json.
  • Re-run image setup if you used v1.6.5 through v1.7.0.
  • Re-authorize Drive sessions and NotebookLM credentials. The previous tokens used permissive file modes and unprotected OAuth flows.
  • If you use Claude Blog in CI, pin to v1.7.1 or later. Hash-pinned requirements are only effective if you pin the skill version too.

Conclusion

Security hardening sprints are unsexy. Nobody tweets about CRITICAL-to-zero in 24 hours the way they tweet about a new feature. But the work compounds. v1.7.1 closed 6 findings, and the next release inherits the higher baseline. Mechanical guardrails do the work that humans forget. Community submissions raise the bar on everyone, and the security review is the price of entry, not a punishment. Ship the guardrails first. The audit will find things. Make sure the things it finds can be fixed in a day.

// AUTHOR

Daniel Agrici

AI Automation Specialist based in Chisinau, Moldova. Creator of 21 open-source repositories with 4,900+ GitHub stars total, including Claude Blog and Claude SEO. GovTech Hackathon Moldova first-place winner. Writes about evidence-led AI content workflows, security hardening of AI tooling, and the operator's view of running Claude Code in production.

Follow: GitHub // YouTube // Skool // LinkedIn

// FAQ

FREQUENTLY ASKED QUESTIONS

VULN-001 was a CRITICAL API key exposure. setup_image_mcp.py wrote Google AI API keys to .mcp.json inside the user's project directory. Any user running v1.6.5 through v1.7.0 who committed .mcp.json to git leaked their key. Mitigation: rotate the key, scrub git history, and re-run setup on v1.7.1 which defaults to the global config path with mode 0600.
Before redirecting the user to the auth URL, v1.7.1 generates a cryptographically random state token and stores it locally. The state is included as a query parameter in the auth URL. When the provider redirects back to the localhost listener, the callback compares the returned state against the stored value. Mismatches reject the exchange. This is the RFC 6749 section 10.12 defense against CSRF.
Hash-pinned dependencies record the SHA-256 of each package alongside its version in requirements files. pip install --require-hashes refuses to install anything that does not match. This blocks supply-chain attacks via compromised PyPI mirrors, typosquats, or hijacked maintainer accounts. v1.7.1 hash-pins every dependency across 4 lock files.
Yes. Several of the fixes apply retroactively to v1.6.5 through v1.7.0. If you ran image setup on any of those versions, rotate your Google AI API key and clean git history if .mcp.json was ever committed. Update via claude plugin install github:AgriciDaniel/claude-blog and re-authorize Drive and NotebookLM credentials.
Each invariant maps to a real prompt-injection or shadowing attack. No agent grants Bash preserves containment. No invalid allowed-tools blocks typos that silently widen permissions. Unique skill names prevents shadowing attacks. FLOW sync integrity uses a SHA-256 lockfile to validate every write. The invariants existed before the audit, which is why v1.7.1 fixes passed on the first try.
// RELATED

KEEP READING

UPDATE TO V1.7.1
TODAY.

$
claude plugin install github:AgriciDaniel/claude-blog
VIEW ON GITHUB ALL ARTICLES >