Podívejte se raději na online verzi přednášky, slajdy mohly být aktualizovány nebo doplněny.

Detail přednášky

Jak se pomocí více úrovní obrany bránit proti notoricky známému útoku Cross-Site Scripting (XSS). Jaké vrstvy zabezpečení existují a kdy se používají. O vlastnostech prohlížečů a Content Security Policy (CSP).

Datum a akce

5. dubna 2017, GMC Kick-Off, Karpacz, Poland (délka přednášky 45 minut, 30 slajdů)

Slajdy

Hradní příkop + vysoké zdi + stráže

#1 Pro dobytí hradu kdysi nestačilo překonat jen ten bazén okolo, ale taky vysoké zdi a na nich budované laserové střílny. Webové aplikace byste měli navrhovat podobně, s několika úrovněmi ochrany. Když selže první úroveň (vývojář), pořád tam jsou další, které mohou návštěvníky ochránit.

Cross-Site Scripting (XSS)

#2 Princip více úrovní ochrany se dá hezky ukázat na útoku Cross-Site Scripting. Ten útočníkům slouží ke spuštění zákeřného JavaScriptu staženého z jiného serveru v kontextu zranitelné aplikace. Tím mohou zaútočit na uživatele a jejich prohlížeče.

@osvdb replying to @jeremiahg: what is the first published XSS vuln that you are aware of? (e.g. in a specific product) 1999-07-09 according to our list

#3 Cross-Site Scripting (XSS) není žádná novinka. Podle Open Sourced Vulnerability Database byla první XSS zranitelnost publikována v roce 1999.

$1.2 million

#4 Jen v letech 2014–2016 vyplatil Google 1,2 milionu USD na odměnách za nalezení XSS chyb ve svých aplikacích v rámci Vulnerability Reward Program. To docela jde.

Krabice od vína plná peněz

#5 Jen pro zajímavost, na obrázku vidíte muže, vlevo, a milion dolarů ve stodolarových bankovkách, alespoň podle PageTutoru. To by se skoro vešlo do krabice od vína, co? Tak zhruba tolika penězi Google za 2 roky odměnil úspěšné nálezce XSS chyb.

<img src=x onerror=alert(1)>

#6 Cross-Site Scripting spočívá ve vložení JavaScriptu útočníkem do stránky. Lze také vložit například značku img s onerror handlerem, nemusí to být jen tag <script>.

Tatra vás dostane dál – alert(1)

#7 Když se XSS ukazuje nebo reportuje, tak nejčastěji jako alert(1). Důkaz možnosti spustit nějaký JavaScript to sice je, ale o nebezpečnosti Cross-Site Scriptingu to nic nevypovídá. Tohle dialogové okno moc lidí o nutnosti řešit XSS nepřesvědčí.

< → &lt;, > → &gt;, " → &quot;, ' → &apos;, & → &amp;

#8 První úroveň ochrany proti XSS je při výpisu správně ošetřit tyto nebezpečné znaky, hlavně ty první čtyři řádky. Ale na to vývojáři často zapomínají a pak se dějí zlé věci.

BeEF (The Browser Exploitation Framework Project)

#9 Jenže XSS je mnohem víc než jen alert(1). XSS framework BeEF má zhruba 300 vestavěných modulů, které v browseru umí zobrazit např. falešné notifikace, falešné přihlašovací formuláře, umí udělat screenshot stránky nebo přehrát MP3. Ukázku najdete v jedné z předchozích přednášek.

2ⁿᵈ line of defense

#10 Vývojáři často zapomínají ošetřit speciální znaky a asi budou zapomínat i nadále. Protože mají hořící termíny, špatný kafe nebo moc piv. Takže potřebujeme tohle.

"Don't worry, I gotcha…"

#11 Potřebujeme další úrovně zabezpečení. Ty nemusí fungovat vždy a pro všechny uživatele, ale když první úroveň selže, tak vám může zachránit život. Nebo cookies.

Krádež cookies za bílého dne

#12 Když už mluvíme o krádeži cookies… tak přesně takhle to funguje. Dneska to dokáže už i králík, Vám k tomu stačí 1–2 řádky JavaScriptu.

XSS Auditor

#14 Další druhá úroveň ochrany je zabudované přímo ve vašem prohlížeči, zvlášť pokud používáte Chrome, Internet Explorer nebo Edge (XSS Auditor byl z Chromia a tím pádem i z Chrome i Edge odstraněn ve verzi 78). Ve Firefoxu není, ale to nevadí, není to primární úroveň ochrany. XSS auditor (XSS filtr) chrání proti Reflected XSS.

>:| → 1 → :-) → 2 → web → 3 → :-)

#15 Takto Reflected XSS funguje. Útočník pošle uživateli odkaz s nějakým zákeřným JavaScriptem v URL (1), uživatel na odkaz klikne a prohlížeč pošle požadavek na webovou aplikaci (2). JavaScript z požadavku se vloží do stránky a vše se pošle zpět uživateli (3), v jehož prohlížeči se ten JavaScript spustí. Browser vidí, co se mu vrátilo z aplikace a pokud to vypadá jako JavaScript, který v požadavku odeslal, tak spustí XSS filtr, pokud ho prohlížeč má a je povolen.

X-XSS-Protection: 1; mode=block

#16 XSS filtr můžete ovládat ze serveru poslanou hlavičkou X-XSS-Protection. Režim mode=block byste měli používat, prohlížeč po aktivaci filtru stránku vůbec neukáže.

This page isn't working, ERR_BLOCKED_BY_XSS_AUDITOR

#17 mode=block byl defaultně zapnutý v Chrome od verze 57 do verze 73. Starší (a novější) verze se pokouší stránku vyčistit. Ve verzi 78 byl XSS Auditor odstraněn úplně. Na mém testovacím webu jste si mohli XSS auditor vyzkoušet, sledujte co se bude se stránkou dít a jaké varování se vypíše v konzoli v developer tools.

Response Headers: content-security-policy

#18 Content Security Policy (CSP) je nejnovější přírůstek v řadě druhých úrovní ochrany proti XSS. Tato hlavička posílaná ze serveru určuje povolené URL, ze kterých prohlížeč do stránky může stahovat obrázky, JavaScript, CSS a další. Takže i když útočník dokáže do HTML vložit značku <script>, tak browser z uvedené adresy nestáhne kód, pokud ta adresa není povolená.

Content-Security-Policy: default-src 'self'

#19 Toto je asi nejjednodušší varianta hlavičky Content-Security-Policy. Povolí browseru do stránky poslané s touto hlavičkou načítat JavaScript, obrázky, CSS a další pouze ze 'self', tedy z aktuálního protokolu, domény a portu (origin).

Content-Security-Policy: default-src 'self'; img-src 'self' https://www.google-analytics.com

#20 Můžeme navíc povolit načítání obrázků z https://www.google-analytics.com, aby fungoval skript Google Analytics. Ten by však musel být načten z aktuálního originu, protože default-src 'self', ale tak to bohužel nefunguje.

Content-Security-Policy: default-src 'self'; img-src 'self' https://www.google-analytics.com; script-src 'self' https://www.google-analytics.com 'unsafe-inline'

#21 V script-src musíme navíc povolit i origin pro skript Google Analytics. Pomocí direktivy 'unsafe-inline' povolíme rovnou i tzv. inline JavaScript. Jo, JavaScript zapsaný rovnou do HTML pomocí značek <script> nebo atributů jako např. onclick může být unsafe. Jenže některé knihovny a nástroje inline JS používají.

CSP ✔ (csp-evaluator.withgoogle.com)

#22 Nasazení CSP není jednoduché a to nejen kvůli nástrojům jako například Google Tag Manager. Politika často musí být vcelku otevřená, je nutné povolit spoustu originůinline JavaScript. Tím se také zvyšují šance pro útočníka, že najde skulinku, kterou bude moci vložit svůj kód. Nastavení CSP si můžete otestovat v nástroji CSP Evaluator, prozradí vám, jak by šlo konkrétní politiku obejít.

Content Security Policy Level 3

#23 Situaci vylepšuje CSP3 a 'strict-dynamic'. Díky této direktivě bude prohlížeč ignorovat seznam povolených domén a bude stahovat jen skripty označené pomocí nonce, ty navíc mohou vkládat další skripty bez potřeby rozšiřovat politiku.

Content-Security-Policy: script-src 'strict-dynamic'

#24 Direktivu 'strict-dynamic' podporuje Chrome i Firefox, oba shodně od verze 52. Vyzkoušet si ji můžete na mé testovací stránce. Pojďme si takovou bezpečnou CSP hlavičku sestavit, začneme tím, že povolíme skripty označené pomocí nonce.

<script src=… nonce="rAnd0m123"></script>

#25 Atribut nonce slouží pro označení skriptů. Jeho hodnota by se měla při každém načtení stránky změnit a měla by být minimálně 16 náhodných bajtů zakódovaných do Base64. Stejný nonce může být použit k označení více skriptů na jedné stránce.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-rAnd0m123'

#26 Takto do hlavičky Content-Security-Policy přidáme hodnotu atributu nonce.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:;

#27 Starší prohlížeče bez podpory 'strict-dynamic' načtou skripty označené pomocí atributu nonce a ty pak mohou dále načítat skripty z http: a https:, tedy prakticky jakékoliv další. Nakonec je potřeba povolit i inline JavaScript pro prohlížeče, které nepodporují ani nonce z CSP2. Content Security Policy není primární metodou obrany proti XSS, tou je stále převod nebezpečných znků na entity, takže nevadí, že pořádně bude fungovat jen pro uživatele moderních prohlížečů s podporou CSP3.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:; object-src 'none'; base-uri 'none';

#28 Nakonec zakážeme načítaní pluginů, jako např. Flashe, a použití značky base pro určení base URL stránky. Pomocí obojího lze Cross-Site Scripting spáchat také.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:; object-src 'none'; base-uri 'none'; report-uri https://report-uri.io/…

#29 Pokud by se prohlížeč pokusil načíst nějaký zdroj, který mu Content Security Policy zakazuje, tak vám o tom může poslat report na adresu v report-uri a vy tak můžete případnou chybu opravit. Jenže prohlížeče posílají spoustu reportů aniž byste v aplikaci nějakou chybu měli, protože lidé používají divná rozšíření, viry nebo různé free Wi-Fi, které do stránek vkládají reklamu. Než číst každý jednotlivý report, tak je lepší koukat na grafy a trendy. Obojí vám hezky zobrazí například report-uri.com.

JavaScript: Stop executing scripts on this page

#30 Chybovat je lidské, evidentně, tak na to myslete, až budete budovat obranu svých aplikací. Protože i skoro 20 let staré útoky jsou pořád in a nebezpečné.

Michal Špaček

Michal Špaček

Vyvíjím webové aplikace, zajímá mě jejich bezpečnost. Nebojím se o tom mluvit veřejně, hledám hranice tak, že je posouvám. Chci naučit webové vývojáře stavět bezpečnější a výkonnější weby a aplikace.

Veřejná školení

Zvu vás na následující školení, která pořádám a vedu: