Validace vstupu
- Validace vstupních dat se provádí proto, aby se zajistilo, že do systému vstupují pouze správná data
- To zabrání uložení nesprávných dat a následných aplikačních chyb v navazujících komponentách
- K validaci by mělo dojít co nejdříve, nejlépe hned po přijetí dat
- Data ze všech nedůvěryhodných zdrojů by měla podléhat validaci
- Nejen uživatelská data, ale také data z jiných systémů, třetích stran, dodavatelů atd.
- Každý z nich totiž může být kompromitován a odesílat chybná data
- Validace vstup ů by neměla být používána jako primární metoda prevence XSS, SQL injection a dalších
- Při správné implementaci však může významně přispět ke snížení jejich dopadu
Strategie
- Provádějte validaci jak na syntaktické, tak na sémantické úrovni
- Syntaktická = zajišťuje správnou syntaxi dat (datum, SSN, symbol měny)
- Sémantická = zajišťuje správnost hodnot v daném kontextu (datum zahájení, datum ukončení, cena v očekávaném rozsahu)
- Předcházejte útokům co nejdříve při zpracování požadavku uživatele
- K odhalení neoprávněného vstupu lze použít právě validaci
Implementace
- Validace lze realizovat pomocí libovolné programovací techniky, která umožňuje vynucení syntaktické a sémantické správnosti
- Validátory datových typů, které jsou nativně k dispozici ve webových frameworcích (Django validators, Apache Commons Validators, atd.)
- Validace podle JSON nebo XML (XSD) schématu
- Konverze typů (
Integer.parseInt()
,int()
) s přísným zpracováním výjimek - Kontrola minimálního a maximálního rozsahu hodnot pro číselné parametry a kontrola délky řetězce
- Pole povolených hodnot pro malé sady string parametrů (dny v týdnu)
- Regulární výrazy pro jakákoli jiná strukturovaná data pokrývající celý řetězec (
^...$
) a nepoužívající “libovolný” znak (\S
)
Seznam povolených a nepovolených vstupů
- Častou chybou je použití validace na základě seznamu nepovolených vstupů ve snaze odhalit nebezpečné znaky a vzory (
'
,1=1
,<script>
) - Takové filtry je možné triviálně obejít
- Zároveň tyto filtry brání autorizovanému přístupu, jako je například
O'Brian
, kde je znak'
legitimní - Seznam povolených vstupů je však vhodný pro všechna vstupní data
- Validace na základě tohoto seznamu zahrnuje definici toho, co je autorizováno s tím, že všechno ostatní autorizováno není
- Pokud jde o dobře strukturovaná data (rodná čísla, PSČ, emaily), mělo by být snadné definovat silný validační vzor založený na regulárních výrazech
- Pokud vstupní hodnota pochází ze sady možností (selectbox, radiobutton), pak musí přesně odpovídat jedné z definovaných hodnot selectboxu nebo radiobuttonu
Validace textu ve volném tvaru
- Text ve volném tvaru (zejména Unicode) je obtížně validovatelný kvůli velk ému množství znaků, které je potřeba povolit
- Zdůrazňuje důležitost kódování v závislosti na kontextu a ukazuje, že validace není hlavní ochranou proti XSS
- Pokud uživatelé chtějí do pole pro komentář napsat znaky jako
<
nebo'
, mohou pro to mít legitimní důvod
- Pokud uživatelé chtějí do pole pro komentář napsat znaky jako
- Úkolem aplikace je s textem správně zacházet po celou dobu životního cyklu dat
- Hlavními zásadami jsou
- Normalizace - zajistěte, aby bylo v celém textu použito kanonické kódování a aby se v něm nevyskytovaly žádné neplatné znaky
- Seznam povolených kategorií znaků - Unicode umožňuje zařazení do kategorií, jako jsou čísla, písmena atp.
- Individuální seznam znaků - na základě kontextu můžete povolit ideogramy, apostrofy, pokud nechcete povolovat celou kategorii interpunkčních znamének
Regulární výrazy
- Regulární výrazy mohou být komplikované a přesahují rámec tohoto dokumentu
- Více informací najdete v OWASP validation regex repository
- Při návrhu si dejte pozor na útoky typu ReDoS
- Způsobují, že program používající špatně navržený regulární výraz pracuje velmi pomalu a dlouho využívá CPU prostředky
- Použijte validaci na všechna vstupní data
- Definujte povolenou množinu znaků
- Definujte minimální a maximální délku dat (
{1,25}
)
Regulární výrazy - seznam povolených znaků
- Validace US PSČ:
^\d{5}(-\d{4})?$
- Validace US států ze seznamu (selectbox)
^(AA|AE|AP|AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|
HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|
NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|
TX|UT|VT|VI|VA|WA|WV|WI|WY)$
- Použití v Javě
private static final Pattern zipPattern = Pattern.compile("^\d{5}(-\d{4})?$");
public void doPost( HttpServletRequest request, HttpServletResponse response) {
try {
String zipCode = request.getParameter( "zip" );
if ( !zipPattern.matcher( zipCode ).matches() {
throw new YourValidationException( "Improper zipcode format." );
}
// Do what you want here, after its been validated ..
} catch(YourValidationException e ) {
response.sendError( response.SC_BAD_REQUEST, e.getMessage() );
}
}
- Některé validátory jsou předdefinovány v různých open source balíčcích - např. Apache Commons Validators
Client side vs server side validace
- Útočník, který zakáže javascript nebo použije proxy, může obejít jakoukoli validaci prováděnou na klientovi
- Ujistěte se, že validace prováděná na klientovi je také na serveru
Validace rich user contentu
- Rich content je velmi obtížné validovat
- Více informací najdete v XSS cheat sheetu