Kad ljudi zamišljaju hakiranje web stranice, zamišljaju sofisticirane napade i genijalce u kapuljačama. Stvarnost je dosadnija i neugodnija: golema većina provala događa se kroz šačicu banalnih, dobro poznatih propusta. A na vrhu tog popisa, po šteti i po učestalosti, sjedi jedna greška: tajne — API ključevi, lozinke i tokeni — ostavljene tamo gdje im nije mjesto.

Kako ta greška izgleda

Nekoliko tipičnih oblika, svi viđeni bezbroj puta u stvarnim projektima:

  • API ključ upisan izravno u JavaScript koji se isporučuje pregledniku — "pa treba mi na frontendu".
  • Datoteka .env s lozinkom baze commitana u git repozitorij — "pa repozitorij je privatan".
  • Ključ plaćenog servisa u javnom GitHub repou — obično otkriven tek kad stigne račun od nekoliko tisuća eura, jer botovi skeniraju GitHub u minutama od pusha.
  • Admin lozinka u komentaru koda, u README-u, u Slack poruci koja je završila u screenshotu.

Zajednički nazivnik: tajna je tajna samo ako je server jedini koji je zna. Sve što stigne u preglednik, u git povijest ili u javni repozitorij — javno je, zauvijek. Da, i nakon što obrišete commit: git povijest pamti, a botovi su je već pročitali.

Zašto je baš ovo najgora greška

Druge sigurnosne rupe napadaču daju priliku; procurjela tajna daje mu ključeve. Nema probijanja, nema zaobilaženja zaštite — napadač se jednostavno prijavi kao vi. S ključem baze čita i briše podatke; s ključem mail servisa šalje phishing u vaše ime; s cloud ključem diže rudare kriptovaluta na vaš račun. A za razliku od većine napada, ovaj ne zahtijeva nikakvo znanje: automatizirani skeneri rade posao, ljudi samo ubiru plodove.

Kako se zaštititi (konkretno, redom)

  1. Tajne žive samo u environment varijablama na serveru — nikad u kodu, nikad u frontend bundleu. U Next.js aplikacijama, na primjer, varijabla bez NEXT_PUBLIC_ prefiksa nikad ne stiže u preglednik; sve s tim prefiksom smatrajte javnim.
  2. .env datoteke u .gitignore — prije prvog commita. Provjerite odmah: git log --all --oneline -- .env. Ako postoji ijedan rezultat, tajne rotirajte (vidi točku 5), jer brisanje iz povijesti ne poništava ono što je već procurilo.
  3. Frontend nikad ne zove plaćene servise izravno. Treba vam AI API, mail servis, mape? Frontend zove vaš backend endpoint, a on — s ključem koji čuva kod sebe — zove vanjski servis. Usput dobivate i mjesto za rate limiting.
  4. Uključite automatsko skeniranje tajni. GitHub secret scanning i push protection, ili alati poput gitleaks u CI pipelineu — uhvate grešku prije nego što postane incident.
  5. Rotirajte ključ čim posumnjate. Rotacija je pet minuta posla; rasprava "je li itko stigao vidjeti" je rulet. Procurilo = mrtvo, generirajte novi.
  6. Najmanje ovlasti za svaki ključ. Ključ koji smije samo čitati jednu tablicu, s potrošnim limitom na računu, pretvara katastrofu u neugodnost.

Bonus: dvije greške koje idu odmah iza ove

Da popis bude pošten — na drugom i trećem mjestu liste sramote: povjerenje korisničkom unosu (SQL injection i XSS žive i zdrave desetljećima nakon što su rješenja standardizirana — koristite parametrizirane upite i okvire koji escapaju output) i zastarjele ovisnosti (onaj npm audit koji svi ignoriraju i CMS pluginovi bez ažuriranja od 2023.). Obje dijele istu osobinu s curenjem tajni: banalne su, poznate i zato najčešće.

Zaključak

Najgora sigurnosna greška nije egzotična — najgora je upravo zato što je obična, tiha i trenutno unovčiva za napadača. Dobra vijest: cijela obrana staje u jedan popis od šest točaka i jedno poslijepodne posla. Ako danas napravite samo jedno: pretražite svoj repozitorij za tajnama i provjerite što vaš frontend zapravo isporučuje svijetu. Statistika kaže da nećete biti sretni s nalazom — ali bolje da ga nađete vi nego bot.