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í
- Zajistěte, aby byly ve fázi návrhu definovány trust boundaries
- Stanovte, jaké typy uživatelů budou k aplikaci přistopovat a jaké operace mohou provádět (read, write, delete, update …)
- Pro každou kombinaci uživatele a zdroje stanovte, jaké operace mohou být prováděny
- 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
- Vytvořte testy, které ověří, zda jsou tato oprávnění správně vynucována
- 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
- 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
- Explicitně zdůvodněte, proč bylo určité oprávnění uděleno konkrétnímu uživateli nebo skupině
- 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
- Vytvořte, udržujte a dodržujte procesy pro detekci a reakci na zranitelné komponenty
- Začleňte do procesu správy aplikace nástroje jako je Dependency Check
- Zvažte odběr novinek týkající se bezpečnostních zranitelností (např. NVD)
- 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
- Snažte se porozumět každé technologii, na které stavíte autorizační logiku
- 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í
- 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
- Nedovolte, aby byly požadavky na autorizaci řízeny možnostmi knihovny nebo frameworku
- Stanovte nejdříve požadavky na autorizaci a následně analyzujte komponenty třetích stran s ohledem na tyto požadavky
- Nespoléhejte se na výchozí konfiguraci
- Testujte konfiguraci
- 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
aadmin
, 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
- Vyhněte se vystavení identifikátorů uživateli
- 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)
- Implementujte nepřímé reference pomocí nástrojů jako je OWASP ESAPI (viz nezabezpečené přímé odkazy na objekt)
- 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
- Zajistěte, aby byly statické prostředky začleněny do zásad řízení přístupu
- 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)
- Ujistěte se, že rozumíte samotným datům a jejich typu
- Zvažte vytvoření formálního schématu a klasifikace dat a začleňte ho do logiky řízení přístupu aplikace
- 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
- Projděte si dokumentaci poskytovatele cloudu
- 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í
- 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
- Centralizujte logiku pro zpracování neúspěšných kontrol řízení přístupu
- Ověřte zpracování výjimek a chyb autorizace
- 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í
- Logujte pomocí konzistentních a přesně definovaných formátů, které lze snadno analyzovat
- Např. Apache Logging Service poskytuje podporu pro mnoho jazyků a platforem
- 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ů
- 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
- 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í