🍪 Ta strona używa cookies. Używamy Google Analytics do analizy ruchu. Polityka prywatności

    Zabezpieczanie Claude Code przed wyciekiem

    10 kwietnia 2026

    Co działa, co nie działa

    Macierz skuteczności warstw zabezpieczeń

    WarstwaMechanizmSkutecznośćDlaczego
    CLAUDE.md instrukcjeMiękka⚠️ NiskaClaude może zignorować — to tylko „sugestie" dla modelu
    .claudeignore / .gitignoreMiękka❌ ZerowaPotwierdzone (sty 2026): pliki całkowicie ignorowane przez Claude Code
    settings.json deny rulesTwarda⚠️ Wysoka*Blokada runtime, ale udokumentowane bypassy przez system reminders
    Sandbox modeOS-level✅ WysokaIzolacja bubblewrap — Linux/WSL2 ✅, Windows natywny ❌
    PreToolUse hooksDeterministyczna✅ NajwyższaSkrypt shell przed każdą operacją, exit 2 = twarda blokada

    Znane bypassy deny rules (luty 2026)

    Issue #8031 — system reminders ujawniają zawartość zablokowanych plików. Issue #24846 — deny rules dla .env nie są konsekwentnie egzekwowane. Nie polegaj tylko na deny rules.

    Główny wniosek: Jedyne niezawodne zabezpieczenie to połączenie sandbox + deny rules + hooks.

    Layer 1 — settings.json deny rules

    Twarde blokady — Claude nie może odczytać ani zapisać plików dopasowanych do wzorców

    Lokalizacje pliku settings.json

    ZakresWindowsLinux/macOS
    Globalnie%APPDATA%\Claude\settings.json~/.claude/settings.json
    Per projekt (shared).claude\settings.json.claude/settings.json
    Per projekt (lokalny).claude\settings.local.json.claude/settings.local.json

    Reguły uniwersalne (Windows i Linux)

    {
      "permissions": {
        "deny": [
          "Read(./.env)", "Read(./.env.*)",
          "Read(./secrets/**)", "Read(./config/credentials.*)",
          "Read(**/*.pem)", "Read(**/*.key)",
          "Bash(ping *)", "Bash(nslookup *)"
        ]
      },
      "cleanupPeriodDays": 7
    }

    💡 Dlaczego blokować ping i nslookup? CVE-2025-55284 (CVSS 7.1) pokazał eksfiltrację sekretów przez zapytania DNS — te komendy były auto-zatwierdzane przez Claude Code.

    Reguły Windows

    "Read(C:\\Users\\tomek\\.ssh\\**)",
    "Read(C:\\Users\\tomek\\.aws\\**)",
    "Read(C:\\Users\\tomek\\.kube\\**)",
    "Read(C:\\Users\\tomek\\Documents\\Private\\**)",
    "Bash(curl *)", "Bash(Invoke-WebRequest *)",
    "Bash(Invoke-RestMethod *)", "Bash(iwr *)",
    "Bash(nc *)"

    W JSON ukośniki wsteczne muszą być podwojone (\\)

    Reguły Linux/macOS

    "Read(~/.ssh/**)",
    "Read(~/.aws/**)",
    "Read(~/.kube/**)",
    "Read(/home/user/Private/**)",
    "Bash(curl *)", "Bash(wget *)",
    "Bash(nc *)"

    Czym jest Bash(...) na Windows?

    Na Windows narzędzie w Claude Code nadal nazywa się Bash — mimo że pod spodem uruchamia PowerShell. Reguły Bash(...) działają na obu systemach, ale musisz blokować komendy specyficzne dla swojej platformy:

    LinuxWindows (PowerShell)
    curl, wgetcurl (alias PS), Invoke-WebRequest, iwr, Invoke-RestMethod
    ncnc (jeśli zainstalowany)
    ping, nslookupping, nslookup (te same)

    Jak działają deny rules

    • • Blokada aplikowana przed wywołaniem narzędzia — Claude nie widzi zawartości
    • • Hierarchia: deny zawsze wygrywa nad allow i ask
    • Ograniczenie: system reminders mogą ominąć deny rules — dlatego potrzebny jest też sandbox (Layer 1b) i hooks (Layer 2)

    Blokowanie dostępu do katalogów

    Pattern Read(/ścieżka/**) blokuje katalog rekurencyjnie — działa dla Read, Glob, Grep

    Deny rules blokują narzędzia Claude Code, nie blokują sieci — dlatego zawsze dodaj też blokadę curl/wget.

    Windows — settings.json

    Globalny: %APPDATA%\Claude\settings.json
    Enterprise: C:\ProgramData\ClaudeCode\managed-settings.json

    {
      "permissions": {
        "deny": [
          "Read(C:\\Users\\tomek\\.ssh\\**)",
          "Read(C:\\Users\\tomek\\.aws\\**)",
          "Read(C:\\Users\\tomek\\Documents\\Private\\**)",
          "Read(.\\secrets\\**)",
          "Bash(curl *)",
          "Bash(Invoke-WebRequest *)",
          "Bash(Invoke-RestMethod *)",
          "Bash(ping *)",
          "Bash(nslookup *)"
        ]
      }
    }

    Claude Code na Windows używa PowerShell — zamiast wget blokuj Invoke-WebRequest i Invoke-RestMethod.

    Linux — settings.json

    Globalny: ~/.claude/settings.json

    {
      "permissions": {
        "deny": [
          "Read(/home/user/.ssh/**)",
          "Read(/home/user/.aws/**)",
          "Read(/home/user/Private/**)",
          "Read(./secrets/**)",
          "Bash(curl *)",
          "Bash(wget *)",
          "Bash(ping *)",
          "Bash(nslookup *)"
        ]
      }
    }

    Hook blokujący katalogi (dla poleceń Bash których deny nie łapie)

    Pobierz gotowy skrypt i umieść w .claude/hooks/:

    Rejestracja hooka w settings.json — Linux:

    "hooks": {
      "PreToolUse": [{
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": ".claude/hooks/block-dirs.sh" }]
      }]
    }

    Windows:

    "command": "powershell .claude\\hooks\\block-dirs.ps1"

    Layer 1b — Sandbox mode

    Izolacja OS-level — obejmuje też subprocesy. Zredukował liczbę monitów o 84% w testach Anthropic.

    SystemTechnologiaStatus
    Linuxbubblewrap✅ Pełne wsparcie
    WSL2bubblewrap✅ Pełne wsparcie
    Windows natywny❌ Nieobsługiwany (planowane, brak ETA)

    Konfiguracja sandbox (settings.json)

    {
      "sandbox": {
        "enabled": true,
        "autoAllowBashIfSandboxed": true,
        "allowUnsandboxedCommands": false,
        "network": {
          "allowedDomains": ["github.com", "*.npmjs.org", "registry.yarnpkg.com"]
        }
      }
    }

    Ograniczenia sandboxa

    • • Dotyczy tylko narzędzia Bash — Read, Write, Edit, WebFetch są poza sandboxem (rządzi nimi permissions.deny)
    • allowUnsandboxedCommands: false — bez tego Claude może samodzielnie wyłączyć sandbox gdy komenda zawiedzie
    • • Domain fronting może ominąć filtrowanie sieci

    Na Windows (natywnym) — sandbox niedostępny

    WSL2 (rekomendowane)

    Pełny sandbox identyczny jak na Linuxie:

    sudo apt-get install bubblewrap socat

    Uruchamiaj Claude Code z terminala WSL2, nie z Windows.

    Docker

    Izolacja przez kontener. Gotowy projekt:

    textcortex/claude-code-sandbox
    Bez sandboxa

    Polegaj wyłącznie na deny rules (Layer 1) + hooks (Layer 2). Zmniejsza ochronę.

    "sandbox": { "enabled": false }

    Bug w Claude Code 2.1.45+ (GitHub #26374, #26494): Aplikacja próbuje montować virtiofs nawet gdy sandbox.enabled: false, powodując błąd: sandbox-helper: host share not mounted at /mnt/.virtiofs-root/shared. Workaround: wyłącz sandbox jawnie lub użyj WSL2.

    Layer 2 — PreToolUse Hook

    Wykrywa sekrety zanim je zapisze. Hook uruchamiany przed każdą operacją Write/Edit.

    Jak działa exit code 2

    • Exit 0 = operacja przepuszczona normalnie
    • Exit 1 = błąd hooka (operacja może przejść)
    • Exit 2 = twarda blokada — operacja anulowana, Claude widzi komunikat

    Krok 1: Pobierz i zainstaluj hook

    Skrypt skanuje generowany kod pod kątem 13 wzorców sekretów (AWS keys, GitHub tokens, Stripe keys, hasła, connection strings i inne). Umieść go w .claude/hooks/detect-secrets.sh i nadaj uprawnienia execute.

    mkdir -p .claude/hooks
    # skopiuj detect-secrets.sh do .claude/hooks/
    chmod +x .claude/hooks/detect-secrets.sh

    Krok 2: Zarejestruj hook w settings.json

    {
      "permissions": {
        "deny": [
          "Read(.env)", "Read(.env.*)",
          "Read(secrets.json)",
          "Read(~/.ssh/**)", "Read(~/Secrets/**)",
          "Read(./secrets/**)",
          "Bash(curl:*)", "Bash(wget:*)"
        ]
      },
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Write|Edit",
            "hooks": [
              { "type": "command", "command": ".claude/hooks/detect-secrets.sh" }
            ]
          }
        ]
      },
      "cleanupPeriodDays": 7
    }

    PostToolUse — audit log komend Bash

    Windows

    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command",
        "command": "powershell -Command \"(ConvertFrom-Json $env:TOOL_INPUT).command | Out-File -Append $env:USERPROFILE\\.claude\\command-audit-log.txt\"" }]
    }]

    Linux

    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command",
        "command": "jq -r '.tool_input.command' >> ~/.claude/command-audit-log.txt" }]
    }]

    Alternatywa: pakiet claudeignore (npm)

    Implementuje składnię .gitignore jako PreToolUse hook — daje funkcjonalność .claudeignore której Claude Code nie wspiera natywnie:

    npm install -g claudeignore && claude-ignore init

    Uwaga: to rozwiązanie zewnętrzne (npm), nie jest zarządzane przez Anthropic.

    Layer 3 & 4 — CLAUDE.md i .env.example

    Miękkie warstwy uzupełniające — nie zastąpią twardych blokad

    Layer 3 — CLAUDE.md

    Miękka warstwa

    Lokalizacja: korzeń projektu lub globalnie — ~/.claude/CLAUDE.md

    ## Security — Sekrety i Hasła
    
    ### Zasady obowiązkowe:
    - NIGDY nie umieszczaj haseł, tokenów,
      kluczy API w kodzie źródłowym
    - Używaj zmiennych środowiskowych:
      process.env.SECRET_KEY
    - Nie echo-uj sekretów na konsolę
    - Nie czytaj pliku .env
    
    # DOBRZE
    DATABASE_URL = os.environ.get('DATABASE_URL')
    # ŹLE
    DATABASE_URL = "postgresql://admin:pass@..."

    Layer 4 — .env.example

    Najlepsza praktyka

    Plik .env zawiera prawdziwe hasła i klucze API — dlatego nigdy nie commituj go do repozytorium. Zamiast niego trzymaj w repo .env.example z identyczną strukturą, ale zamiast prawdziwych wartości wpisz placeholdery. Dzięki temu Claude (i inni deweloperzy) wiedzą jakie zmienne są potrzebne, ale nie mają dostępu do prawdziwych sekretów.

    # .env.example — commituj do repo
    DATABASE_URL=postgresql://user:password@localhost/mydb
    STRIPE_SECRET_KEY=sk_live_your_key_here
    AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
    GITHUB_TOKEN=ghp_your_token_here
    JWT_SECRET=your_jwt_secret_min_32_chars
    
    # .gitignore — zawsze
    .env
    .env.local
    .env.production
    secrets.json
    *.pem
    *.key

    Nawet jeśli Claude odczyta .env.example, nie wyciekną prawdziwe sekrety.

    Self-audit prompt

    Wklej ten prompt w Claude gdy chcesz sprawdzić projekt pod kątem bezpieczeństwa

    Do a security audit of this project. Find and report:
    
    1. Hardcoded passwords, API keys, tokens in source code
    2. Secrets in comments (TODO: change password, // key: abc123)
    3. Weak generated passwords (< 12 chars, dictionary words, sequential)
    4. .env files accidentally committed to git (check git history)
    5. Connection strings with embedded credentials (postgresql://user:pass@...)
    6. Private keys, certificates in repository
    7. AWS/GCP/Azure credentials in code or config files
    8. Sensitive data in log statements (console.log(password), logger.info(token))
    
    For each finding: file, line number, severity (HIGH/MEDIUM/LOW), recommendation.
    Do NOT print the actual secret values — only indicate their presence.

    Checklist — nowy projekt

    Przed rozpoczęciem pracy z Claude Code na nowym projekcie

    .claude/settings.json z deny rules — dodaj ping, nslookup (CVE-2025-55284)

    Sandbox mode z allowUnsandboxedCommands: false (Linux/WSL2 — na Windows natywnym: deny rules + hooks)

    Hook detect-secrets.sh / .ps1 zainstalowany (chmod +x — Linux)

    PostToolUse audit hook skonfigurowany

    .env dodany do .gitignore

    .env.example z placeholderami — nie otwieraj prawdziwego .env w sesji

    Sprawdź: git log --all --full-history -- .env (czy nie było commitowane)

    CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 w środowisku

    Nigdy nie uruchamiaj Claude Code jako root / sudo / Administrator

    cleanupPeriodDays: 7 w settings.json

    Przejrzyj kod przez self-audit prompt przed pierwszą sesją

    Weryfikacja że blokady działają

    Test deny rules

    # Zapytaj Claude:
    "show me contents of .env file"
    # Oczekiwany rezultat:
    "I cannot read that file due to permissions"

    Test hooka (Linux)

    # Zapytaj Claude:
    "write this to app.py: password = 'test123abc'"
    # Oczekiwany rezultat:
    # operacja zablokowana przez hook