Hooki Claude Code: jak zablokować AI groźne komendy, zanim je wykona
Napisałem AI w instrukcji wielkimi literami: „nigdy nie nadpisuj crontaba przez | crontab -”. Dwa tygodnie później Claude Code, pracując na serwerze klientów, zrobił dokładnie to – i kilkadziesiąt zadań cyklicznych zniknęło bez jednego komunikatu o błędzie. Wtedy zrozumiałem, że reguła zapisana zdaniem chroni tylko wtedy, gdy model akurat ją czyta. Rozwiązaniem okazały się hooki Claude Code: mały skrypt, który sprawdza każdą komendę, zanim AI ją wykona, i potrafi powiedzieć „nie”.
W tym wpisie pokazuję, jak hooki w Claude Code zamieniły moje „pamiętaj, żeby…” w twarde bramki. Bez teorii – na czterech wpadkach, które realnie mi się przydarzyły.
Kontekst: AI, które ma klucze do serwerów
Na co dzień pracuję z Claude Code jak z pracownikiem technicznym. Ma dostęp SSH do serwerów, na których stoją strony i platformy kursowe moich klientów, bazę mojego CRM-a, skrzynkę zadań. Robi wdrożenia, aktualizacje wtyczek, poprawki w WordPressie, raporty. Część pracy idzie w nocy, bez nikogo przy klawiaturze.
Przez pierwsze miesiące każdą lekcję zapisywałem w pliku instrukcji (CLAUDE.md i plik procedur). Plik rósł: najpierw kilkanaście, potem kilkadziesiąt ponumerowanych „min”, na które już raz nadepnęliśmy. I wtedy przyszło zderzenie z rzeczywistością.
Cztery wpadki, które pokazały, że instrukcja to za mało
1. Crontab wyczyszczony trzy razy
Wzorzec wyglądał niewinnie: pobierz listę zadań cyklicznych, usuń jedną linię, dopisz nową, zapisz całość z powrotem. Problem w tym, że gdy pierwsze polecenie z jakiegoś powodu odda pustkę, zapis nadpisuje cały crontab jedną linijką. Bez błędu, z kodem wyjścia zero.
Pierwszy raz zdarzyło się to na wspólnym hostingu klientów na początku września. Zapisałem regułę. Następnego dnia – drugi raz, tym razem przez „jednorazowy” skrypt, który miał po sobie posprzątać. Zaostrzyłem regułę i dodałem kontrolę katalogu ze skryptami na serwerze. W październiku trzeci raz: winne było nasze własne narzędzie lokalne, którego kontrola na serwerze w ogóle nie widziała.
2. Hasło administratora w oknie czatu
AI miało wyciągnąć login z pliku z dostępami. Na wypadek, gdyby wyszukiwanie nie trafiło, dopisało sobie „awaryjnie” wyświetlenie kilku pierwszych linii pliku. Wyszukiwanie nie trafiło, bo plik miał wcięcie przed słowem „login”. Wykonało się wyświetlenie i hasło administratora strony klientki wylądowało w rozmowie. Trzeba było je zmienić i wszędzie zaktualizować.
Reguła „nie cytuję sekretów” była w tym czasie zapisana w trzech miejscach.
3. Ban na cały serwer w siedem sekund
Chciałem sprawdzić, czy stara kopia jednej wtyczki nie otwiera się z sieci na kilku stronach. AI zrobiło pętlę po kilkunastu domenach i zapytało każdą o ten sam plik. Zapora hostingu uznała to za skaner: siedem odmów na siedmiu domenach w siedem sekund i adres biura został odcięty od stron, SSH i panelu, do ręcznego odblokowania przez obsługę hostingu.
4. Dane osobowe z bazy
Szukając w CRM-ie wiadomości od klientki, AI zapytało bazę o pełną treść SMS-ów. W jednym z nich były dane osobowe, które klientka przysłała do formularza płatności. Pilnowałem plików z sekretami, a dane wyciekły z bazy.
Wniosek, który zmienił mój sposób pracy z AI: zdanie w instrukcji działa tylko wtedy, gdy model akurat je czyta i akurat łączy je z tym, co robi. Reguły, na którą nadepnąłem po tym, jak ją zapisałem, nie wolno „dopisać mocniej”. Trzeba ją przenieść do kodu.
Czym są hooki Claude Code
Hook to zwykły program, który Claude Code uruchamia w określonym momencie pracy. Mnie najbardziej interesuje zdarzenie PreToolUse – odpalane, zanim AI użyje narzędzia, na przykład zanim wykona komendę w terminalu.
Mechanizm jest prosty:
- Claude Code przekazuje hookowi na wejściu JSON z opisem planowanej akcji – w przypadku terminala jest tam pełna treść komendy,
- hook kończy się kodem
0– komenda idzie dalej, - hook kończy się kodem
2– komenda jest zablokowana, a to, co hook wypisał na stderr, trafia do modelu jako wyjaśnienie, dlaczego.
Najważniejsze: hook nie jest prośbą do modelu. Model może zapomnieć o zdaniu w instrukcji, ale nie ominie programu, który stoi przed terminalem.
Jak to wygląda u mnie w praktyce
Krok 1 – wpis w ustawieniach
Hooki rejestruje się w pliku ~/.claude/settings.json. U mnie każdy hook to osobny, mały skrypt w Pythonie:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "python ~/scripts/crontab-zapis.py" },
{ "type": "command", "command": "python ~/scripts/sekret-do-czatu.py" },
{ "type": "command", "command": "python ~/scripts/skan-wielu-domen.py" }
]
}
]
}
}
Krok 2 – sam hook
Uproszczony szkielet hooka pilnującego crontaba. Prawdziwa wersja ma więcej wyjątków, ale zasada jest ta sama:
import json, re, sys
ZAPIS = re.compile(r'\|\s*crontab\s+-(?!l)|crontab\s+-r')
def main():
try:
dane = json.load(sys.stdin)
komenda = dane.get('tool_input', {}).get('command', '')
except Exception:
sys.exit(0) # błąd hooka nie może zablokować całej pracy
if 'KOSA_CRONTAB_OK=1' in komenda:
sys.exit(0) # świadoma furtka, tylko po mojej zgodzie
if ZAPIS.search(komenda):
print('ZABLOKOWANE: zapis crontaba tylko przez crontab-safe.sh', file=sys.stderr)
sys.exit(2)
sys.exit(0)
main()
Trzy decyzje projektowe, które wyszły z praktyki:
- Błąd samego hooka przepuszcza komendę. Wolę, żeby zepsuty hook nie zatrzymał całej pracy w nocy. Za to każdy hook ma test (o tym niżej).
- Komunikat blokady mówi, co zrobić zamiast. AI nie dostaje samego „nie”, tylko „użyj crontab-safe.sh” – i zwykle w następnym kroku robi to dobrze.
- Furtka jest jawna. Zmienna w komendzie, widoczna w historii. Nie da się jej użyć przypadkiem.
Krok 3 – hook zagląda też do skryptów
Trzecie czyszczenie crontaba nauczyło mnie, że sama komenda to za mało. AI często uruchamia gotowy skrypt .sh, a groźna linia siedzi w środku. Dlatego hook szuka w komendzie nazw skryptów, otwiera je z dysku i sprawdza ich treść – także wtedy, gdy skrypt jest wysyłany na serwer przez ssh host 'bash -s' < skrypt.sh.
Krok 4 – każdy hook ma swój test
To jest część, którą najłatwiej pominąć, a która robi całą różnicę. Hook, którego nie widziałeś odmawiającego, nie jest bramką. Dlatego każdy ma obok skrypt z listą przypadków: komendy, które muszą zostać zablokowane (w tym dokładnie te linie, które kiedyś narobiły szkód), i komendy, które muszą przejść. Test kończy się błędem, gdy choć jeden przypadek się nie zgadza.
Hook od crontaba ma 14 przypadków, hook od sekretów – 16, od skanowania wielu domen – 10, od danych z SMS-ów – 14.
Co dziś pilnują moje hooki
- Zapis crontaba – blokuje nadpisanie całej listy i jej skasowanie, przepuszcza odczyt i zapis przez bezpieczne narzędzie z backupem.
- Sekrety w czacie – blokuje wyświetlanie plików, których nazwa mówi o haśle, kluczu albo dostępach, także gdy ścieżka siedzi w zmiennej. Przepuszcza przekazanie wartości do innego programu bez pokazywania jej na ekranie.
- Skanowanie wielu domen – blokuje zapytania o pliki techniczne do czterech i więcej domen w jednej komendzie. Czy plik istnieje, sprawdza się z dysku jednym połączeniem, nie przez sieć.
- Dane osobowe z bazy – blokuje odczyt pełnej treści SMS-ów. Przepuszcza metadane i treść z zamaskowanymi cyframi.
- Kruche skrypty – blokuje wklejanie kodu z ukośnikami wstecznymi przez heredoc, bo powłoka po drodze po cichu je zjada i poprawka ląduje na serwerze uszkodzona.
Efekt
Nie mam wykresu „o ile procent mniej awarii” i nie będę go wymyślał. Mam za to coś prostszego: odkąd hook od crontaba pilnuje komend i skryptów, AI ani razu nie nadpisało listy zadań cyklicznych. Kilka razy próbowało – i za każdym razem dostało odmowę z instrukcją, a w następnym kroku użyło bezpiecznego narzędzia.
Zmieniła się też moja głowa. Nie muszę już sprawdzać po każdej nocnej sesji, czy AI „pamiętało” o regule. Najgroźniejsze rzeczy po prostu się nie wydarzą, a plik instrukcji przestał puchnąć od coraz głośniejszych ostrzeżeń.
Jak zacząć u siebie – checklista
- Przejrzyj swój plik instrukcji dla AI i wypisz reguły typu „nigdy nie…”. To kandydaci na hooki.
- Przy każdej zadaj pytanie: czy da się to sprawdzić komendą? Jeśli tak – to nie jest zdanie do zapamiętania, tylko bramka do napisania.
- Zacznij od jednej rzeczy, która może zrobić największą szkodę: kasowanie, nadpisywanie, sekrety, masowe zapytania do serwerów.
- Napisz hook PreToolUse z kodem
2i komunikatem, co zrobić zamiast. - Dopisz test z komendą, która kiedyś narobiła szkód, i z komendami, które muszą przejść.
- Zobacz, jak hook odmawia na żywo. Dopiero wtedy wiesz, że działa.
Czego nauczyła mnie ta historia
AI nie jest nieuważne w ludzki sposób, ale efekt jest podobny: reguła, której w danej sekundzie nie ma przed oczami, nie istnieje. Dlatego dziś dzielę wiedzę na dwie półki. W instrukcji trzymam to, jak pracować. W hookach – to, czego nie wolno zrobić nigdy. Każda wpadka, którą da się wykryć mechanicznie, kończy się u mnie kodem z exit 2, a nie kolejnym akapitem.
FAQ
Czym jest hook w Claude Code?
To program uruchamiany automatycznie przez Claude Code w określonym momencie pracy, na przykład przed użyciem narzędzia albo po zakończeniu odpowiedzi. Konfiguruje się go w pliku settings.json. Hook dostaje opis akcji w formacie JSON i może ją przepuścić albo zablokować.
Czym różni się hook od reguły w CLAUDE.md?
Reguła w CLAUDE.md to tekst, który model czyta i może o nim zapomnieć albo nie skojarzyć go z bieżącą komendą. Hook wykonuje się zawsze, niezależnie od tego, co model „pamięta”. Instrukcja uczy, hook egzekwuje.
Jak zablokować komendę w Claude Code?
Zarejestruj hook PreToolUse z matcherem Bash. Skrypt czyta z wejścia JSON, sprawdza pole z komendą i kończy się kodem 2, gdy komenda jest niebezpieczna. Tekst wypisany na stderr trafia do modelu jako powód blokady.
Czy hook nie zablokuje mi całej pracy, jeśli się zepsuje?
To zależy od tego, jak go napiszesz. U siebie każdy wyjątek wewnątrz hooka kończy się kodem 0, czyli przepuszczeniem komendy. Żeby zepsuty hook nie przeszedł niezauważony, każdy ma osobny test uruchamiany po każdej zmianie.
Czy hooki zastępują kopie zapasowe i uprawnienia?
Nie. Hook to dodatkowa warstwa przed wykonaniem komendy. Kopie zapasowe, ograniczone uprawnienia kont i środowisko testowe nadal są potrzebne – hook po prostu wyłapuje błędy, zanim do nich dojdzie.
Chcesz pracować z AI bez nerwów?
Jeśli Claude Code ma u Ciebie dostęp do serwerów, sklepu albo danych klientów, a bezpieczeństwo opiera się dziś na zdaniach w instrukcji – to dobry moment, żeby to zmienić. Na konsultacjach 1:1 pokazuję, jak budować skille, hooki i procedury, dzięki którym AI pracuje szybko i nie robi szkód. Wolisz przejść przez swoją konfigurację indywidualnie? Umów się na konsultację 1:1.
A jeśli wolisz, żeby agenci AI i automatyzacje w Twojej firmie po prostu zostali wdrożeni za Ciebie, zajrzyj do wdrożeń agentów AI w Kosari albo do automatyzacji procesów.
Masz podobny problem? Napisz do mnie
Automatyzacje, AI w firmie, strona albo platforma - odpowiem osobiście, zwykle w ciągu 24 godzin.
