Skip to content

Add one-command security tools setup and pre-push scanning#1185

Open
John-David Dalton (jdalton) wants to merge 6 commits intomainfrom
feat/setup-security-tools
Open

Add one-command security tools setup and pre-push scanning#1185
John-David Dalton (jdalton) wants to merge 6 commits intomainfrom
feat/setup-security-tools

Conversation

@jdalton
Copy link
Copy Markdown
Contributor

@jdalton John-David Dalton (jdalton) commented Apr 10, 2026

What this adds

/setup-security-tools command

One command to download and configure all three security tools:

  • AgentShield — scans Claude config for prompt injection/secrets
  • Zizmor — static analysis for GitHub Actions workflows
  • SFW (Socket Firewall) — intercepts package manager commands to block malware

Prompts for a Socket API key (enterprise features), downloads binaries with SHA-256 verification, creates PATH shims (bash + Windows .cmd).

Pre-push scanning

Adds AgentShield + zizmor blocking scans to the pre-push hook. Every push is automatically checked.

Files

  • .claude/hooks/setup-security-tools/ — setup script + README
  • .claude/commands/setup-security-tools.md — the slash command
  • .git-hooks/pre-push — updated with security pre-checks
  • .claude/skills/security-scan/SKILL.md — cross-references the hook
  • .gitignore — tracks hooks and settings

Note

Medium Risk
Adds a new mandatory pre-push gate that can block pushes and introduces a script that downloads/executes external binaries (zizmor/SFW), so misconfiguration or platform edge cases could impact developer workflows.

Overview
Introduces a new /setup-security-tools command and accompanying hook that sets up AgentShield, zizmor, and Socket Firewall (SFW) for local use, including SHA-256–verified binary downloads, caching under ~/.socket/, and PATH shims for supported package managers (with optional enterprise mode via SOCKET_API_KEY).

Adds a .git-hooks/pre-push hook that runs AgentShield and zizmor scans and blocks pushes on findings, plus commit-message AI attribution checks and secret/file hygiene checks. Updates .gitignore to allow committing .claude/hooks/ and settings.json, and documents the new setup in the security scan skill/readmes.

Reviewed by Cursor Bugbot for commit bf5169b. Configure here.

One command to set up AgentShield, zizmor, and Socket Firewall.
Downloads binaries with SHA-256 verification, creates PATH shims
(bash + Windows .cmd), and adds blocking scans to pre-push hook.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: SFW free shims disable SSL verification globally
    • Removed the export GIT_SSL_NO_VERIFY=true line and its comment from the sfw-free shim generation code, eliminating the global SSL verification bypass.

Create PR

Or push these changes by commenting:

@cursor push 6216e6d7db
Preview (6216e6d7db)
diff --git a/.claude/hooks/setup-security-tools/index.mts b/.claude/hooks/setup-security-tools/index.mts
--- a/.claude/hooks/setup-security-tools/index.mts
+++ b/.claude/hooks/setup-security-tools/index.mts
@@ -273,10 +273,6 @@
         'fi',
       )
     }
-    if (!isEnterprise) {
-      // Workaround: sfw-free does not yet set GIT_SSL_CAINFO (temporary).
-      bashLines.push('export GIT_SSL_NO_VERIFY=true')
-    }
     bashLines.push(`exec "${binaryPath}" "${realBin}" "$@"`)
     const bashContent = bashLines.join('\n') + '\n'
     const bashPath = path.join(shimDir, cmd)

You can send follow-ups to the cloud agent here.

- Remove GIT_SSL_NO_VERIFY=true from SFW free shims (MITM risk)
- Remove dead sha256File function and unused createReadStream/createHash imports
- Fix pre-push: skip scan when no baseline exists instead of scanning all history
- Fix pre-push: use remote_sha..local_sha for existing branches to avoid
  re-scanning already-pushed commits
@jdalton
Copy link
Copy Markdown
Contributor Author

Cursor (@cursor) review

- Use $remote variable instead of hardcoded 'origin' in pre-push hook
- Remove unused YELLOW color variable
- Return false from setupSfw when no shims were created
- Add sync note referencing .husky/security-checks.sh
@jdalton
Copy link
Copy Markdown
Contributor Author

Cursor (@cursor) review

Windows .cmd shims for enterprise SFW had no equivalent of the bash
shim's .env.local/.env file reading logic. Enterprise features would
silently fail unless SOCKET_API_KEY was set as an OS-level env variable.
@jdalton
Copy link
Copy Markdown
Contributor Author

Cursor (@cursor) review

1 similar comment
@jdalton
Copy link
Copy Markdown
Contributor Author

Cursor (@cursor) review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Pre-checks may consume stdin, silently skipping commit validation
    • Added </dev/null to both the agentshield and zizmor command invocations so they cannot consume the git ref data from stdin, ensuring the while-read loop processes all refs.

Create PR

Or push these changes by commenting:

@cursor push 0fb9c637e2
Preview (0fb9c637e2)
diff --git a/.git-hooks/pre-push b/.git-hooks/pre-push
--- a/.git-hooks/pre-push
+++ b/.git-hooks/pre-push
@@ -27,7 +27,7 @@
 # ============================================================================
 if command -v agentshield >/dev/null 2>&1 || [ -x "$(pnpm bin 2>/dev/null)/agentshield" ]; then
   AGENTSHIELD="$(command -v agentshield 2>/dev/null || echo "$(pnpm bin)/agentshield")"
-  if ! "$AGENTSHIELD" scan --quiet 2>/dev/null; then
+  if ! "$AGENTSHIELD" scan --quiet 2>/dev/null </dev/null; then
     printf "${RED}✗ AgentShield: security issues found in Claude config${NC}\n"
     printf "Run 'pnpm exec agentshield scan' for details\n"
     TOTAL_ERRORS=$((TOTAL_ERRORS + 1))
@@ -44,7 +44,7 @@
   ZIZMOR="$HOME/.socket/zizmor/bin/zizmor"
 fi
 if [ -n "$ZIZMOR" ] && [ -d ".github/" ]; then
-  if ! "$ZIZMOR" .github/ 2>/dev/null; then
+  if ! "$ZIZMOR" .github/ 2>/dev/null </dev/null; then
     printf "${RED}✗ Zizmor: workflow security issues found${NC}\n"
     printf "Run 'zizmor .github/' for details\n"
     TOTAL_ERRORS=$((TOTAL_ERRORS + 1))

You can send follow-ups to the cloud agent here.

- Redirect agentshield and zizmor stdin from /dev/null to prevent them
  from consuming git's ref data pipe, which would cause the while-read
  loop to silently iterate zero times
- Use computed range base instead of $remote_sha in rebase suggestion
  so new-branch pushes don't print the zero SHA
@jdalton
Copy link
Copy Markdown
Contributor Author

Cursor (@cursor) review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues. You can view the agent here.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit bf5169b. Configure here.

const suffix = sfwPlatform.startsWith('windows') ? '.exe' : ''
const asset = `${prefix}-${sfwPlatform}${suffix}`
const repo = isEnterprise ? 'SocketDev/firewall-release' : 'SocketDev/sfw-free'
const url = `https://github.com/${repo}/releases/latest/download/${asset}`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SFW uses latest URL with pinned checksums

High Severity

The SFW download URL uses releases/latest/download/ which always resolves to the newest release, but the SHA-256 checksums in SFW_ENTERPRISE_CHECKSUMS and SFW_FREE_CHECKSUMS are hardcoded for a specific version. When a new SFW release is published, downloadBinary will fetch the new binary but the checksum won't match, causing the setup to fail. Contrast with zizmor, which correctly pins a version in the URL (releases/download/v${ZIZMOR_VERSION}/).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bf5169b. Configure here.

printf "These commits were likely created with --no-verify, bypassing the\n"
printf "commit-msg hook that strips AI attribution.\n"
printf "\n"
range_base="${range%..*}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shell pattern removes wrong suffix, leaving trailing dot

Medium Severity

${range%..*} uses shortest-suffix matching. For a range like abc123..def456, the glob ..* matches .def456 (shortest suffix starting with a dot), not ..def456. This leaves a trailing dot: range_base becomes abc123. instead of abc123. The suggested git rebase -i command is then invalid. The original .husky/pre-push avoided this by using $remote_sha directly.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bf5169b. Configure here.

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.

2 participants