S dotazi nás neváhejte kontaktovat: (420) 777 849 161 - Email info@vyroba-webu.cz

Jenkins Build Server

Dnes si zkusíme otestovat nějaký větší projekt. Vybral jsem Open-Source build server Jenkins. Abychom nemuseli mít dilema zda zakládat tikety pro vývojáře dané aplikace a jednalo se pouze o ukázku, otestujeme nějakou starší verzi. Vybral jsem verzi 1.649. Každý si jako vždy můžete tento kód zkusit otestovat vaším nástroje, tato verze je k dispozici zde:

https://github.com/jenkinsci/jenkins/releases/tag/jenkins-1.649

Prohnal jsem aplikaci SAST nástrojem (jako vždy neuvádím kterým, nechávám na fantazii čtenářů). Níže je přehled vybraných nálezů z krátkým popisem jak by mělo/mohlo vypadat vyhodnocení takových nálezů:

Code Injection

V Service.java

Popis chyby:

Aplikace spouští nedůvěryhodný kód – instanciace třídy ze souboru podle názvu.

Doporučení:

Jedná se o nález, který je důsledkem open-source pluginové architektury aplikace. Bylo by vhodné zvolit omezení formou whitelistingu, například názvy důvěryhodných tříd. Je třeba nasadit provozní opatření – aplikace by měla být spuštěna pod uživatelem s minimálním oprávněním a mít nakonfigurované role tak, že plug-iny může nasazovat pouze administrátor (ideálně po provedení code-review nebo statického testu).

 

Code Injection

V Service.java (další výskyt)

Popis chyby:

Aplikace spouští nedůvěryhodný kód – instanciace třídy ze souboru.

Doporučení:

Jedná se o nález, který je důsledkem open-source pluginové architektury aplikace. Bylo by vhodné zvolit omezení formou whitelistingu, například názvy důvěryhodných tříd. Je třeba nasadit provozní opatření – aplikace by měla být spuštěna pod uživatelem s minimálním oprávněním a mít nakonfigurované role tak, že plug-iny může nasazovat pouze administrátor (ideálně po provedení code-review nebo statického testu).

 

Stored Code Injection

V PluginManager

Popis chyby:

Metoda createPluginStrategy přijímá a dynamicky spouští uživatelský kód pomocí metody loadClass. To by mohlo umožnit útočníkovi vložit a spustit libovolný kód.
Útočník může kód vložit pomocí standardních textových polí do databáze nebo místního souboru. Tento text je pak načten metodou createPluginStrategy pomocí getProperty a následně odeslán spouštěcí metodě.

 

Doporučení:

Aplikace, která spouští kód třetí strany (pluginy), by měla být spuštěna pod uživatelem s minimálním oprávněním. Pokud je to možné, izolovat veškeré dynamické spouštění do separátního dedikovaného uživatelského účtu, který má oprávnění pouze pro specifické operace a soubory použité pro dynamické spouštění, podle principu nejmenší nutné zodpovědnosti.

 

Stored Code Injection

V Lifecycle.java

Popis chyby:

Metoda get přijímá a dynamicky spouští uživatelský kód pomocí metody loadClass. To by mohlo umožnit útočníkovi vložit a spustit libovolný kód.
Útočník může kód vložit pomocí standardních textových polí do databáze nebo místního souboru. Tento text je pak načten metodou get pomocí getProperty a následně odeslán spouštěcí metodě.

 

Doporučení:

Aplikace, která spouští kód třetí strany, by měla být spuštěna pod uživatelem s minimálním oprávněním. Pokud je to možné, izolovat veškeré dynamické spouštění do separátního dedikovaného uživatelského účtu, který má oprávnění pouze pro specifické operace a soubory použité pro dynamické spouštění, podle principu nejmenší nutné zodpovědnosti.

 

Stored Code Injection

V ConfigFile

Doporučení:
Jelikož se již správně používá whitelist a podepisování tříd nepřipadá v úvahu, riziko je nutné akceptovat (jedná se o základní funkčnost aplikace). Útočník nesmí získat přístup na úrovni file systému.

Stored XSS

V ConfigDirectory.java

Popis chyby:

Metoda load načítá data ze souborů *.conf pomocí funkce readLine. Tato data jsou bez kontroly zobrazena v ConfigFile.java:27. Stav umožňuje podvrhnout škodlivá data v konfiguraci.

 

Doporučení:

Validujte všechny vstupy bez ohledu na zdroj. Validace by měla být založená na whitelistu: namísto odmítání známých chyb akceptujte pouze data, která pasují do specifikované struktury. Kontrolujte datový typ, velikost, rozsah, formát a očekávané hodnoty.
Veškeré dynamické data plně zaenkódujte, před vložením do výstupu. Encoding byl měl být kontextově senzitivní, například:
• HTML encoding pro HTML obsah
• HTML Attribute encoding pro data zapisovaná do hodnot atributů
• JavaScript encoding pro serverem generovaný JavaScript.
Zvažte užití encoding knihovny ESAPI, nebo vestavených funkcí platformy. V hlavičce Content-Type explicitně určete podporované kódování znaků pro celou stránku.
Na session cookie nastavte atribut httpOnly, abyste zamezili zneužití formou XSS při krádeži cookie.

 

Stored XSS

V TcpSlaveAgentListener.java

Popis chyby:

Metoda run ziskava data z db,  pro element readUTF. Tento element prochazi volne kodem aniz by byl validovan a sanitizovan a je zobrazen uzivateli v metode error. To muze umožnit útok typu Stored Cross-Site-Scripting.

 

Doporučení:

Veškeré dynamické data plně zaenkódujte, před vložením do výstupu.

 

Reflected XSS All Clients

V Jenkins.java

Popis chyby:

Metoda doLoginEntry přesměrovává uživatele na jím zadaný parametr “from”; může uživatele přesměrovat na jiné stránky.

 

Doporučení:

Metoda by měla ověřovat parametr “from” a přesměrovávat pouze v rámci domény, ve které aplikace běží.

 

Deserialization of Untrusted Data

Nejčastější chyba v Jenkins. Níže uvádím několik z mnoha výskytů:

ConsoleNote.java

Popis chyby:

Serializovaný objekt buf je deserializován pomocí return (ConsoleNote) ois.readObject(); – není ověřena autentičnost, spoléhá se na casting. Jedná se o parser build-logu, takže veškerá data jsou implicitně nedůvěryhodná.

 

Doporučení:

Pokud je to třeba, využijte whitelist povolených objektů. Vždy se ujistěte, že objekt je známý, očekávaný a důvěryhodný. Nikdy nesestavujte dynamicky objekt, pokud jeho zdroj nebyl verifikován a považován za důvěryhodný a sám neobsahuje žádné nedůvěryhodné objekty.

 

AtomicFileWriter.java

Popis chyby:

Serializovaný objekt tmpFile zpracovaný v AtomicFileWriteru je bez kontroly deserializován pomocí XStream2.unmarshal.

 

Doporučení:

Pokud je to třeba, využijte whitelist povolených objektů. Vždy se ujistěte, že objekt je známý, očekávaný a důvěryhodný. Nikdy nesestavujte dynamicky objekt, pokud jeho zdroj nebyl verifikován a považován za důvěryhodný a sám neobsahuje žádné nedůvěryhodné objekty. Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

Run.java

Popis chyby:

Serializovaný objekt zpracovaný v Integer.parseInt uvnitř Run.java je bez kontroly deserializován pomocí unmarshal v XStream2 do proměnné LIST_CUTOFF. 

 

Doporučení:

Parametr LIST_CUTOFF by měl být ověřen na maximální povolený rozsah, aby se tak zamezilo potenciálnímu DoS při zobrazení komplexnější struktury artefaktů. Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

Run.java (další výskyt)

Popis chyby:

Serializovaný objekt zpracovaný v Integer.parseInt uvnitř Run.java je bez kontroly deserializován pomocí unmarshal v XStream2 do proměnné TREE_CUTOFF.

 

Doporučení:

Parametr TREE_CUTOFF by měl být ověřen na maximální povolený rozsah, aby se tak zamezilo potenciálnímu DoS při zobrazení komplexnější struktury artefaktů. Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

UpdateCenter.java

Popis chyby:

Serializovaný objekt zpracovaný v System.getProperty uvnitř UpdateCenter.java je bez kontroly deserializován pomocí unmarshal v XStream2 do proměnné UPDATE_CENTER_URL. Výsledem je riziko stažení podvrženého kódu ve formě aktualizace pluginu.

 

Doporučení:

Správným řešením je fixace aktualizačního URL na pevně definovanou hodnotu namísto generovaného názvu. Může mít nicméně negativní dopad na funkčnost. Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

FingerprintCleanupThread.java

Popis chyby:

Serializovaný objekt File zpracovaný v execute uvnitř FingerprintCleanupThread.java je bez kontroly deserializován pomocí fromXML v XmlFile.java.

 

Doporučení:

Kontrolovat strukčturu souboru a povolené hodnoty, zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

Nodes.java

Popis chyby:

Serializovaný objekt File zpracovaný v getNodesDir uvnitř FingerprintCleanupThread.java je bez kontroly deserializován pomocí fromXML v XmlFile.java.

 

Doporučení:

Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

View.java

Popis chyby:

Serializovaný objekt getInputStream zpracovaný v metodě create je bez kontroly deserializován pomocí fromXML.

 

Doporučení:

Zakázat parsování externích entit (až to v XStreamu půjde, zatím jde o známou zranitelnost https://nvd.nist.gov/vuln/detail/CVE-2016-3674).

 

Unchecked Input for Loop Condition

LargeText.java

Popis chyby:

Metoda doProgressText získá vstup uživatele od prvku “” start “”.
Hodnota tohoto prvku protéká kódem, aniž by byla ověřena, a nakonec se používá ve stavu smyčky. To představuje nekontrolovaný vstup pro podmínku smyčky.

 

Doporučení:

V ideálním případě nezakládejte smyčku na datech poskytovaných uživatelem. Je-li to nutné, musí být nejprve

ověřen vstup uživatele a jeho rozsah by měl být omezen.

 

Frameable Login Page

V RememberMeServicesProxy.java

Popis chyby:

Aplikace nepouživá X-FRAME-OPTIONS pro zamezení vložení stránky do cizího obsahu.

 

Doporučení:

X-Frame-Options: SAMEORIGIN nebo X-Frame-Options: ALLOW-FROM https://example.com/”

 

About fotodobias