Přeskočit na hlavní obsah

Autorizace

  • Autorizace = proces ověření, kde je požadovaná činnost nebo služba schválena pro daný subjekt / proces
  • Autorizace není totéž co autentizace (proces ověřování identity)
    • Při návrhu a implementaci aplikace je zapotřebí mít tyto rozdíly na paměti
    • Uživatel, který byl přihlášen (ověřen; např. zadáním emailu a hesla), často není oprávněn přistupovat ke všem zdrojům a provádět všechny akce, které jsou prostřednictvím systému technicky možné
    • Např. webová aplikace může mít běžné uživatele a administrátory, ale běžný uživatel nemá oprávnění provádět akce, které přísluší administrátorům i přes to, že je přihlášen
    • Nepřihlášený uživatel také může mít přístup k veřejným částem aplikace, nebo k celé aplikaci
  • Zranitelnost porušení access controls byla v žebříčku OWASP Top 10 vyhodnocena jako nejznepokojivější a je označena jako zranitelnost s vysokou pravděpodobností zneužití
  • Potenciální dopady zneužití jsou velmi různorodé - jak z hlediska formy, tak závažnosti
  • Útočníci mohou být schopni vytvářet, měnit nebo mazat prostředky, které by měly být chráněny (a ohrozit tak jejich důvěryhodnost, integritu a dostupnost)
  • Skutečný dopad tak souvisí s kritičností a sensitivitou napadených prostředků
  • Firemní náklady úspěšného zneužití se tedy mohou pohybovat od nízkých po velmi vysoké
  • Slabin v autorizaci mohou využít jak přihlášení, tak nepřihlášení uživatelé
  • Horizontální zvýšení oprávnění (možnost přístupu ke zdrojům jiného uživatele) je velmi častou slabinou
  • Chyby související s řízením oprávnění mohou umožnit upravovat nebo mazat citlivé zdroje všech forem (databázové záznamy, statické soubory, osobní údaje), provádět činnosti, jako je vytvoření nového účtu nebo nákladné objednávky, k nimž by neměly mít oprávnění
  • Pokud není správně nastavené logování, může porušení oprávnění zůstat neodhaleno nebo nebude možné identifikovat útočníka či skupinu útočníků

Doporučení

Vynucujte least privilege

  • Zásada nejnižšího oprávnění
  • Princip přidělování uživatelům pouze minimální oprávnění nezbytné pro dokončení jejich práce
  • Tento princip musí být uplatňován jak horizontálně, tak vertikálně
    • Účetní i obchodní zástupce mohou být ve firemní hierarchii na stejné úrovni
    • Účetní by neměla mít přístup k databázi zákazníků a obchodní zástupce k údajům o mzdách
    • Podobně vedoucí obchodního oddělení bude pravděpodobně potřebovat vyšší oprávnění než jeho podřízení
  • Nevynucení tohoto pravidla může ohrozit důvěryhodnost citlivých údajů
  • Nad touto strategií je potřeba přemýšlet už ve fázi návrhu architektury (CWE-272), nicméně je potřeba ji řešit v průběhu celého životního cyklu aplikace (SDLC)

Best practices

  • Je mnohem snazší uživatelům udělit nová oprávnění, než jim odebrat ta stívající
  1. Zajistěte, aby byly ve fázi návrhu definovány trust boundaries
  2. Stanovte, jaké typy uživatelů budou k aplikaci přistopovat a jaké operace mohou provádět (read, write, delete, update …)
  3. Pro každou kombinaci uživatele a zdroje stanovte, jaké operace mohou být prováděny
  4. Zohledněte veškeré atributy
    • Např. obchodní zástupce má přístup k databázi zákazníků po celou dobu pracovní doby, ale ne z domova o půlnoci
  5. Vytvořte testy, které ověří, zda jsou tato oprávnění správně vynucována
  6. Pravidelně kontrolujte oprávnění v systému, zda oprávnění uživatelů nepřekračují oprávnění definovaná při návrhu (vyjma všechny schválené změny)

Deny by default

  • V případě, že nejsou explicitně povolena žádná pravidla pro řízení přístupu, nemůže aplikace zůstat v neutrálním stavu - vždy musí rozhodnout, zda přístup povolí nebo odmítne
  • Může také dojít k logickým chybám souvisejících s řízením přístupu, zejména pokud jsou požadavky na přístup složité
  • Z bezpečnostních důvodů by aplikace měla být nakonfigurována tak, aby ve výchozím nastavení přístup odmítla

Best practices

  1. Přijměte mentalitu “deny-by-default” jak během počátečního vývoje, tak při přidávání nových funkcionalit
  2. Explicitně zdůvodněte, proč bylo určité oprávnění uděleno konkrétnímu uživateli nebo skupině
  3. Nepovolujte přístup ve výchozím nastavení

Ověřujte oprávnění pro každý požadavek

  • Oprávnění by mělo být ověřováno pro každý požadavek - AJAX, na straně serveru nebo z jiného zdroje
  • Technologie použitá k provádění kontrol by měla umožňovat globální konfiguraci pro celou aplikaci
    • Neměla by být aplikována pro každou třídu nebo metodu zvlášť
    • Útočníkovi stačí najít pouze jednu cestu dovnitř …
  • Ověřování oprávnění pouze u většiny požadavků je tedy nedostatečné
  • Mezi technologie, které mohou vývojářům pomoci patří například tyto:

Zkontrolujte autorizační logiku nástrojů a technologií, případně implementujte vlastní logiku

  • Vývojáři mají přístup k velkému množství knihoven, platforem a frameworků, které jim umožňují implementovat komplexní logiku s minimálním úsilím
  • Ne vždy je možné tyto komponenty považovat za rychlý všelék na všechny problémy při vývoji
  • Vývojáří musí tyto komponenty používat s rozvahou a zodpovědně
  • Obecnými problémy s tím souvisejícími jsou:
    • nesprávná a nedostatečná konfigurace ze strany vývojáře
    • zranitelnosti v samotných komponentách
  • I v jinak bezpečné aplikaci mohou zranitelnosti v komponentách třetích stran umožnit útočníkovi obejít autorizační kontroly
  • Takové problémy mohou potkat nejen špatně udržované projekty, ale také robustní, často nejoblíbenější knihovny a frameworky
  • Předpokládejte tedy, že každá komponenta, kterou do své aplikace začleníte, může být zranitelná

Důležité úvahy

  1. Vytvořte, udržujte a dodržujte procesy pro detekci a reakci na zranitelné komponenty
  2. Začleňte do procesu správy aplikace nástroje jako je Dependency Check
  3. Zvažte odběr novinek týkající se bezpečnostních zranitelností (např. NVD)
  4. Nespoléhejte se na jediný framework, knihovnu nebo technologii, která by byla tou jedinou věcí, jež by vynucovala řízení přístupu
  • K nefunkční autorizaci také vede chybná (nebo žádná) konfigurace
  • Komponenty jsou většinou navržené jako univerzální, aby oslovily co největší publikum
  • Pro všechny případy (mimo ty základní) je vyžadována úprava nebo doplnění logiky, aby se splnily konkrétní požadavky aplikace
  • To je důležité hlavně v kontextu bezpečnostních požadavků a autorizace

Konfigurační aspekty autorizace

  1. Snažte se porozumět každé technologii, na které stavíte autorizační logiku
  2. Analyzujte možnosti technologií s vědomím, že autorizační logika může být pro požadavky vaší aplikace nedostatečná
    • Spoléhání se na připravenou logiku je pohodlné, ale ne vždy dostačující
  3. Smiřte se s tím, že pro splnění požadavků na zabezpečení aplikace může být nezbytná vlastní autorizační logika
  4. Nedovolte, aby byly požadavky na autorizaci řízeny možnostmi knihovny nebo frameworku
    1. Stanovte nejdříve požadavky na autorizaci a následně analyzujte komponenty třetích stran s ohledem na tyto požadavky
  5. Nespoléhejte se na výchozí konfiguraci
  6. Testujte konfiguraci
    1. Nepředpokládejte, že konfigurace komponenty bude fungovat přesně tak, jak jste zamýšleli (dokumentace může být zastaralá, neúplná nebo nejasná)

Preferujte autorizaci na základě atributů a vztahů namísto rolí

  • Dnes jsou hojně využívány dvě základní formy řízení přístupu založené na rolích (RBAC) a atributech (ABAC)
  • Existuje třetí, novější model, který získává na oblibě - řízení přístupu založené na vztazích (ReBAC)
  • Rozhodnutí, kterou formu pro aplikaci zvolit, by mělo být učiněno co nejdříve

RBAC

  • Model, ve kterém je přístup řízen na základě rolí přiřazených uživatelům aplikace
  • Oprávnění jsou přiřazena dané roli a entita (uživatel) je od role dědí
  • Vztah mezi uživateli a rolemi je obecně many-to-many a role mohou mít hierarchickou povahu

ABAC

  • Model, kde jsou požadavky subjektu na provedení operací s objekty povoleny nebo zamítnuty na základě atributů subjektu, objektu nebo podmínek prostředí a dalších zásad
  • Atributy = charakteristiky, které lze reprezentovat jako dvojice name-value a přiřadit je subjektu, objektu nebo prostředí
  • Možné atributy: pracovní role (obchodní zástupce, manažer), denní doba, název projektu, MAC adresa, datum vytvoření atd.

ReBAC

  • Model, který uděluje přístup na základě vztahů mezi prostředky
  • Např. příspěvek může být upraven nebo smazán pouze tím, kdo jej vytvořil
    • Toto je zejména vhodné u sociálních sítí, kde uživatelé chtějí omezit přístup ke svým datům (např. příspěvkům) na osoby, které si sami zvolí (přátelé, rodina)

Výhody ABAC a ReBAC oproti RBAC

Podpora fine-grained a komplexní boolovské logiky

  • V RBAC se o přístupu rozhoduje na základě rolí - jejich přítomnosti či nepřítomnosti
  • Taková logika špatně podporuje rozhodování na úrovni objektu, horizontální řízení přístupu nebo to, kde je vyžadováno více faktorů
  • ABAC model může obsahovat role, ale ta je jen jedním z atributů subjektu, která může být ověřována samostatně / nezávisle na ostatních atributech
  • ABAC může zahrnovat pracovní dobu, geolokaci, informaci, zda zaměstnanec dokončil školení atd., což jsou podmínky, které bude RBAC obtížně splňovat
  • ReBAC umožňuje fine-grained oprávnění - např. algebraické operace: “pokud má uživatel vztah X a zároveň nemá vztah Y s objektem, pak povol přístup”

Robustnost

  • V rozsáhlých projektech nebo při velkém počtu rolí je snadné vynechat nebo nesprávně provést kontrolu rolí (viz vynucování kontroly přístupu)
  • To může mít za následek jak malý, tak příliš velký přístup
  • Toto platí zejména v RBAC implementacích, kde není žádná hierarchie rolí a je potřeba role při kontrole zřetězit, aby měly požadovaný dopad
if (user.hasAnyRole("SUPERUSER", "ADMIN", "ACCT_MANAGER")

Rychlost

  • RBAC aplikace může definovat velké množství rolí
  • Pokud se role posílají prostřednictvím požadavků (např. HTTP hlavičky), které mají velikostní limity, může se stát, že nedojde k odeslání všech rolí uživatele
  • Řešením je posílat pouze ID role, kdy aplikace tyto role načte, to však zvyšuje latenci každého požadavku

Podpora multi-tenancy a mezi-organizačních požadavků

  • RBAC se nehodí tam, kde je potřeba, aby různé organizace nebo uživatelé měli přístup ke stejným chráněným zdrojům
    • Vyžaduje metody jako je konfigurace pravidel pro každého uživatele v prostředí nebo požadavek na poskytnutí identit napříč organizacemi (vynucování kontroly přístupu)
  • Pokud jsou však atributy správně definovány, umožňuje ABAC řídit přístup ve stejných nebo oddělených infrastrukturách a zachovává odpovídající úroveň zabezpečení

Snadná správa

  • RBAC nastavení je často jednodušší než než ABAC
  • Tato výhoda je však krátkodobá a mizí s rozsahem a složitostí systému
  • Na začátku může stačit malé množství rolí, jako je user a admin, ale je nepravděpodobné, že by to platilo dlouho
  • S rostoucím počtem rolí se testování, auditování, kritické procesy i vlastní kontrolní mechanismy stávají obtížnějšími (vynucování kontroly přístupu)
  • ABAC a ReBAC jsou mnohem expresivnější, dokáží odrazit reálné problémy a lze je snadněji aktualizovat

Zajistěte, aby ID nebyla přístupná pro vyhledávání ani v případě uhodnutí a nedalo se s nimi manipulovat

  • Aplikace často vystavují interní ID objektů (například primární klíč v databázi)
  • Tato ID se dále používají například ve vyhledávání nebo jako reference na objekt
  • ID může být vystaveno jako query parametr, hidden field nebo jinde
https://mybank.com/accountTransactions?account_id=901
  • Na základě této URL je možné předpokládat, že aplikace vrátí seznam transakcí, které jsou spojeny s daným účtem
  • Co se ale stane, když se změní hodnota parametru account_id například na 100?
  • Bude možné zobrazit si transakce spojené s jiným účtem, nebo ne?
  • Pokud ne, bude výsledkem něco ve stylu "účet s ID 100 nebyl nalezen" / "neexistuje", nebo bude chyba spojená s odepřením přístupu?
  • Častou chybou při vývoji je obcházení autorizace prostřednictvím klíče / identifikátoru poskytnutého uživatelem
  • Při zneužití může dojít k obejití autorizace, horizontálnímu a vertikálnímu zvýšení oprávnění (CWE 639)
  • Tento typ také představuje formu nebezpečného přímého odkazu na objekt (IDOR)
  • Výše uvedené ID bylo nejen vystaveno, ale také se dá předpokládat, že je sekvenční
    • I když lze použít techniky maskování nebo náhodného výběru, takový přístup stejně není dostatečný
  • Uživatel by neměl mít možnost přistupovat ke zdroji, ke kterému nemá oprávnění
  • Spíše než na formu zastírání a maskování je nutné klást důraz na kontrolu přístupu k objektům a identifikátorům

Best practices

  1. Vyhněte se vystavení identifikátorů uživateli
  2. Zajistěte, aby údaje (např. o účtu) bylo možné získat pouze na základě identity a atributů aktuálního uživatele (prostřednictvím informací v bezpečně implementovaném JWT nebo session)
  3. Implementujte nepřímé reference pomocí nástrojů jako je OWASP ESAPI (viz nezabezpečené přímé odkazy na objekt)
  4. Provádějte access control u každého požadavku na objekt nebo funkci, ke které se přistupuje
    • To, že má uživatel přístup k některému objektu určitého typu, neznamená, že by měl mít přístup ke každému objektu tohoto typu

Vynuťte kontrolu autorizace u statických prostředků

  • Význam zabezpečení statických prostředků je často přehlížen nebo zastíněn jinými bezpečnostními problémy
  • V poslední době se do popředí dostávají špatně zabezpečené zdroje v nabídkách cloudových úložišť (např. AWS S3 Bucket)

Best practices

  1. Zajistěte, aby byly statické prostředky začleněny do zásad řízení přístupu
  2. Zajistěte, aby byl typ ochrany prostředků závislý na kontextu (některé budou veřejné a jiné budou vyžadovat vysoce omezující sadu pravidel a atributů uživatele)
  3. Ujistěte se, že rozumíte samotným datům a jejich typu
  4. Zvažte vytvoření formálního schématu a klasifikace dat a začleňte ho do logiky řízení přístupu aplikace
  5. Zajistěte, aby všechny cloudové služby používané k ukládání statických prostředků byly zabezpečeny pomocí možností konfigurace a nástrojů poskytovaných dodavatelem
  6. Projděte si dokumentaci poskytovatele cloudu
  7. Chraňte statické prostředky pomocí stejné logiky řízení přístupu, které se používají k zabezpečení ostatních zdrojů a funkcí aplikace

Ověřte, že autorizační kontroly provádíte na správném místě

  • Vývojáři se nesmí spoléhat na kontrolu řízení přístupu na straně klienta
  • Tyto kontroly jsou sice přípustné, ale nikdy by neměly být rozhodujícím faktorem pro udělení nebo odepření přístupu
    • Logiku na straně klienta lze snadno obejít
  • Kontroly řízení přístupu musí být prováděny na straně serveru, gateway nebo serverless funkce

Bezpečně ukončete požadavek v případě selhání kontroly autorizace

  • Neúspěšné kontroly jsou v aplikacích častým jevem
  • Vývojáři s nimi musí počítat a bezpečně je řešit
  • Nesprávné ošetření selhání může vést k tomu, že aplikace zůstane v nepředvídatelném stavu

Doporučení

  1. Zajistěte zpracování všech výjimek a neúspěšných kontrol bez ohledu na to, jak nepravděpodobné se zdají být
    • To neznamená, že by se aplikace měla vždy snažit “opravit” neúspěšnou kontrolu - často stačí jen jednoduchá zpráva nebo HTTP stavový kód
  2. Centralizujte logiku pro zpracování neúspěšných kontrol řízení přístupu
  3. Ověřte zpracování výjimek a chyb autorizace
  4. Ujistěte se, že selhání neuvedou software do nestabilního stavu, který by mohl vést k obejití autorizace

Implementujte vhodné logování

  • Logování je jednou z nejdůležitějších detekčních kontrol zabezpečení aplikací
  • Selhání logování a monitorování je v OWASP žebříčku označováno za jedno z nejkritičtějších bezpečnostních rizik
  • Logy mohou odhalit škodlivou činnost, ale také je lze použít při řešení problémů souvisejících nejen se zabezpečením aplikace
  • Jde o důležitou součást zabezpečení a musí být zařazeno do všech fází životního cyklu

Doporučení

  1. Logujte pomocí konzistentních a přesně definovaných formátů, které lze snadno analyzovat
  2. Zvažte, co budete logovat, na základě požadavků aplikace
    • Nedostatečné logování může vést k neodhalení škodlivé činnosti a výrazně snížit účinnost analýzy po incidentu
    • Nadměrné logování může zatížit zdroje, vést k velkému množství falešně pozitivních výsledků, ale také může vést ke zbytečnému logování citlivých údajů
  3. Synchronizujte čas a časová pásma napříč systémy
    • Přesnost je klíčová pro sestavení posloupnosti útoku během reakce na incident i po něm
  4. Zvažte začlenění logování aplikací do centralizovaného log serveru nebo SIEM

Napište unit a integrační testy pro autorizační logiku

  • Unit a integrační testy jsou nezbytné pro ověření, zda aplikace funguje podle očekávaní a konzistentně reaguje na různé změny
  • Chyba v logice může být nenápadná, zejména v případě složitých požadavků
  • Unit a integrační testy nenahrazují specializovaný bezpečnostní test nebo penetrační test
  • Testy pomohou snížit počet bezpečnostních chyb, které se dostanou do produkce
  • Sofistikovanější vektory útoků však mají problém zachytit
  • Testy by měly zahrnovat koncepty popsané v tomto dokumentu, například testování deny-by-default, bezpečné ukončení aplikace po selhání, zásady ABAC
  • Testy sice mohou být nahrazeny manuálním testováním, ale slouží hlavně k rychlémů odhalení problémů a výrazně snižují prostředky pro manuální testování

Kam dál

Zranitelnosti

Checklisty