Articles

CORS, XSS a CSRF s příklady za 10 minut

Tento článek by měl být vaším vstupním bodem pro existující webové bezpečnostní standardy, nejčastější webové útoky a metody, jak jim předcházet. Na konci se také dozvíte, jak a proč byl Samy hrdinou všech (asi kromě Ruperta Murdocha)

Cross-origin resource sharing neboli CORS je bezpečnostní funkce prohlížečů IE10+, Chrome 4+, Firefox 3.5+ nebo téměř všech verzí prohlížečů vydaných po roce 2012 s výjimkou Opery Mini.

Když je CORS nakonfigurován na serveru, který je dostupný v doméně website.com, pak prostředky z této domény, které jsou požadovány prostřednictvím AJAX, musí být iniciovány z prostředků, které jsou obsluhovány ze stejné domény.
CORS

Jinými slovy, pokud povolíme CORS na domain-b.com a nakonfigurujeme jej tak, aby umožňoval pouze GET požadavky z domény domain-b.com, pak pokud chcete použít obrázek dostupný pod https://domain-b.com/images/example.png v plátně na svých webových stránkách, které jsou hostovány na domain-a.com, pak tento obrázek nebude načten pro většinu návštěvníků.
Vaše zdroje chráněné pomocí CORS budou stále dostupné, když je bude požadovat jakýkoli nástroj nebo prohlížeč, který nerespektuje CORS policy.

Konfigurace CORS

CORS jsou ve výchozím nastavení vypnuty, což znamená, že neexistuje žádná odpovídající obslužná rutina serveru, která by konfigurovala CORS, což znamená, že ve vašem XHR nemůžete přistupovat ke zdrojům z jiného původu. Pokud v podstatě nic neuděláte nebo výslovně povolíte CORS pouze pro určité domény, pak bude každý požadavek AJAX, který se pokusí přistupovat k vašim zdrojům, odmítnut, protože webové prohlížeče respektují CORS policy.
To je důvod, proč se setkáte s problémem CORS, když začnete vyvíjet SPA pomocí VueJS a NodeJS. Vaše aplikace VueJS je hostována na http://localhost:8080 a při pokusu o přístup k serverové aplikaci NodeJS na http://localhost:8000 se zobrazí „No Access-Control-Allow-Origin header is present„, protože se jedná o dva různé ORIGINS(kombinace PROTOCOL, HOST a PORT).

Chytré řešení problému CORS ve vývojovém režimu VueJS spočívá v nastavení proxy serveru devServer v souboru vue.config.js takto:

module.exports = { ... devServer: { proxy: 'http://localhost:8000', }, ...}
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Pro nastavení CORS ve výrobě byste měli přidat příslušný posluchač pro požadavek OPTIONS. Tento posluchač by měl posílat odpověď 200 s no body, ale s Headers, který bude definovat vámi požadovanou politiku CORS:

Access-Control-Allow-Origin: https://domain-b.comAccess-Control-Allow-Methods: GET
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Pro více informací o konfiguraci CORS se podívejte na https://enable-cors.org/index.html a pro hlubší ponoření do CORS policyzkontrolujte https://livebook.manning.com/book/cors-in-action/part-1/

XSS

XSS znamená Cross Site Scripting a jedná se o injekční typ útoku. Je uveden na 7. místě z 10 nejčastějších zranitelností identifikovaných organizací OWASP v roce 2017. Cross site scripting je metoda, při které útočník injektuje škodlivý skript do důvěryhodné webové stránky (sekce aktualizována, díky Sandor) Existují 3 typy těchto útoků.

  1. Stored XSS – Zranitelnost pocházející z nechráněných a nesanitizovaných uživatelských vstupů, které jsou přímo uloženy v databázi a zobrazeny ostatním uživatelům
  2. Reflected XSS – Zranitelnost pocházející z nechráněných a nesanitizovaných hodnot z adres URL, které jsou přímo použity na webových stránkách
  3. DOM based XSS – Podobné jako reflected XSS, nechráněné a nesanitizované hodnoty z adres URL, které jsou přímo použity ve webových stránkách, s tím rozdílem, že DOM based XSS ani nepřechází na stranu serveru

Útok

1. Uložený XSS

Uvádíme příklad útoku. Útočník přijde na vaše webové stránky a najde nechráněné vstupní pole, například pole pro komentář nebo pole pro uživatelské jméno, a místo očekávané hodnoty zadá škodlivý skript. Poté, kdykoli se má tato hodnota zobrazit ostatním uživatelům, spustí škodlivý kód. Škodlivý skript se může pokusit získat přístup k vašemu účtu na jiných webových stránkách, může být zapojen do útoku DDoS apod. Vizuální znázornění (zdroj geeksforgeeks.org):

XSS example

2. Odražený XSS

Odražený XSS je útok, ke kterému dojde, když útočník objeví stránku s takovou zranitelností, například:

očekávaná adresa URL: https://mywebpage.com/search?q=javascript
nebezpečná adresa URL: https://mywebpage.com/search?q=<script>alert('fortunately, this will not work!')</script>

<body>...<div> showing results for keyword <script> document.write(window.location.href.substr(window.location.href.indexOf('q=') + 2))</script></div>......JavaScript results......</body>
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Po objevení útočník naláká uživatele, aby na takovou škodlivou adresu URL kliknul a voila. Citlivé údaje uživatele jsou zneužity.

Životní cyklus útoku znázorněný v příkladu poskytnutém geekforgeeks.com:

Reflected XSS example

3. DOM based XSS

Tento druh útoku je stejný jako reflektovaný, ale s tím rozdílem, že škodlivá část URL se na server vůbec neodešle. Pro výše uvedený příklad:

očekávaná adresa URL: https://mywebpage.com/search?q=javascript
škodlivá adresa URL (odražený XSS): https://mywebpage.com/search?q=<script>alert('fortunately, this will not work!')</script>
škodlivé URL(DOM based XSS): https://mywebpage.com/search#q=<script>alert('fortunately, this will not work!')</script>

Rozdíl je v použití znaku # namísto ?. Prohlížeče neodesílají část adresy URL za # na server, takže ji předávají přímo vašemu klientskému kódu.

Ochrana

Každá hodnota, kterou může uživatel zadat a která je použita ve vaší aplikaci(buď na straně serveru, nebo na straně klienta), by měla být považována za nedůvěryhodná data, a proto by měla být před použitím zpracována! Bezpečnostní kontrolu byste měli provést jak v aplikaci na serveru, tak v klientské aplikaci!
Jak je uvedeno v dokumentaci, VueJS sám o sobě escapuje řetězec před získáním hodnoty z proměnné. Novější verze Angularu také implicitně escapují řetězce, takže pokud používáte Vanilla JS, JQuery nebo podobné, měli byste escapování řetězců implementovat ručně.

Níže jsou uvedeny tři nejběžnější přístupy ke zpracování nedůvěryhodných dat a ideální metoda závisí na aktuálním typu pole, které potřebujete zpracovat.

1. Validace řetězce

Validace je metoda, při které uživatel definuje sadu pravidel a před dalším postupem požaduje, aby nedůvěryhodná data tato pravidla splňovala. Tato metoda je vhodná pro číselné hodnoty, uživatelské jméno, e-mail, heslo a podobná pole s konkrétní sadou syntaktických pravidel.

Než začnete uvažovat o psaní validátorů vlastními silami, zkontrolujte, zda pro váš framework existují knihovny.

2. Validátory. Řetězcový escape

Metoda escape je užitečná v případech, kdy máte uživateli umožnit používat interpunkční znaménka. Tato metoda prochází řetězec a hledá speciální znaky, například < >, a nahrazuje je příslušným názvem entity HTML. Zde je základní funkce, kterou můžete použít:

function escapeText(text) { return text.replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;')}
Vstup do celoobrazovkového režimu Ukončení celoobrazovkového režimu

Před napsáním vlastní knihovny se opět podívejte na existující knihovny.

3. Sanitizace řetězce

Sanitizace řetězce se používá v případě, že uživatel smí ve svých komentářích, článcích apod. zadávat některé značky HTML. Metoda sanitize prochází text a hledá zadané značky HTML a odstraňuje je. Jednou z nejoblíbenějších knihoven, která tento přístup používá, je Google Closure.
Tato metoda je náročná na zdroje a je považována za škodlivou, proto ji před výběrem více prozkoumejte.

Webové prohlížeče(nejsou dostupné zdroje od které verze, IE tento problém opravil v roce 2014.) automaticky escapeují URL před odesláním na stranu serveru a zpřístupňují je také v objektu window.location, takže 2. a 3. typ útoku je zde jen proto, abyste o nich věděli a aby bylo jasné, že s paramenty URL je třeba také zacházet jako s nedůvěryhodnými daty.

Podrobnější informace o XSS a o tom, jak správně chránit aplikaci, pokud rotujete velké množství nedůvěryhodných dat, najdete v cheatsheetu OWASP o prevenci XSS.

CSRF

Cross site request forgery neboli CSRF je typ útoku, ke kterému dochází, když škodlivý web, e-mail, blog, rychlá zpráva nebo program způsobí, že webový prohlížeč uživatele provede nežádoucí akci na jiném důvěryhodném webu, kde je uživatel ověřen. Tato zranitelnost je možná, když prohlížeč s každým požadavkem automaticky odesílá autorizační prostředek, jako je soubor cookie relace, IP adresa nebo podobně.

ÚTOK

Předpokládejme, že uživatel je přihlášen do vaší nechráněné webové aplikace burzy a že k ověření používáte buď soubor cookie relace, nebo soubor cookie JWT. Útočník také používá vaši službu a je schopen zkontrolovat, jak funguje vaše API. Útočník přiměje uživatele, aby spustil skript (kliknutím na SPAM odkaz v e-mailu nebo podobně), který odešle požadavek na vaše API https://www.stockexchange.com/users/withdraw?how_much=all&address=MY_ADDRESS(hrozný návrh API, neptejte se). Vzhledem k tomu, že požadavek je prováděn z prohlížeče, který s každým požadavkem odesílá ověřovací payload, váš webový server burzy úspěšně ověří uživatele a provede transakci a podvedený uživatel přijde o celý svůj zůstatek, aniž by o tom věděl, protože vše se odehrálo na pozadí. Vizuální znázornění(zdroj miro.medium.com)
CSRF attack

OCHRANA

Naštěstí existují snadno implementovatelné vzory, které tomuto webovému útoku zabrání. Jedním z nejčastějších vzorů je použití CSRF token. Postup je v podstatě následující:

  1. Vygenerovat pro každý požadavek uživatele jedinečný token, tzv. token CSRF token.
  2. Uložit jej bezpečně na serveru a odeslat zpět uživateli jako payload odpovědi.
  3. Uložit CSRF token na straně klienta.
  4. Když se uživatel pokusí provést jakýkoli požadavek měnící stav*, pošlete tento CSRF token s požadavkem jako payload.
  5. Před provedením tohoto požadavku na straně serveru zkontrolujte, zda je CSRF token přítomen a je platný.

Toto je nejjednodušší způsob, jak zabránit CSRF útoku pro všechny uživatele.

Pokud se jedná pouze o návštěvníky, kteří používají moderní prohlížeče, pak se můžete spolehnout na atribut SameSite souboru cookie relace (díky Gergely)

Protože odpovědi serveru jsou zpracovatelné v odpovědi XHR, pak neexistuje žádná ochrana proti útoku CSRF, pokud je vaše webová aplikace zranitelná XSS!

Chcete-li se ponořit hlouběji, podívejte se na cheatsheet OWASP o CSRF.

BONUS

Krátký dokument o Samyovi, autorovi červa, který v roce 2005 zničil MySpace zneužitím zranitelnosti XSS a prošel obranou MySpace proti CSRF.
https://youtu.be/DtnuaHl378M

Další informace o červu Samy
https://samy.pl/myspace/tech.html

.