Čo odhalí
Sentinel odhaľuje; databázové oprávnenia a row-level security zabraňujú. Jedno dopĺňa druhé — Sentinel vám povie, že zapečatená hodnota, pečať alebo história za ňou sa zmenila mimo aplikácie, a odmietne na nej stavať, kým zmenu niekto neschváli.
Aktéri
| Id | Aktér | Schopnosti | V rozsahu |
|---|---|---|---|
| A1 | Zapisovateľ do DB | INSERT/UPDATE/DELETE v ľubovoľnej tabuľke vrátane sentinel_*; bez spúšťania kódu; bez prístupu k env, konfigurácii či APP_KEY. | áno |
| A2 | Zapisovateľ do DB + obnova snapshotu | A1 + nahradenie tabuliek alebo celej databázy starším snapshotom. | áno (plné pokrytie vyžaduje kotvy) |
| A3 | Útočník v sieti / klient | Prehráva, mení alebo duplikuje HTTP požiadavky. | áno |
| A4 | Oprávnený insider | Používa aplikáciu bežne (napr. potvrdzuje zmeny). | auditovaný (aktér + dôvod + zmenené atribúty v denníku chránenom MAC); autorizácia je úlohou aplikácie (Gate hook) |
| A5 | Držiteľ podpisových kľúčov / APP_KEY (kľúče drivera database) / RCE / zápis do konfigurácie | Dokáže sfalšovať čokoľvek. | mimo rozsahu |
Matica detekcie
„Okno“ je čas od posledného kontrolného bodu — predvolene sa plánuje každú minútu.
| # | Útok | Len DB (bez kotvy) | S ≥ 1 externou kotvou | Stav / zistenie |
|---|---|---|---|---|
| 1 | Zmena zapečateného stĺpca | áno | áno | Tampered (+ zmenené atribúty cez značky polí) |
| 2 | Zmena riadkov, z ktorých sa počíta vypočítaná hodnota | áno | áno | Tampered |
| 3 | Skopírovanie hodnôt + pečate z iného riadku / modelu / názvu pečate / scope tenanta / kontextu aplikácie | áno (doménová separácia) | áno | Tampered |
| 4 | Presmerovanie riadku pečate (sealable_id, seal) | áno | áno | Tampered |
| 5 | Zmazanie riadku pečate | áno | áno | Missing (seal_deleted, ak existuje história v denníku) |
| 6 | Vloženie nezapečateného riadku (striktná pečať) | áno | áno | Missing (never_sealed); benevolentná pečať → Unsealed (z definície nejde o zistenie) |
| 7 | Obnova staršieho riadku + jeho staršieho riadku pečate | áno, kým existujú novšie záznamy denníka | áno | Stale (newer_version) |
| 8 | #7 + zmazanie novších záznamov denníka | áno, ak už boli v kontrolnom bode (CheckpointMismatch); vnútri okna nie | áno mimo okna | zistenia v denníku |
| 9 | Obnova celej databázy (vrátane denníka a kontrolných bodov) zo staršieho snapshotu | nie | áno (AnchorAhead) pri každom návrate za posledný ukotvený kontrolný bod | zistenie v denníku |
| 10 | Zmazanie konca kontrolných bodov (+ záznamov) | nie | áno | AnchorAhead |
| 11 | Prepísanie záznamu denníka alebo kontrolného bodu | áno (MAC záznamu / MAC kontrolného bodu + reťaz) | áno | EntryInvalid, CheckpointInvalid, ChainBroken |
| 12 | Zmazanie zapečateného riadku bez tombstonu | áno (sentinel:verify --ledger: živá hlava denníka, riadok chýba) | áno | EntityDeleted |
| 13 | Prepísanie uloženého algorithm / key_id / ring v riadku pečate | áno (algoritmus určuje kľúč; allowlist kruhov; HKDF info viaže ring + kid + algoritmus) | áno | AlgorithmMismatch / UnknownKey / Tampered |
| 14 | Riadky kľúčov drivera database: zámena ring/kid/algoritmu, výmena verejného kľúča, prepísanie, vymazanie či pridanie labelu, podstrčenie obálky vytvorenej cez cast encrypted | áno (AEAD obálka pod vlastným kľúčom odvodeným z APP_KEY viaže každé pole — od verzie 1.2 aj label — aj svoj riadok); kľúč s obálkou spred 1.2 viaže label až po opätovnom zapečatení (sentinel:key:reseal) | áno | KeyIntegrityException → UnknownKey (+ KeyIntegrityViolated) |
| 15 | Riadky kľúčov drivera database: obnova staršej obálky (zrušenie odvolania) — alebo na inštalácii aktualizovanej z 1.1 obálka spred 1.2, ktorej label sa potom prepíše | nie (autentický starý šifrový text) — náprava: uveďte kid v SENTINEL_REVOKED_KEYS, ktoré má vždy prednosť. Prípad spred 1.2: áno, keď je zapnuté sentinel.keys.require_bound_label | nie; prípad spred 1.2 ako pri len DB | — / s require_bound_label: KeyIntegrityException → UnknownKey |
| 16 | Zmeny vykonané a vrátené celé vnútri okna | nie | nie | — (skráťte interval kontrolných bodov) |
| 17 | Prehratie podpísanej HTTP požiadavky | áno (okno created/expires + deduplikácia nonce) | — | replayed, too_old, expired |
| 18 | Zmena tela či hlavičiek podpísanej požiadavky alebo pridanie prepisu metódy | áno (content-digest + podpis; vykonaná metóda musí byť tá podpísaná) | — | digest_mismatch, invalid_signature, malformed |
| 19 | Duplicitný POST (búrka opakovaní, dvojklik) | áno (prehratie / 409) | — | idempotencia |
| 20 | Opätovné použitie idempotenčného kľúča s iným obsahom | áno (422) | — | idempotencia |
| 21 | Opätovné použitie jednorazovej URL | áno (atomické spotrebovanie) | — | 403 |
Čo negarantuje
- Sentinel odhaľuje, nezabraňuje. Riadok môže byť zmenený medzi dvoma overeniami.
- Riadky zapísané cez query builder, surové SQL alebo withoutSealing() sú nezapečatené alebo zastarané, kým sa znovu nezapečatia. Striktné pečate ich nahlásia.
- Kľúče drivera database sú len také bezpečné ako APP_KEY. Driver config drží kľúče mimo databázy — odporúča sa pre predvolený kruh.
- Bez externej kotvy sa návrat celej databázy (#9) a orezanie kontrolných bodov (#10) odhaliť nedajú. S kotvou kontrolný bod nikdy neprepíše kotvu, s ktorou databáza nesúhlasí, takže po návrate si kotva dôkaz ponechá, kým to niekto nepreskúma a kotvu nevyčistí.
- Overenie dokazuje integritu voči poslednej autorizovanej pečati, nie to, že autorizovaná hodnota bola správna.
- Vypočítané hodnoty zo súvisiacich riadkov sú len také čerstvé ako posledné prepečatenie modelu, ktorý ich vlastní.
- MAC so surovým tajomstvom (verifyMac()) je symetrický: kto ho vie overiť, má tajomstvo a vie ho aj sfalšovať — prijímajúca aplikácia aj každý odosielateľ s rovnakým kľúčom. Každému odosielateľovi dajte vlastný kľúč viazaný labelom alebo vlastníkom a kde overovateľ nesmie vedieť podpisovať, použite podpisy HTTP s Ed25519.
- Labelu kľúča spred verzie 1.2 sa dôveruje od jeho prvého prepečatenia: čokoľvek je v stĺpci label, keď sa kľúč prvýkrát znovu zapečatí — cez sentinel:key:reseal alebo akýkoľvek zápis kľúča —, to sa naviaže, preto labely, ktoré príkaz vypíše, skontrolujte. Kým nie je zapnuté sentinel.keys.require_bound_label, obnovená obálka spred 1.2 sa stále otvorí s labelom, ktorý je práve v jej stĺpci.
- MAC nenesie čerstvosť: verifyMac() dokazuje, kto bajty poslal, nie to, že prídu len raz — do správy vložte poradové číslo alebo časovú značku a duplikáty odfiltrujte.
Zámerne mimo rozsahu: dôvernosť (použite casty encrypted v Laraveli), útočník s podpisovými kľúčmi, APP_KEY (pre kľúče drivera database), nasadeným kódom alebo konfiguráciou, a zachytávanie zápisov cez query builder či surové SQL — tie sa odhalia dodatočne.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.