Bezpečnost ve webových aplikacích

Z FI WIKI
Přejít na: navigace, hledání


Autentizace a autorizace

Přístup k webovým aplikacím často musí být omezen na určitou skupinu uživatelů. Tato stránka pojednává o způsobech, jak toho dosáhnout.

Při omezování přístupu používáme dva důležité pojmy:

  • autentizace (anglicky authentication) - prokázání identity nějakého subjektu, obvykle uživatele
  • autorizace (anglicky authorization) - rozhodnutí o povolení přístupu autentizovanému subjektu

Příklad ze života - při vstupu do budovy musím ukázat občanku, tím dokazuji, že jsem třeba Franta Novák, tím jsem provedl autentizaci. Při vstupu do přísně tajného armádního objektu, kde skladují havarované ufony, mne ale nepustí dál - autorizace neproběhne, přestože moje identita je prokázaná. Častou chybou je zaměňování autentizace za autorizaci, tj. jako kdybych pustil každého, kdo má občanku, což jsou všichni.

Autentizace u webových aplikací

Způsobů, jak provádět autentizaci u webových aplikací, je více:

  • HTTP BASIC - jméno a heslo
  • SSL klientským certifikátem
  • vyplněním jména a hesla do formuláře
  • Shibboleth (federace identit)
  • OpenID a OAuth
  • a další (HTTP DIGEST, Kerberos, atd.)

Rozeberme ty nejpoužívanější

HTTP BASIC autentizace

Historicky nejstarší, a asi nejpoužívanější, je autentizace jménem a heslem na úrovni HTTP protokolu. Probíhá tak, že při pokusu prohlížeče o přístup k chráněné stránce pošle HTTP server odpověď:

HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic realm="Tajna oblast"
...

na což prohlížeč zareaguje zobrazením okna zhruba tohoto vzhledu:

Prompt.PNG

a po zadání jména a hesla pošle v požadavku hlavičku:

GET /chranene/ HTTP/1.1
Authorization: Basic bWFrdWI6bWFrdWJpaw==
...

ve které jsou jméno a heslo pouze zapsány pomoci Base64, tj. nezašifrované. Proto je nutné používat HTTP BASIC autentizaci vždy přes šifrovaný kanál, tj. SSL.

Basic autentizace se dá nastavit přímo v popisovači webové aplikace (web.xml), ale můžeme si ji zajistit i sami v servletu nebo v servletovém filtru, případně můžeme před servletový kontejner předřadit webserver Apache.

Autentizace klientským SSL certifikátem

Komunikace mezi prohlížečem a HTTP serverem může být šifrovaná pomocí SSL (Secure Socket Layer). Strana serveru se musí vždy autentizovat předložením digitálního X509 certifikátu, klientská strana tak může učinit, pokud je k tomu serverem vyzvána.

Při ustavení spojení server pošle svůj X509 certifikát, klient vygeneruje symetrický šifrovací klíč, pošle ho serveru (zašifrovaný asymetrickým veřejným klíčem serveru získaným z certifikátu serveru) a všechna posílaná data jsou tímto symetrickým klíčem šifrována.

SSL server může vyžadovat, aby klient při ustavení spojení předložil svůj digitální certifikát, podepsaný některou z Certifikačních Autorit, které server uznává jako věrohodné. Prohlížeč pak zobrazí uživateli výzvu k předložení certifikátu:

Cert.PNG

Ověřování klientských certifikátů lze nejlépe nastavit na serveru Apache, který předřadíme servletovému kontejneru pomocí modulu mod_jk. V servletech pak získáme informace o předloženém klientském certifikátu pomocí standardizovaných atributů requestu pojmenovaných:

javax.servlet.request.cipher_suite
javax.servlet.request.key_size
javax.servlet.request.X509Certificate

nebo, pokud si pošleme z Apache přes mod_jk informace o jeho proměnných direktivou JkEnvVar, pak v atributech se jmény

SSL_CLIENT_S_DN
SSL_CLIENT_M_SERIAL
SSL_CLIENT_CERT

Autentizace vyplněním formuláře

Asi nejčastěji používanou metodou je vytvoření HTML formuláře, do kterého musí uživatel vyplnit jméno a heslo, a pokud jsou správné, do HttpSession se uloží informace, že uživatel je autentizován. Opět je nutné zajistit, aby spojení, přes které jdou při prvním požadavku jméno a heslo, a při všech dalších požadavcích pak cookie identifikující autentizovanou session, bylo šifrované.

Pro autentizaci formulářem lze využít standardizovanou metodu deklarovanou ve web.xml, nazývanou ve specifikaci Servlet API HTTP FORM, nicméně je dobré vědět, že tato metoda má dost omezení, a je lepší si implementovat vlastní formulář a ochranu přístupu pomocí servletového filteru.

Jak (ne)ukládat hesla

Uživatelé používají stejná hesla pro různé služby, proto je nebezpečné, pokud je někdo ukradne.

Špatné způsoby ukládání hesel:

  • plaintext (jsou přímo přístupná)
  • hashovaná bez soli (lze je zpětně zjistit pomocí rainbow tables - předpočítaných hashů všech hesel do určité délky)
  • hashovaná pomocí MD5, SHA-1 ... SHA-512 se solí (lze vytvořit rainbow table pro konkrétního uživatele, třeba celebritu)

Správný zpúsob ukládání hesel:

  • použít BCrypt nebo PBKDF2 s volitelným počtem iterací

V JRE je k dispozici PBKDF2WithHmacSHA512, v knihovně Spring Security je implementace BCrypt.

Shibboleth - federace identit

Z na stránce zmiňovaných technologií je nejmladší. Uživatelé mívají spousty účtů na mnoha serverech a protože je těžké pamatovat si pro každý jiné heslo, používají všude stejné, což způsobuje, že kompromitace jednoho systému kompromituje i ostatní, aniž o tom jejich správci vědí. Používání certifikátů zase naráží na to, že uživatelé musí vynaložit určitou námahu na získání certifikátu. Jako řešení těchto problémů se objevila myšlenka federace identit. Většina uživatelů patří do nějaké organizace (škola, zaměstnavatel, profesní sdružení atd.) kde již má přiděleno jméno a heslo (popř. jiný způsob autentizace). Organizace tak pomocí právních smluv mohou vytvořit federaci, ve které si navzájem věří informace o uživatelích. Tedy uživatel se přihlašuje vždy u své domovské organizace, a ta o něm poskytuje vybrané informace (ve formě dokumentu v jazyce SAML) webovým serverům ostatních organizací. Schéma viz obrázek:

Federace.png

V ČR existuje testovací federace mezi univerzitami (zajišťovaná CESNETem) od léta 2007, od začátku roku 2009 je v ostrém provozu pod názvem eduID.cz. Organizace s uživateli provozují tzv. Identity Provider (IdP), aplikaci pro tomcat, která má jako jediná přístup k heslům a zajišťuje jejich ověření. Oproti tomu organizace poskytující služby používají tzv. Service Providery (SP), autentizační modul pro webový server, který komunikuje s IdP a přijímá od něj informace o identitě uživatele.

Masarykova univerzita je do projektu eduID.cz už od testovacího provozu zapojena. Identity provider provozuje Ústav výpočetní techniky MU, Service providerů běží na MU spousta -- jedna instance i na tomto serveru Kore. Zkusit si Shibboleth můžete sami kliknutím na "login via is mu" vpravo nahoře.


OpenID, OAuth a OpenID Connect (OIDC)

OpenID je otevřený standard specifikující protokol pro autentizaci.

OAuth je otevřený standard specifikující protokol pro autorizaci přístupu k vyjmenovaným operacím nějakého API, ale lze jej využít i pro autentizaci v případě, že dané API má funkce pro získání informací o uživateli.

OpenID Connect (OIDC) je autentizační vrstva nad autorizačním protokolem OAuth.

OpenID

OpenID umožňuje přihlášení se na nějakém website pomocí účtu na jiném serveru, zvaném identity provider (poskytovatel totožnosti). O uživateli lze získat buď jen identifikátor, nebo i atributy typu firstname, lastname, email.

OpenID podporují jako identity providers třeba Google, Seznam.cz, MojeID.cz.

Implementace pro Javu je v knihovně OpenID4Java.

OAuth

OAuth umožňuje povolit pro konkrétního poskytovatele služby jen určité operace (ze všech operací) na API určitého poskytovatele.

OAuth podporují Google, Facebook, Twitter, LinkedIn, ORCID.

API a množina jeho operací jsou specifické pro každou službu. Např. Facebook umožňuje povolit čtení základních osobních údajů, nebo i dalších osobních údajů, nebo povolit zapisování na zeď. Google umožňuje povolit přístup jen ke kalendáři, jen k dokumentům, atd.

Knihovna Spring Social umožňuje unifikovaný přístup k API různých sociálních sítí využívajících OAuth, je svázaná se Spring MVC. Naprogramovat jednoduchou autorizaci přes OAuth lze snadno i jen s pomocí Servlet API a třídy HttpURLConnection, viz např. [1].

OAuth podporuje nejen služby s webovým rozhraním, umožňuje i mobilní aplikace (Android, iOS).

OpenID Connect

OpenID Connect vznikl spojením OpenID a OAuth, v podstatě bylo definováno jednotné UserInfo API, přes které lze získávat informace o přihlášeném uživateli.

Známé útoky

Cross-site scripting (XSS)

Cross-site scripting je útok, který se snaží obejít same origin policy v prohlížečích, a získat tak přístup k datům.

Obrana: v textech zadávaných uživateli je třeba speciální znaky nahrazovat entitami, např. < nahrazovat za &lt;, v java aplikacích nejlépe pomocí značky <c:out value="${hodnota}"/>. Dále je nutno kontrolovat URL od uživatele, která jdou do obrázků, odkazů a podobně, protože mohou začínat např. na javascript:. Kvůli různým variacím a budoucím změnám je vhodné použít pro tuto kontrolu whitelist.

Cross-site request forgery (XSRF)

Cross-site request forgery je pasivní útok, kdy útočník nachystá na nějakou stránku kód, který způsobí vyvolání URL na nějakém jiném serveru, kde uživatel může být stále přihlášen.

Obrana: důležité akce (třeba převod peněz) je třeba potvrzovat, do přihlašovacích formulářů je třeba přidávat náhodně generované hodnoty.

Clickjacking

Cizí stránka, na kterou je veden útok, je zobrazena na útočníkově stránce v iframe tak, že je vidět jen část bez bližšího kontextu. (Je možné využít i opacity v CSS.) Uživatel je naveden ke kliknutí na tuto část stránky, čímž provede nějakou akci, například hlasování v anketě.

Obrana: Lze se bránit hlavičkou X-Frame-Options, která je v některých prohlížečích podporována, a Javascriptem. Princip spočívá v zabránění zobrazení stránky v rámci.

Session hijacking

Session hijacking je útok, při kterém útočník odposlechne cookie použité pro označení úspěšně autentizovaného uživatele, a začne se za něj vydávat.

Obrana: Session cookies musí mít označení secure, tedy mohou být poslána jen přes šifrovaná SSL spojení. V případě předávání session ID přes URL je obrana komplikovanější, vyžaduje zabránit úniku URL přes referer (odkazy, obrázky, ...) a Session fixation.

Phishing

Phishing je aktivní útok, při kterém útočník vydává svoje vlastní webové stránky za stránky instituce, aby získal přihlašovací údaje uživatele.

Obrana: vzdělávání uživatelů v kontrole autentizace serveru, použití Extended Validation SSL Certificates

SQL Injection

SQL Injection útok není omezen jen na webové aplikace, ale vzhledem k tomu, že webové aplikace jsou často přístupné masám uživatelů, musí být proti němu dobře chráněny.

Obrana: Důsledné používání PreparedStatement a jeho setXXX() metod pro nastavování hodnot. Tam kde se nejedná o hodnotu (třeba název sloupce v ORDER BY), zkontrolovat vstup regulárním výrazem na očekávané hodnoty.