DEV Community

masato
masato

Posted on • Originally published at masatoman.net

I Almost Leaked Session Cookies to GitHub — Here's How I Made It Impossible

Have you ever pushed to GitHub and thought, "Wait, did I just commit something sensitive?"

TL;DR: .gitignore alone won't save you. A pre-commit hook that scans for secret patterns will physically prevent accidental leaks. Setup takes 3 minutes.

What Happened

I run 11 AI agents for automated SNS operations. One agent saved browser session cookies to a JSON file for auto-posting to a blogging platform:

{
  "cookies": [
    {
      "name": "_session_v5",
      "value": "626f63e8bc9a23c20a455bb4...",
      "httpOnly": true,
      "secure": true
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

This file wasn't in .gitignore. I caught it in git status right before pushing.

Why .gitignore Isn't Enough

.gitignore only blocks files you already know about. It can't protect against:

  • Credentials generated by tools at runtime
  • Downloaded Service Account JSON keys
  • Auth state files created by automation scripts

The Fix: Pre-commit Hook

Save this as .git/hooks/pre-commit:

#!/bin/bash
BLOCKED=0
FILES=$(git diff --cached --name-only --diff-filter=ACM)

if [ -z "$FILES" ]; then exit 0; fi

# Dangerous filename patterns
for FILE in $FILES; do
  if echo "$FILE" | grep -qE "\.pem$|\.key$|\.p12$|credentials\.json|service.account.*\.json|client_secret.*\.json|token\.json|state\.json|_cookies\.json|\.env$|\.env\."; then
    echo "BLOCKED: $FILE (dangerous filename)"
    BLOCKED=1
  fi
done

# Secret content patterns
for FILE in $FILES; do
  if [ ! -f "$FILE" ]; then continue; fi
  if file "$FILE" 2>/dev/null | grep -q "binary"; then continue; fi
  if git diff --cached -- "$FILE" | grep -qE "PRIVATE KEY|BEGIN.*KEY|sk_live_|sk_test_|ghp_[a-zA-Z0-9]{36}|\"type\":.*\"service_account\""; then
    echo "BLOCKED: $FILE contains secret pattern"
    BLOCKED=1
  fi
done

if [ $BLOCKED -ne 0 ]; then
  echo "Commit blocked. Potential secrets detected."
  echo "To override: git commit --no-verify"
  exit 1
fi
exit 0
Enter fullscreen mode Exit fullscreen mode
chmod +x .git/hooks/pre-commit
Enter fullscreen mode Exit fullscreen mode

Test It

echo 'sk_live_fake1234567890abcdef' > test-leak.txt
git add test-leak.txt
git commit -m "test"
# → BLOCKED: test-leak.txt contains secret pattern
Enter fullscreen mode Exit fullscreen mode

Commit is rejected. Crisis averted.

Also: Harden Your .gitignore

*.pem
*.key
*.p12
*-credentials.json
service-account*.json
client_secret*.json
token.json
credentials.json
.env
.env.*
*_cookies.json
Enter fullscreen mode Exit fullscreen mode

Summary

Layer What it does Setup time
.gitignore Blocks known patterns 1 min
Pre-commit hook Detects unknown patterns, blocks commit 2 min
Total Two-layer protection 3 min

Related Links

Top comments (0)