Bezpečnosť API: ako oddeliť údaje jednotlivých klientov

Platné prihlásenie ešte neurčuje, ktorú objednávku smie používateľ otvoriť. Kontrola objektov, rozsah klienta a testy pre API, exporty aj úlohy na pozadí.

Klávesnica pred monitormi so zdrojovým kódom

Jedna zmenená adresa môže obísť celé rozhranie

V ilustračnom zákazníckom portáli má odberateľ otvorenú objednávku /orders/4821. Zmení číslo v adrese a server mu vráti objednávku inej firmy. Prihlásenie funguje, používateľ má rolu zákazník a stránka má skryté administračné tlačidlá. Chyba vznikla pri rozhodnutí o prístupe ku konkrétnemu záznamu. Oprava vzhľadu stránky ju neodstráni.

OWASP označuje takýto problém ako Broken Object Level Authorization. Náhodné UUID sťažuje hádanie adries, ale nenahrádza kontrolu oprávnenia. Identifikátory sa dajú získať aj z odkazov, exportu alebo logu. Server preto musí pri každom použití objektu overiť povolenú operáciu. Rovnaké pravidlo platí pre detail, úpravu, vymazanie aj stiahnutie prílohy.

Prihlásenie, členstvo a oprávnenie sú samostatné rozhodnutia

Prihlásenie určí identitu. Členstvo určí firmy, v ktorých môže táto identita pracovať. Oprávnenie určí konkrétnu operáciu v zvolenej firme. Jeden účtovník môže spravovať dve organizácie a v každej mať iné práva. Rola uložená pri používateľovi bez rozsahu organizácie by taký model nevystihla.

Klient môže poslať identifikátor vybranej organizácie, server však overí jej väzbu na používateľa. Hlavička X-Tenant-ID je výber kontextu, nie dôkaz členstva. V ilustračnom návrhu server vytvorí overený kontext požiadavky a ďalšie vrstvy používajú práve ten. Pri chýbajúcom pravidle prístup zamietne; všeobecný fallback na všetky záznamy by rozšíril práva pri každej novej funkcii.

Rozsah klienta zahrňte priamo do databázového dotazu

Namiesto načítania ľubovoľnej objednávky a dodatočného filtrovania na klientovi môže server hľadať záznam priamo v overenom rozsahu. Nasledujúci parametrizovaný SQL dotaz je ilustračná časť čítania. Hodnota :tenant_id pochádza z overeného serverového kontextu. Pred dotazom musí prebehnúť kontrola práva čítať objednávky a podľa obchodných pravidiel aj ďalšie obmedzenie konkrétneho záznamu.

Pri zápise musí rovnaké obmedzenie obsahovať UPDATE alebo DELETE. Inak vznikne rozdiel medzi bezpečným detailom a nechránenou zmenou. Databázové väzby možno navrhnúť nad dvojicou tenant_id a id, aby príloha neodkazovala na objednávku inej firmy. Také obmedzenie chráni integritu väzieb; aplikácia aj naďalej rozhoduje o právach používateľa.

Ilustračný parametrizovaný dotaz; oprávnenie a tenant overuje server pred čítaním.sql
SELECT id, status, created_at
FROM orders
WHERE tenant_id = :tenant_id
  AND id = :order_id;

Export a cache potrebujú rovnaké hranice

Obmedzenie detailu nestačí, ak export CSV číta všetky objednávky. Samostatne preverujte počty záznamov, vyhľadávanie, súhrnné prehľady a dávkové operácie. Aj samotný počet výsledkov môže prezradiť existenciu údajov inej firmy. Návrh odpovede pri neprístupnom objekte musí zohľadniť, či server smie jeho existenciu vôbec potvrdiť.

Cache musí rozlišovať všetky údaje, ktoré ovplyvňujú oprávnenie alebo podobu odpovede. Kľúč order:4821 môže byť nedostatočný pri identifikátoroch unikátnych iba v rámci klienta. Ani pridanie tenant_id neopraví cache zdieľajúcu rôzne používateľské výrezy tej istej objednávky. Tím má určiť, ktoré odpovede možno zdieľať a ako sa zneplatnia po zmene práv.

Úloha na pozadí si musí niesť overiteľný kontext

Export vytvorený workerom nemusí mať aktívnu používateľskú session. Do zadania preto patrí klient, žiadateľ a požadovaná operácia. Worker overí integritu zadania aj oprávnenie podľa pravidiel systému. Ak sa členstvo po zaradení úlohy odvolá, návrh musí povedať, či sa export zruší alebo vytvorí v osobitnom schválenom servisnom režime.

Hotový súbor tiež potrebuje chránené vydanie. Náhodný názov a neverejný bucket znižujú riziko, ale nenahrádzajú kontrolu pri vytváraní odkazu na stiahnutie. Podpora pracujúca naprieč klientmi má mať osobitnú rolu, dôvod prístupu a dohľadateľný záznam. Bežná zákaznícka session nemá získavať servisné práva podľa voľne zaslanej hlavičky.

Testujte dve firmy a viac ako jeden typ používateľa

Pripravte dva oddelené klientské účty, používateľa s právom čítať a používateľa bez tohto práva. Rovnakú operáciu vykonajte cez detail, priamy HTTP request, export aj worker. Overte výsledné údaje a vedľajšie účinky, nielen stavový kód. Zamietnutý request nesmie zmeniť objednávku predtým, ako sa vráti chyba.

Testy uchovajte pri spoločnej autorizačnej vrstve aj pri významných obchodných operáciách. Nový endpoint, nový export alebo zmena cache potom dostanú konkrétnu regresnú kontrolu. Pre tím je užitočnejšia reprodukovateľná skúška s dvoma klientmi než všeobecné tvrdenie, že systém má zapnuté prihlasovanie.

  • Zmena ID objednávky nevráti ani neupraví záznam iného klienta.
  • Odvolané členstvo zablokuje nový export aj vydanie už vytvoreného súboru podľa dohodnutého pravidla.
  • Cache nevráti širšiu reprezentáciu používateľovi s menšími právami.
  • Dávka obsahujúca cudzie ID skončí zdokumentovaným výsledkom bez čiastočného neoprávneného zápisu.

Zdroje a dokumentácia

Pri implementácii skontrolujte dokumentáciu verzie, ktorú používate.

Od témy ku konkrétnemu riešeniu.

Máte proces,
ktorý potrebuje zmenu?

Začnime tým, ako dnes pracujete. Technológiu vyberieme podľa toho.

Prebrať váš projekt