Przejdź do treści
Newsy

„Don’t ask again” w Claude Code: hasła w 1122 plikach na GitHubie. Jak sprawdzić u siebie

8 min czytania
„Don’t ask again” w Claude Code: hasła w 1122 plikach na GitHubie. Jak sprawdzić u siebie

👁 117 przeczytań

11 sierpnia 2025 roku jeden z użytkowników Claude Code zgłosił na GitHubie błąd numer 5544. Napisał, że komendy, które zatwierdził w agencie, zapisują się w pliku settings.local.json słowo w słowo, razem z kluczami API i tokenami. Nikt z Anthropic nie odpisał. 3 stycznia 2026 roku, po 60 dniach ciszy, automat zamknął zgłoszenie z adnotacją „not planned”. Dziesięć miesięcy później badacze z firmy Apiiro policzyli skutki: na publicznym GitHubie leżą 1122 kopie tego pliku z co najmniej jednym prawdziwym sekretem w środku.

Używam Claude Code codziennie, w folderze z ponad pięcioma setkami podfolderów z projektami. Zanim usiadłem do tego tekstu, przeskanowałem go. Wynik podaję niżej, razem z komendami, którymi w dwie minuty zrobisz to samo u siebie.

Jedno kliknięcie, które zapisuje hasło

Claude Code przed uruchomieniem większości komend w terminalu pyta o zgodę. Oprócz zwykłego „tak” i „nie” jest trzecia opcja: „Yes, and don’t ask again”. Ta dopisuje regułę do pliku .claude/settings.local.json w folderze projektu i od tej chwili pasujące komendy przechodzą bez pytania. Tak to działa według dokumentacji ustawień Claude Code.

Kłopot w tym, że reguła bywa całą komendą, a nie wzorcem. Gdy prosisz agenta, żeby sprawdził, czemu nie działa logowanie do bazy na serwerze testowym, ten składa polecenie z hasłem wyjętym z twojej konfiguracji, bo bez hasła niczego nie sprawdzi. Pytania o zgodę wyskakują po kilka razy na sesję, więc po dziesiątym mało kto czyta długą linijkę do końca. Klik - i hasło trafia do pliku JSON jawnym tekstem. Apiiro odtworzyło to na najnowszych modelach, Opus 5.5 i Fable 5.1, więc winne jest samo narzędzie, a nie konkretny model.

Claude Code próbuje trzymać ten plik z dala od repozytorium. Kiedy pierwszy raz zapisuje go w repozytorium git, dopisuje go do globalnej listy plików ignorowanych na twoim komputerze. Ta ochrona nie podróżuje jednak z projektem: nie trafia do .gitignore repozytorium, nie obejmuje folderu, który dopiero później stanie się repozytorium, ani pliku, który już raz wszedł do commita. Do tego agent często sam go commituje. W 539 z 1105 repozytoriów z sekretem, które prześledziło Apiiro, plik zmienił commit podpisany jako współtworzony przez Claude’a. Instrukcje commitowania każą modelowi omijać .env i credentials.json, ale o własnym pliku z uprawnieniami milczą.

1122 pliki, 1379 sekretów

Shmulik Cohen i Matan Giladi z Apiiro przeszukali publiczny GitHub między 1 a 3 listopada 2026 roku. Znaleźli 104 185 kopii pliku w 103 617 repozytoriach. Sekret siedział w 1122 z nich, czyli w 1,1 procent. Razem to 1379 różnych sekretów: 636 kluczy w formacie znanych dostawców i 743 hasła albo tokeny stojące obok adresu publicznego serwera.

Ponad jedna trzecia otwiera bazę danych wprost: 379 haseł do baz i 122 klucze serwisowe Supabase. Dalej 43 loginy SSH do publicznych serwerów, część z hasłem roota, 42 tokeny do GitHuba, GitLaba i npm oraz 23 klucze AWS. Pliki należą głównie do pojedynczych programistów, ale wśród właścicieli są też 63 organizacje, od kół studenckich po firmy programistyczne. Najmocniejsze przypadki to klucz chmurowy producenta baz danych z uprawnieniami administratora i hasło właściciela bazy w aplikacji z dokumentacją medyczną. Jedna z uprzedzonych firm potwierdziła, że jej klucz działał. Pozostałych nikt nie testował, więc „sekret” znaczy tu tyle, co dane wyglądające na prawdziwe, a nie dane, które na pewno otwierają drzwi.

Najwięcej mówią dwie liczby. W połowie repozytoriów z sekretem plik leżał co najmniej 217 dni, a w 118 ponad rok. Samo usunięcie pliku też niewiele daje, bo starsze wersje w historii git kryją kolejne 734 sekrety w 509 repozytoriach, a 211 forków skopiowało te same dane z 74 projektów. Licząc historię, wspólny plik settings.json i zapisane rozmowy z agentami, Apiiro doszło do 2539 sekretów w 1994 repozytoriach.

Nie przepłacaj za te subskrypcje

Prowadzę sklep z rocznymi dostępami do narzędzi AI - te same konta, o których piszę wyżej, tylko taniej niż w cenniku producenta.

Zobacz, co jest dostępne

Popularne skanery sekretów sporo z tego przepuszczają. Spośród 1122 plików gitleaks oznaczył 564, TruffleHog 643, a 215 nie wyłapało żadne z tych narzędzi. Skanery szukają kluczy o znanym kształcie, tymczasem hasło wpisane po PGPASSWORD= albo sshpass -p wygląda jak zwykłe słowo w zwykłej komendzie.

Co znalazłem u siebie

Mój folder roboczy ma 504 podfoldery i 34 repozytoria git. Plik settings.local.json znalazłem dokładnie jeden, w folderze głównym, z 14 regułami zgody. Skrypt, który szukał w nim haseł, tokenów, kluczy i adresów z hasłem w środku, nie znalazł nic. Folder główny nie jest repozytorium, więc plik i tak nie miał jak trafić na GitHuba. Wspólnych plików settings.json jest dziewięć, sześć z nich śledzi git w projektach demonstracyjnych, i one też są czyste.

Zawdzięczam to raczej przyzwyczajeniu niż przezorności: odpalam Claude Code z jednego folderu nadrzędnego, więc wszystkie zgody lądują w jednym pliku poza gitem. Ciekawiej wyszło gdzie indziej. Apiiro przejrzało też pliki pamięci agentów i w dziewięciu repozytoriach znalazło w nich sekrety. U mnie Claude Code prowadzi ponad tysiąc takich notatek. Mój prosty skaner wskazał w dwóch z nich ciąg, który wygląda na klucz, i te dwie idą dziś do ręcznego przejrzenia. Leżą poza repozytoriami, ale to wciąż zwykły tekst na dysku.

Sprawdzenie w dwie minuty

Na Linuksie, macOS albo w Git Bash na Windows zacznij od listy wszystkich plików ustawień Claude Code w katalogu domowym:

find ~ -path '*/.claude/settings*.json' -not -path '*/node_modules/*' 2>/dev/null

Potem wypisz te, w których coś przypomina sekret. Komenda pokazuje tylko nazwy plików, nie wartości, więc możesz ją puścić przy kimś albo na nagraniu ekranu:

find ~ -path '*/.claude/settings*.json' -not -path '*/node_modules/*' -print0 2>/dev/null |
 xargs -0 grep -lE 'PGPASSWORD=|MYSQL_PWD=|sshpass -p|mysql .*-p[^ ]|Bearer [A-Za-z0-9._-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|AKIA[0-9A-Z]{16}|://[^:/" ]+:[^@/" ]+@'

W PowerShellu na Windows to samo wygląda tak:

Get-ChildItem $HOME -Recurse -Force -Filter 'settings*.json' -ErrorAction SilentlyContinue |
 Where-Object { $_.DirectoryName -like '*\.claude' } |
 Select-String -Pattern 'PGPASSWORD=|MYSQL_PWD=|sshpass -p|Bearer [A-Za-z0-9._-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|AKIA[0-9A-Z]{16}|://[^:/" ]+:[^@/" ]+@' -List |
 Select-Object -ExpandProperty Path

Pusty wynik to nie gwarancja: żaden wzorzec nie złapie każdego hasła, więc długie pliki i tak przejrzyj wzrokiem. Następnie w każdym repozytorium, w którym pracujesz z agentem, sprawdź, czy git śledzi plik teraz i czy śledził go kiedykolwiek:

git ls-files .claude/
git log --all --oneline -- .claude/settings.local.json

Pusta odpowiedź z obu komend to dobra wiadomość. Jeśli trzymasz projekty na GitHubie, wpisz w wyszukiwarce kodu path:.claude/settings.local.json user:twoj-login albo org:twoja-firma. Każde trafienie to plik, który każdy może teraz przeczytać.

Klucz wyciekł: najpierw zmiana, potem sprzątanie

Kolejność ma znaczenie. Najpierw w panelu dostawcy - bazy, chmury, GitHuba - unieważnij i wygeneruj na nowo każde hasło, token i klucz, który plik kiedykolwiek zawierał. Usunięcie pliku z repozytorium nie cofa wycieku, bo stara wersja żyje dalej w historii, w forkach i w klonach u każdego, kto zdążył je pobrać. Przy okazji zajrzyj w logi dostępu u dostawcy, czy ktoś obcy z klucza nie korzystał.

Dopiero potem sprzątanie:

git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git commit -m "Nie sledz lokalnych ustawien Claude Code"

Plik zostaje na dysku, ale git przestaje go śledzić, a wpis w .gitignore jedzie razem z projektem do każdego, kto go sklonuje. Otwórz też sam plik, nawet jeśli nigdy nie był w gicie, i skasuj reguły z hasłami. Historię repozytorium można potem wyczyścić narzędziem git filter-repo, tylko że to już kosmetyka: zmieniony klucz nikomu się nie przyda, a niezmienionego nie uratuje żadne przepisywanie historii.

Na przyszłość wystarczą dwa nawyki. Nie wpisuj sekretów do komend, tylko każ agentowi odwoływać się do zmiennej, na przykład $DATABASE_URL, wtedy reguła zapamięta nazwę zmiennej, a nie hasło. I zatwierdzaj wzorce, takie jak Bash(npm run:*), zamiast pojedynczych komend. W zespole dopisz .claude/settings.local.json do szablonów .gitignore, a foldery agentów (.claude/, .cursor/, .gemini/) traktuj jak pliki .env. O tym, co sam trzymam w plikach dla agentów, pisałem w tekście o CLAUDE.md i AGENTS.md, a szerszy obraz tego, jak AI zmienia bezpieczeństwo, zebrałem w przeglądzie AI w cyberbezpieczeństwie 2026.

Anthropic obiecuje prototypy

Apiiro przekazało wyniki Anthropic przed publikacją. 7 listopada na Hacker News odpowiedział Boris Cherny, szef Claude Code. Przyznał, że narzędzie dotąd nie czyściło sekretów, i zapowiedział, że zespół sprawdzi kilka rozwiązań, w tym wyłapywanie takich komend w trybie auto i proste skanowanie sekretów. Zespół jest - jak napisał - „looking into what we can do to prevent this”. Dodał też, że Claude Code ignoruje plik w gicie już przy jego tworzeniu, więc jego zdaniem kopie na GitHubie ktoś dodał ręcznie. Poprawki na razie nie ma. Zgłoszenie numer 5544 jest dziś zamknięte i zablokowane, a plik, o którym mówi, nadal zapisuje się po każdym kliknięciu „don’t ask again”.

Najczęstsze pytania

Czy problem dotyczy tylko Claude Code?

Mechanizm z zapisem pełnej komendy w pliku projektu Apiiro potwierdziło tylko w Claude Code, spośród 16 porównanych agentów. Sekrety znalazło jednak także w eksportach rozmów z Cursora i aidera, w plikach pamięci agentów oraz w ustawieniach automatycznych zgód Copilota w VS Code.

Czy wystarczy usunąć plik z repozytorium?

Nie. Stara wersja zostaje w historii git, w forkach i w klonach. Jedyną skuteczną reakcją jest zmiana każdego hasła i klucza, który był w pliku, a sprzątanie repozytorium robi się dopiero potem.

Czy tryb auto chroni przed tym problemem?

Częściowo. Cherny poleca tryb auto zamiast stałych reguł zgody. Gdy jednak jeden z czytelników zauważył, że w trybie auto agent też potrafi zapytać o wrażliwą komendę, szef Claude Code przyznał mu rację. Najpewniejsza ochrona to nie wpisywać sekretów do komend wcale.

Czytasz Promptowego częściej? Dodaj go do preferowanych źródeł w Google, a nowe teksty będą wyżej w Twoich wynikach.

Źródła

// Newsletter

Cały tydzień w AI, w jednym mailu

Wybrane premiery, narzędzia i analizy. Raz w tygodniu, prosto do skrzynki.

Zapisz się za darmo →
Za darmo. Wypisujesz się jednym kliknięciem.
// z sieci - nowe teksty w moich serwisach

Wszystkie moje projekty →

Piotr Olszewski

Piotr Olszewski

AUTOR I WYDAWCA

Piotr Olszewski - twórca i autor Promptowego, polskiego serwisu o sztucznej inteligencji. Codziennie śledzi premiery modeli, narzędzia i regulacje AI, i tłumaczy je prostym, konkretnym językiem.

// mapa strony

🛒 Sklep Kinetyka CapCut Pro 460 zł/rok Lovable Pro 450 zł/rok Replit Core 119 zł/rok Zobacz wszystko →
promptowy w liczbach 0tekstów w archiwum0newsów z ostatnich 7 dni0modeli wideo w obserwatorium0zagadek w grach
× ‹ powiększenie ›