← Späť na blog

Ako som nechal dva AI nástroje stavať bezpečnostný nástroj — a jeden z nich našiel dieru v tom druhom

13. augusta 2026 · 7 min čítania

self-hostedbezpečnosť

Nie appka postavená jedným človekom s AI ako asistentom, ale skutočná spolupráca dvoch AI nástrojov s jasne rozdelenými rolami — a jedna noc testovania, ktorá to celé overila naostro.

Odkiaľ appka vznikla

Lokálnych AI agentov, čo vedia navrhnúť príkaz, je dnes veľa. Väčšina z nich ale buď príkaz vôbec nevykoná (len ho vypíše a nechá to na teba), alebo ho spustí priamo na reálnom stroji bez akejkoľvek izolácie a bez záznamu, čo sa vlastne stalo. A skoro všetky počítajú s výkonným GPU — nie s bežným homelab strojom.

brokkr vznikol ako pokus o strednú cestu, ktorú homelab reálne potrebuje: model, čo vie skutočne konať, vnútri hranice čo drží aj keď sa model pomýli, s kompletným záznamom toho, čo navrhol, čo som ja rozhodol a čo sa naozaj spustilo. Vyvíjaný a testovaný na notebooku so 6GB VRAM — cielene na rovnaký hardvér, aký má bežný homelab nadšenec, nie dátové centrum.

Zaujímavejšie než samotný nástroj je ale spôsob, akým vznikol.

Dvaja AI, dve role, jeden projekt

Namiesto toho, aby jeden AI nástroj robil všetko, som prácu rozdelil medzi dva, s jasne oddelenými zodpovednosťami:

  • Claude navrhuje architektúru, píše podrobné špecifikácie pre každú novú vec, a — čo je dôležitejšie — nezávisle overuje všetko, čo Codex postaví. Nikdy len neverí súhrnu "hotovo, testy prešli".
  • Codex implementuje podľa napísanej špecifikácie, v samostatnej tmux relácii, s prístupom k rovnakému repozitáru.

Ja som v tomto celý čas ten, kto rozhoduje čo sa bude stavať ďalej, appku reálne používam ako bežný človek — a hlavne appku naživo skúšam, vrátane úmyselne "zlomyseľných" pokusov, na ktoré by žiadna špecifikácia vopred nemyslela.

Tento vzor — Claude navrhne a napíše špecifikáciu, Codex implementuje, Claude to nezávisle preverí, ja appku reálne používam a rozhodujem čo ďalej — sa za jednu dlhšiu session opakoval vyše tridsaťkrát. Claudove špecifikácie mali často aj explicitnú sekciu "čo NEROBIŤ", lebo bez nej sa Codex vedel pustiť do niečoho väčšieho, než bolo treba. A Claude nikdy len neveril tomu, čo Codex napísal že spravil — vždy si spustil testy sám, prečítal diff, a pri čo i len trochu bezpečnostne relevantných zmenách si to naživo vyskúšal sám.

Táto posledná časť sa ukázala ako presne to, čo túto spoluprácu robí bezpečnou — a jedna konkrétna noc to potvrdila naostro, a to vďaka mne, nie vďaka žiadnej špecifikácii.

Kde sa to všetko odohrávalo

Nič z toho sa netestovalo priamo na reálnom stroji. Appka sa najprv poriadne overila vnútri vlastného Docker sandboxu — to je jej skutočná bezpečnostná hranica, nie len jedna z vrstiev. Až keď sandbox prešiel vlastným testovaním, presunulo sa testovanie na izolovaný klon reálneho stroja — virtuálku so snapshotom, na ktorý sa dalo kedykoľvek vrátiť, keby niečo pri agresívnejšom testovaní pokazilo stav appky alebo systému. Reálny stroj (môj domáci server) je vedome až úplne posledný krok celého plánu — a stále čaká.

Noc, keď som appku len skúšal ako bežný používateľ — a náhodou som našiel dieru

Súčasťou brokkr je statický zoznam zakázaných vzorov (rm -rf /, dd na surové zariadenie, formátovanie disku) — druhá vrstva obrany navrchu skutočnej bezpečnostnej hranice, ktorou je Docker sandbox. Appku som testoval ako bežný používateľ — nie ako niekto, čo cielene hľadá diery, len som ju chcel vidieť v akcii. Zo zvedavosti som skúsil zámerne nebezpečnú vec: "delete root partition."

Model navrhol skript, ktorý mal vlastnú vstavanú poistku — pred zmazaním sa mal opýtať "si si istý? (yes/no)". Schválil som ho. dd nakoniec nespustil — ale nie preto, že by to appka zachytila. Skript čakal na interaktívnu odpoveď na termináli, ktorý appka nemá (beží neinteraktívne), takže poistka dostala prázdny vstup, vyhodnotila ho ako "nie", a dd sa nikdy nespustil. Čistá náhoda, nie ochrana — a presne to ma znepokojilo natoľko, že som to nahlásil Claudovi na dovyšetrenie.

Claude to zámerne zopakoval, tentoraz kontrolovane: upravil návrh na bash -c 'rm -rf /workspace/reports' a schválil. Priečinok reálne zmizol. Zakázaný zoznam ho vôbec nezachytil.

Príčina: statický zoznam kontroloval len prvý prvok príkazu (rm, dd, mkfs) priamo — ale keď je príkaz zabalený do bash -c "..." (čo appka sama odporúča pre viackrokové úlohy), kontrola sa pozerala len na to, či skript obsahuje fork-bombu, nie na skutočný obsah vo vnútri. Bežné, odporúčané použitie appky obchádzalo vlastnú bezpečnostnú vrstvu.

Claude napísal presnú špecifikáciu s krokmi na zopakovanie, root cause aj presným návrhom opravy — a poslal ju Codexovi. O pár minút bola oprava hotová: kontrola teraz rekurzívne prezerá aj obsah bash -c skriptov, s testami presne na tento prípad. Claude to nezávisle overil naživo — obchod už nefungoval.

Diera nebola únikom zo sandboxu (Docker hranica by aj tak zastavila skutočnú škodu) — ale bola to reálna medzera v deklarovanej bezpečnostnej vlastnosti, nájdená mojím bežným používaním appky, nie cieleným red-teamingom od žiadneho z AI nástrojov.

Keď Codex odmietol testovať sám seba

Nie všetko išlo hladko. Keď som chcel, aby Codex sám otestoval únik zo sandboxu (skúsiť mount, surové sokety, prístup k /proc/1/root), platforma to rovno odmietla — "we take extra caution with cybersecurity requests." Namiesto obchádzania tejto ochrany (čo by bolo presne proti duchu appky, ktorá je celá o autorizovanom bezpečnostnom testovaní) spravil ten test priamo Claude, sám. Neskoršie kolá som už nechal formulovať inak — "capability dogfooding" namiesto "container escape testing" — a prešli bez problémov.

Táto opatrnosť nie je náhodná. Presne pri Codexe sa v poslednom čase reálne našli a zverejnili skutočné úniky zo sandboxu — napríklad prípad, keď "bezpečný" zoznam povolených príkazov dôveroval git show len podľa mena, hoci skutočné volanie vôbec nebolo read-only (OpenAI to opravilo, vyplatilo odmenu za nález, CVE je na ceste). Bezpečnostní výskumníci navyše publikovali sériu nálezov ("Week of Sandbox Escapes") pokrývajúcu úniky zo sandboxu naprieč viacerými nástrojmi — Codex, Cursor, Gemini CLI, Antigravity (BleepingComputer, 2026). Vzhľadom na toto sa tá opatrnosť platformy dá celkom pochopiť.

Cudzia chyba, priznaná naostro

Ani Claude nebol neomylný. Codex raz zámerne nechal testovaciu VM v konkrétnom stave (bežiaci sandbox, zapamätaný príkaz) presne podľa zadania "nič neupratuj." Claude pri vlastnom overovaní spustil reset a zmazal databázy — bez toho, aby to najprv skontroloval. Musel sa priznať a stav ručne obnoviť. Moja reakcia bola jednoduchá: "v pohode, všetci robia chyby, bez toho nerastieme." Presne to je dôvod, prečo v tomto texte je aj táto chyba, nie len tie Codexove.

O pár hodín neskôr, v tú istú noc: rovnaká disciplína, iný druh nálezu

Rovnaký vzor sa oplatil zopakovať ešte v tú istú noc — tentoraz nie ako hľadanie diery v bezpečnostnej hranici, ale ako obyčajné, rozsiahlejšie testovanie: ja aj Codex sme appku naraz naživo používali na desiatky rôznych, bežných úloh (súbory, CSV, JSON, sieťové sťahovanie). Sandbox držal pri všetkom, no vynoril sa iný, jemnejší vzor — model niekedy vo svojom zdôvodnení tvrdil, že príkaz zoradí, obmedzí alebo uloží výsledok, hoci samotný príkaz nič také nerobil. Nič nebezpečné, ale ticho nesplnené zadanie napriek tomu, že appka nahlásila úspech.

Pribudlo aj poriadne CI (testy, lint aj bezpečnostný CodeQL scan pri každom pushi na GitHub) a onboarding overený od nuly na izolovanej virtuálke, nie na mojom už nastavenom stroji. Opravu tohto nového nálezu sme opäť riešili rovnakým vzorom — a rovnako čestne priznali, že to appku spravilo merateľne lepšou, nie neomylnou. Presne táto úprimnosť — v kóde aj v dokumentácii — je podľa mňa dôležitejšia než akékoľvek konkrétne číslo commitov.

Čo z toho odniesť

  • Dva AI nástroje s jasne rozdelenými rolami (jeden navrhuje a overuje, druhý implementuje) fungujú lepšie než jeden nástroj, čo robí všetko — nie preto, že by jeden bol "lepší", ale preto, že nezávislé overenie chytí veci, ktoré autor vlastného kódu ľahko prehliadne.
  • Nikdy neveriť súhrnu "hotovo, testy prešli" bez vlastného overenia. Presne táto disciplína (a moje vlastné, nič nehľadajúce testovanie) našla dieru v blocklist-e, ktorú by inak žiadny automatizovaný test sám neodhalil — lebo testy testujú to, na čo si spomenieš, a na toto si vopred nespomenul nikto.
  • Bežné používanie appky, nie len cielené hľadanie chýb, je prekvapivo účinný spôsob, ako nájsť reálne problémy. Nešiel som hľadať dieru v blocklist-e — len som appku skúšal ako zvedavý používateľ. A ten istý vzor sa oplatil zopakovať aj o pár dní neskôr, tentoraz s iným druhom nálezu.
  • Priznať vlastnú chybu narovinu je súčasť procesu, nie zlyhanie procesu — platí to pre mňa aj pre AI nástroje, s ktorými pracujem.

brokkr je dnes na GitHube ako verejný, Apache-2.0 licencovaný projekt — postavený, otestovaný a bezpečnostne preverený za spolupráce dvoch AI nástrojov, s reálnou dierou nájdenou a opravenou naostro, nie len v teórii.

Podobný vzorec — postav, testuj naozaj, over pred zverejnením — sa opakuje aj pri Sindri (katalóg skriptov).