Hlavní navigace

Chyby v programovacích jazycích ohrožují bezpečnost aplikací

Petr Krčmář

Pět velmi populárních programovacích jazyků bylo podrobeno bezpečnostním zkouškám. JavaScript, Perl, PHP, Python a Ruby obsahují v různých implementacích vážné bezpečnostní chyby, které ohrožují výsledný kód.

Doba čtení: 3 minuty

Na konferenci Black Hat Europe 2017 byla odhalena celá řada bezpečnostních chyb v populárních programovacích jazycích. Interprety těchto jazyků obsahují vážné bezpečnostní chyby, které pak vystavují výsledný kód různým typům útoků. Autorem nové analýzy je Fernando Arnaboldi, který pracuje jako bezpečnostní konzultant ve společnosti IOActive.

Pro testování vytvořil vlastní automatizovaný software, pomocí kterého se snažil objevit bezpečnostní chyby v pěti nejpopulárnějších interpretovaných jazycích současnosti: JavaScript, Perl, PHP, Python a Ruby.

Testované implementace daných jazyků

Při testování byla použita metoda zvaná fuzzing, kdy se na vstup programu dostávají nevalidní, neočekávaná nebo jednoduše náhodná data. To dovoluje navozovat běžně netestované stavy, které sice neodpovídají běžnému použití, ale mohou být zneužity k cílenému útoku.

Fuzzing umožňuje odhalit pády, špatnou práci s paměti nebo třeba neočekávané chování programu. Nejedná se o novinku, tyto techniky se používají už velmi dlouho, rádi je mají například lidé z Google. Nedávno byla takto objevena celá řada chyb v linuxových ovladačích USB.

Diferenciální fuzzer XDiFF

Arnaboldi si pro tento účel napsal vlastní diferenciální fuzzer XDiFF (eXtended Differential Fuzzing Framework), který poté uvolnil na GitHubu. Je napsán tak, aby generoval práva pro pětici zmíněných jazyků. Pro každý z nich zvolil sadu základních funkcí, do kterých pak vkládal různé typy vstupů (payloads).

Počet testovaných funkcí

Aby bylo možné odhalit zranitelnosti v kódu, je potřeba zvolit správné vstupy. Autor tedy zvolil méně než tři desítky primitivních hodnot (čísla, znaky a podobně), které doplnil o známý payload. Ten byl zvolen tak, aby dovoloval odhalit, že se testovaná aplikace pokusila přistoupit k externím zdrojům – tedy že se stalo něco neočekávaného.

Diferenciální fuzzery jsou méně časté než ty klasické. Jejich funkce je rozšířená o to, že obvykle testují jeden kód na více různých implementacích stejného jazyka a hledají odlišné chování. Porovnávají se například výstupy a chybové hlášky s očekávaným stavem.

Konkrétně se hlídá, zda program vyzrazuje obsah lokálních souborů, spouští cizí kód nebo volá neobvyklé funkce operačního systému. Tato náročná práce přinesla své ovoce, každý z testovaných programovacích jazyků má nějaký problém:

  • Python obsahuje nedokumentované metody a lokální proměnné, které mohou být zneužity pro spuštění příkazu v operačním systému.
  • Perl obsahuje funkce typu typemap, které dovolují provést kód stejně jako  eval().
  • Node.js zobrazuje za určitých okolností chybové hlášky odhalující obsah souborů na disku.
  • JRuby načítá a spouští vzdálený kód ve funkci, která k tomu není určena.
  • PHP dovoluje zneužít jména konstant ke vzdálenému spuštění kódu.

Chyby ohrožují i dobře napsané programy

Arnaboldi varuje, že případný útočník může tyto chyby zneužít i v programu, který je jinak napsán velmi bezpečně. Protože se programy vyskytují v interpretru, může je programátor jen velmi těžko ovlivnit. Nevědomky tak při psaní svého kódu použije nebezpečné funkce, které jsou zneužitelné, i když je zbytek programu napsán přesně podle pravidel bezpečného programování.

Příklady kódů narážejících na chyby

Podle objevitele bezpečnostních problémů jde pravděpodobně o chyby v kódu nebo o snahu zjednodušit si vývoj. Chyby jednoznačně ohrožují výsledné programy, ale měly by být opraveny v interpretrech. Taková oprava pak vyřeší plošně problémy ve všech programech využívajících daný jazyk.

Našli jste v článku chybu?