Kui audiitor esimest korda teie auditijälge küsib, ekspordite tõenäoliselt CSV-faili sellest logisüsteemist, mida te juba käitate, ja see näeb korras välja. Ajatemplid, kasutajanimed, tegevused, ressursi ID-d, kõik korras. Siis küsib keegi ainsa küsimuse, mis loeb: kust me teame, et see fail vastab sellele, mis tegelikult juhtus? Muutumatu auditilogi, mida keegi väljastpoolt teie meeskonda sõltumatult kontrollida ei saa, ei ole tõend. See on väide teie enda käitumise kohta, mille on tootnud süsteemid, mida te kontrollite, formaadis, mille te ise valisite. Audiitorid on selle suhtes viisakad. Regulaatorid muutuvad üha vähem.

"Muutumatu" tähendab enamikus infrastruktuurikihtides midagi nõrgemat, kui sõna ise viitab. Tavaliselt tähendab see lisamisele orienteeritust kokkuleppe alusel - rakendus ainult lisab kirjeid ja kõik on nõus mitte käivitama UPDATE-lauset. Mõnikord tähendab see objektisalvestuse säilituspoliitikat või WORM-korvi (WORM bucket), mis kaitseb kustutamise eest, kuid ei ütle midagi selle kohta, mis algselt kirjutati. Kõik need on reaalsed kontrollid. Ükski neist ei lase kolmandal osapoolel tagantjärele muudatust tuvastada. Just see lõhe - vahe selle vahel, et keegi ei tohiks seda muuta, ja selle vahel, et te saate tõestada, et keegi ei muutnud - ongi kogu teema.

Kuidas manipuleerimiskindel auditijälg töötab

Võtke iga logikirje väli, mis loeb - tegevus, kes selle tegi, millise organisatsiooni nimel, ressurss, muudetud väärtused, korrelatsiooni-ID, riskitase, kliendi aadress -, serialiseerige need kindlas, kokkulepitud järjekorras, lisage eelmise kirje räsi ning käivitage tulemuse peal SHA-256. Salvestage see räsi reale väljana entry_hash ja eelkäija räsi väljana prev_hash. Esimesel real eelkäijat pole, seega on selle prev_hash null. Kõik pärast seda on keevitatud sellega, mis tuli enne.

Tagajärg ongi kasulik osa. Muutke kolm kuud vana kirje sees kasvõi üks tähemärk ja selle uuesti arvutatud räsi ei ühti enam real salvestatuga. Kustutage rida täielikult ja järgmise rea prev_hash osutab eelkäijale, keda pole olemas. Sisestage väljamõeldud kirje ja sel pole järjestuses üldse kehtivat kohta. Te ei pea usaldama salvestuskihti, operaatorit ega tarnijat. Teil on vaja kirjeid, räsimisreegleid ja skripti. Just see teeb sellest manipuleerimiskindla auditijälje, mitte lihtsalt korrektse logi.

Olge täpne selles, mida see teile EI anna. Räsiahel muudab manipuleerimise nähtavaks, mitte võimatuks. Ründaja, kellel on andmebaasi kirjutusõigus ja kes teab räsimisreegleid, saab kirje ümber kirjutada ja seejärel arvutada uuesti kõik sellele järgnevad räsid, luues ahela, mis verifitseerub täiuslikult. Seda võidab ahela pea avaldamine kuskil, mida ründaja ei kontrolli: praeguse entry_hash väärtuse allkirjastamine võtmega, mida hoitakse väljaspool andmebaasi, selle eksportimine, saatmine audiitorile, kirjutamine eraldi süsteemi. Iga neist külmutab ajaloo kuni selle hetkeni.

Miks üksainus kirjutaja on olulisem, kui arvate

Räsiahelal on täpselt üks pea ja iga uus kirje peab selle enne lugema, et saaks sellega siduda. Käivitage sama tabeli vastu kaks kirjutajat ja nad hakkavad võidu jooksma - mõlemad loevad sama pead, mõlemad seovad end sellega ja üks neist on nüüd vale. Ahel teatab end katkisena ja te veedate päeva otsides ründajat, keda pole olemas. Me kohtleme seda muutumatuna, mitte eelistusena: üks protsess tarbib auditijärjekorda ja kirjutab tabelisse ning teise kirjutaja sisselülitamine on teadlik üleminek, mitte skaleerimislüliti.

Ka verifitseerimise ebaõnnestumised peavad olema loetavad, sest operaatorid reageerivad esimesele sõnale, mida nad loevad. Meie verifitseerija teatab kolm erinevat põhjust. chain_broken tähendab, et side on vale, et prev_hash ei ühti eelkäijaga. content_tampered tähendab, et side on terve, kuid salvestatud väljadest räsi uuesti arvutamine annab midagi muud. entry_never_hashed tähendab, et rida kirjutati ilma räsita üldse. Ainult teine on tõend manipuleerimisest ja nende kolme ühte sõnumisse kokku surumine on viis, kuidas käivitada turvaintsident testis oleva vea pärast.

See kolmas juhtum ei ole hüpoteetiline ja seda tasub enda kohta tunnistada. Peotäis ridu meie enda ahelas kirjutati testi poolt, mis sisestas otse tabelisse toore SQL-iga, kirjutajast mööda minnes, jättes mõlemad räsiveerud tühjaks. Andmebaasi päästikud, mis teevad tabeli lisamisele orienteerituks, keelduvad nii kustutamisest kui uuendamisest, mis tähendab, et need read on jäädavalt parandamatud. Nad jäävad ahelasse igaveseks ja iga verifitseerimiskäik jõuab nendeni. Parandus oli abifunktsioon, mida testid peavad kasutama, pluss valvetest, mis läbi kukub hetkel, kui keegi jälle toore SQL-i järele haarab.

Mida audiitor peaks tegelikult saama

Tulemus ei ole ekraanitõmmis dashbordist tekstiga "chain valid". See on CSV, mis sisaldab kirjeid endid koos mõlema räsiveeruga - id, tegevus, tegutseja, organisatsioon, kliendi ulatus, ressursi tüüp ja ID, riskitase, korrelatsiooni-ID, aadress, kasutajaagent, prev_hash, entry_hash ja ajatempel - pluss kirjalik spetsifikatsioon selle kohta, täpselt millised väljad räsi sisse lähevad ja mis järjekorras. Nende kahe asjaga kirjutab audiitor kakskümmend rida Pythonit ja kontrollib teie tööd ilma teilt midagi muud küsimata. See ongi tõend: midagi, mille saate üle anda ja seejärel selle üle kontrolli kaotada.

Väike detail reaalsete tagajärgedega: eksporditud auditiväljad on ründaja poolt mõjutatavad stringid ning arvutustabelid käivitavad kõike, mis algab võrdus-, pluss-, miinus- või at-märgiga. Auditieksport, mis avab audiitori sülearvutis shelli, on meeldejääv viis auditit läbi kukutada. Iga väli meie ekspordis on kaitstud paomärkidega ja valemi-eesliitega väärtused neutraliseeritakse enne faili jõudmist. See on selline kontroll, mis näib pisiasjana kuni hetkeni, mil esimene inimene avab tõendipaki Excelis.

Kõige selle all peab tabel ise keelduma ohtlikest operatsioonidest. Rakenduskoodis jõustatud lisamisele orienteeritus on lubadus, mis püsib täpselt seni, kuni keegi ei kirjuta migratsiooni, koristusskripti või hea tahtega parandust kell kaks öösel. Andmebaasi päästikud, mis lükkavad tagasi UPDATE ja DELETE auditi tabelil, muudavad selle lubaduse piiranguks. See tähendab ka, et rakendus ja salvestus saavad olla eriarvamusel ainult ühes suunas: andmebaas võib keelduda kirjutusest, mida rakendus soovis, kuid rakendus ei saa kunagi andmebaasi vaikselt ümber kirjutada.

Verifitseerige oma muutumatut auditilogi ajakava alusel

Enamik meeskondi, kellel on verifitseerimise lõpp-punkt, kutsub seda üks kord, demo ajal. See on vale sagedus. Ahela katkemine, mis avastatakse siis, kui audiitor küsib, on kohtuekspertiisi probleem, mis katab niipalju kuid, kui on möödunud; sama katkemine, mis avastatakse ajastatud käigu poolt, on vearaport koos ajatempliga. Suure tabeli verifitseerimine peab olema selle jaoks üles ehitatud. Meie oma käib kirjed läbi järjestatud lehtedena, selle asemel et laadida kõik mällu, sest tabel kasvab iga platvormil toimuva muutusega, ning verifitseerija, mis töötab ainult väikeste tabelitega, on verifitseerija, mis lõpetab töötamise.

Teine harjumus on kate. On lihtne panna auditilogimine HTTP middleware'i, vaadata, kuidas iga API-muudatus jälgele ilmub, ja kuulutada asi valmis. Siis arhiveerib cron-töö kliendi andmed, järjekorra tarbija tühistab agendi, taustaprotsess rotib kredentsiaali ja mitte ükski neist pole jäljes, sest mitte ükski neist polnud HTTP-päring. Need teekonnad peavad logima eksplitsiitselt. Ebamugav tõde on, et need tegevused, mida kõige vähem tõenäoliselt logitakse, on täpselt need, mida uurija kõige rohkem näha tahab.

NIS2 ja DORA suruvad samas suunas: kontrollid, mida saate demonstreerida, mitte lihtsalt väita. Keegi ei anna teile sertifikaati SHA-256 kasutamise eest ja meie ka ei väida sellist. Kuid kui keegi küsib, kes muutis tulemüürireeglit kolmandal märtsil, on suur vahe päringutulemuse ja sellise päringutulemuse vahel, mille terviklust võib võõras kontrollida. Kolm küsimust, mida tasub küsida igaühelt, kes teile muutumatut auditilogi müüb: kas saan räsid eksportida, kas saan need teie tarkvarata uuesti arvutada, ja mis juhtub, kui ahel teatab end katkisena?