Validace a sanitace vstupů a prevence injekčních útoků

Zjistěte, jak validace a sanitace vstupů chrání formuláře před injekčními útoky a čím se data z formulářů stávají bezpečnými.

Koncept

Když útočníci míří na formuláře, nevyplňují je běžným způsobem. Posílají kód, který má prolomit vaše systémy nebo ukrást data. Mohou odeslat JavaScript, který se spustí v prohlížečích návštěvníků, příkazy SQL, které poškodí vaši databázi, nebo škodlivý obsah, který způsobí újmu. Validace a sanitace vstupů jsou obrana, která tyto útoky zastaví.

Co se dozvíte: co je validace a sanitace vstupů, v čem se liší, jak fungují injekční útoky, jaká ochrana funguje pro různé typy dat a jak je zavést ve svých formulářích.

Co je validace vstupů?

Validace vstupů je kontrola, že data odeslaná do formuláře mají očekávaný formát a splňují vaše požadavky. Je to první linie obrany proti škodlivému vstupu.

Validace odpovídá na otázky, například zda jde o e-mailovou adresu, nebo o náhodný text, zda jde o číslo, nebo o slovo, zda je pole prázdné, když by nemělo být, a zda návštěvník napsal něco, co dává v tomto poli smysl, nebo něco podezřelého.

Příklady toho, co validace kontroluje:

  • Pole pro e-mail má obsahovat zavináč a doménu
  • Pole pro telefonní číslo má obsahovat jen číslice a spojovníky
  • Číselné pole nemá obsahovat písmena
  • Povinné pole nemá být prázdné
  • Pole pro heslo má splnit minimální délku

Validace probíhá na dvou místech. Na zařízení návštěvníka se jí říká validace na straně klienta. Na vašem serveru se jí říká validace na straně serveru. Validace na straně klienta dá návštěvníkům okamžitou zpětnou vazbu, když udělají chybu. Skutečně před útoky chrání validace na straně serveru, protože útočníci mohou kontroly na straně klienta obejít.

Co je sanitace vstupů?

Sanitace je odstranění nebo zneškodnění všeho nebezpečného ve vstupu od uživatele dřív, než ho uložíte nebo zpracujete. I když data projdou validací, mohou stále obsahovat kód nebo znaky určené k tomu, aby způsobily škodu.

Příklady toho, co sanitace dělá:

  • Odstraňuje z textových polí značky HTML, například `<script>` a `<img>`
  • Odstraňuje speciální znaky SQL, které by šly použít k prolomení databází
  • Převádí speciální znaky tak, aby se braly jako text, ne jako kód
  • Omezuje délku vstupu, aby se zabránilo útokům přetečením vyrovnávací paměti

Validace a sanitace spolupracují, ale slouží různým účelům. Validace kontroluje, že data mají správný formát. Sanitace odstraní vše nebezpečné, i když je formát technicky správný.

Jak fungují injekční útoky

SQL injection

K útoku SQL injection dojde, když útočník vloží do pole formuláře kód SQL. Pokud kód vašeho formuláře tento vstup nesanitizuje, kód SQL se provede ve vaší databázi.

Příklad: Přihlašovací formulář chce e-mailovou adresu. Místo e-mailu útočník odešle:

' OR '1'='1

Pokud to váš formulář nesanitizuje, váš kód může spustit dotaz SQL, který vypadá takto:

SELECT * FROM users WHERE email = '' OR '1'='1'

Část `OR '1'='1'` způsobí, že podmínka platí vždy, takže dotaz vrátí všechny uživatele, ne jen toho s daným e-mailem. Útočník tak obešel přihlašování.

Cross-Site Scripting (XSS)

K útoku XSS dojde, když útočník odešle do pole formuláře kód JavaScript. Pokud formulář tento kód nesanitizuje a uloží ho, JavaScript se později spustí v prohlížečích každého, kdo si tato data zobrazí.

Příklad: Formulář pro komentáře přijímá komentáře od uživatelů. Útočník odešle:

<script>alert('hacked')</script>

Pokud se to nesanitizuje a uloží do databáze, JavaScript se spustí a zobrazí upozornění, jakmile si někdo otevře sekci s komentáři. Nebezpečnější verze by mohla ukrást cookies, přesměrovat návštěvníky na phishingovou stránku nebo získat data z formulářů.

Command injection

Pokud se data z vašeho formuláře používají v systémových příkazech (což se v některých backendových systémech děje), může útočník vložit příkazy operačního systému.

Příklad: Pole formuláře se použije v příkazu, jako je tento:

ffmpeg -i $filename output.mp4

Pokud se `$filename` nesanitizuje a útočník odešle `;rm -rf /`, příkaz se změní na:

ffmpeg -i ;rm -rf / output.mp4

Příkaz `rm -rf /` se spustí a smaže soubory ze systému. Proto by systémové příkazy nikdy neměly dostávat nesanitizovaný vstup od uživatele.

Validace a sanitace pro různé typy dat

E-mailové adresy

Validace: Zkontrolujte, že vstup odpovídá vzoru e-mailu (něco jako text@domena.koncovka). Ověřte, že obsahuje jen povolené znaky.

Sanitace: Odstraňte všechny značky HTML a speciální znaky. Ponechte jen písmena, číslice, tečky, spojovníky a zavináč.

Telefonní čísla

Validace: Zkontrolujte, že obsahuje jen číslice, spojovníky, závorky a mezery. Ověřte, že délka odpovídá očekávané zemi.

Sanitace: Odstraňte všechny nečíselné znaky kromě spojovníků a závorek. Podle potřeby odstraňte úvodní nuly nebo mezery.

Textová pole (komentáře, jména, adresy)

Validace: Zkontrolujte, že pole není prázdné a že délka je rozumná (ne miliony znaků).

Sanitace: Odstraňte nebo převeďte značky HTML, JavaScript a speciální znaky SQL. Ponechte jen prostý text a základní interpunkci.

Čísla a částky

Validace: Zkontrolujte, že vstup je číslo. U cen nebo množství zkontrolujte, že jde o kladné číslo.

Sanitace: Odstraňte všechny nečíselné znaky. Podle potřeby zaokrouhlete na správný počet desetinných míst.

Hesla

Validace: Zkontrolujte minimální délku (alespoň 8 znaků) a případně požadujte kombinaci velkých a malých písmen, číslic a symbolů.

Sanitace: Hesla neořezávejte ani neupravujte. Mají se ukládat přesně v zadané podobě (jako hash, nikdy jako prostý text). Pokud z hesla odstraníte znaky, uživatelé se nebudou moci přihlásit.

Nahrávání souborů

Validace: Zkontrolujte, že typ souboru odpovídá očekávání (např. jen soubory PDF, jen obrázky). Zkontrolujte, že soubor není příliš velký.

Sanitace: Soubor přejmenujte, aby útočníci nemohli využít zvláštní názvy souborů. Prohledejte soubor, zda neobsahuje malware. Uložte ho mimo kořenový adresář webu, aby se nemohl spustit jako kód.

Jak validaci a sanitaci zavést

Na straně klienta (v prohlížeči)

Použijte atributy validace vstupů z HTML5, aby návštěvníci dostali okamžitou zpětnou vazbu:

<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120">

Tím zachytíte zjevné chyby a zlepšíte zkušenost uživatelů. Validaci na straně klienta ale lze obejít, takže sama o sobě není bezpečnostním opatřením.

Na straně serveru (na vašem serveru)

Tady se odehrává bezpečnost. Váš backendový kód musí validovat a sanitizovat každý údaj:

// Pseudo-code example if (email does not match email pattern) { reject the submission } // Remove HTML tags sanitized_comment = remove_html_tags(comment_text) // Escape special characters for database safe_name = escape_sql_characters(user_name) // Only then store the data store_in_database(safe_name, sanitized_comment)

Používejte parametrizované dotazy pro databáze

Nejlepší obranou proti SQL injection jsou parametrizované dotazy (říká se jim také prepared statements). Místo vkládání vstupu od uživatele přímo do dotazu SQL použijete zástupné znaky a data předáte zvlášť:

// Bad (vulnerable): query = "SELECT * FROM users WHERE email = '" + email + "'" // Good (safe): query = "SELECT * FROM users WHERE email = ?" execute(query, [email])

U parametrizovaných dotazů parser SQL ví, že vstup od uživatele jsou data, ne kód. I když útočník odešle kód SQL, bere se jako prostý text.

Používejte knihovny a frameworky

Nepište sanitační kód od nuly. Použijte osvědčené knihovny určené k tomuto účelu. V PHP použijte htmlspecialchars() nebo knihovnu jako HTML Purifier. V Pythonu použijte modul `html` nebo knihovnu jako bleach. V Node.js použijte `express-validator` nebo podobný nástroj. Tyto knihovny jsou otestované a aktualizované, aby zvládly nové typy útoků.

Časté chyby při validaci a sanitaci

Validace jen na straně klienta. Validace na straně klienta slouží pro pohodlí uživatele, ne pro bezpečnost. Útočník ji může obejít. Musíte validovat i na serveru.

Zakazování nebezpečných znaků místo povolení bezpečných. Pokud se pokusíte zablokovat SQL injection odstraněním středníků a uvozovek, útočníci najdou způsob, jak to obejít. Raději povolte jen znaky, které očekáváte (u telefonních čísel jen číslice a spojovníky), a vše ostatní odmítněte.

Spoléhání na datový typ pole formuláře. Pokud máte číselné pole, prohlížeč pošle text, který vypadá jako číslo. Váš server musí před použitím stejně ověřit, že jde skutečně o číslo. Nikdy nepředpokládejte, že datový typ je správný.

Zapomenutí sanitovat data, která se zobrazují. I když jsou data uložena bezpečně, pokud je zobrazíte na webové stránce bez převedení HTML, mohou útočníci vložit kód, který se spustí v prohlížečích návštěvníků, když tato data uvidí.

Sanitace ve špatném pořadí. Nejdřív validujte (je to správný formát?), pak sanitizujte (je to bezpečné?). Pokud nejdřív sanitizujete a pak validujete, můžete odmítnout data, která byla ve skutečnosti bezpečná.

Co WEMASY dělá pro validaci vstupů

WEMASY validuje pole formulářů automaticky podle typu pole, který zvolíte. Pole pro e-mail se kontrolují na platný formát e-mailu. Číselná pole se kontrolují na číselný vstup. U povinných polí se před odesláním kontroluje, zda mají obsah. Na straně serveru WEMASY sanitizuje veškerý vstup a před uložením odeslaných dat z něj odstraní HTML, JavaScript a další nebezpečný kód. Vy nastavíte, která pole se mají sbírat, a validaci i sanitaci WEMASY zajistí na pozadí.

Které funkce formulářů zahrnuje váš tarif, uvidíte v ceníku.

Často kladené otázky

Mohu místo validace použít WAF (Web Application Firewall)?
WAF dokáže zachytit některé injekční útoky dřív, než se dostanou k vašemu formuláři, což pomáhá. Není to ale náhrada validace a sanitace. WAF je druhá linie obrany. Kód vašeho formuláře musí data stále validovat a sanitizovat sám. Díky kombinaci WAF a validace vstupů máte několik vrstev ochrany.
Co když návštěvník oprávněně potřebuje odeslat speciální znaky?
Speciální znaky, jako jsou apostrofy, spojovníky a ampersandy, jsou bezpečné, pokud správně sanitizujete. Někdo může mít například jméno "O'Brien" nebo "Mary-Jane". Tyto znaky můžete bezpečně přijmout, pokud je správně ošetříte pro databázi (parametrizovanými dotazy) i při zobrazení (převedením HTML). Klíčem je správná sanitace, ne blokování znaků.
Mám validovat na straně klienta i serveru?
Ano. Validace na straně klienta dává návštěvníkům okamžitou zpětnou vazbu a zlepšuje zkušenost (vědí, že se překlepli, ještě před odesláním). Skutečně před útoky chrání validace na straně serveru. Používejte obě vrstvy. Strana klienta je pro pohodlí uživatele. Strana serveru je pro bezpečnost.
Jaký je rozdíl mezi převedením (escaping) a sanitací?
Převedení (escaping) změní nebezpečné znaky tak, aby se braly jako prostý text (například < se změní na <). Sanitace nebezpečný obsah odstraní úplně (například smaže všechny značky HTML). Escaping data zachová, sanitace odstraní hrozbu. U většiny dat z formulářů je sanitace (úplné odstranění značek) bezpečnější než escaping (jejich převedení).
Musím se bát injekčních útoků u formulářů jen pro čtení?
Pokud formulář jen zobrazuje informace (nic neodesílá), nemá žádnou zranitelnost vůči injekci. Pokud ale tento formulář někdy zobrazuje data odeslaná uživateli, stále musíte sanitizovat. Útočník mohl dříve odeslat škodlivý kód a při zobrazení se tento kód spustí. Veškerá data odeslaná uživateli vždy před zobrazením sanitizujte, bez ohledu na typ formuláře.

Využijte to hned
na vlastním webu.

Začněte zdarma s WEMASY a postavte si web za pár minut.