Programovanie

Trinásť pravidiel pre vývoj bezpečných aplikácií Java

Zabezpečenie je jedným z najkomplexnejších, najširších a najdôležitejších aspektov vývoja softvéru. Zabezpečenie softvéru je tiež často prehliadané alebo zjednodušené iba na niekoľko menších úprav na konci vývojového cyklu. Výsledky vidíme na každoročnom zozname hlavných porušení zabezpečenia údajov, ktoré v roku 2019 predstavovalo viac ako 3 miliardy exponovaných záznamov. Ak sa to môže stať Kapitálu Jeden, môže sa to stať vám.

Dobrou správou je, že Java je dlhoročná vývojová platforma s mnohými zabudovanými bezpečnostnými funkciami. Balík zabezpečenia Java prešiel intenzívnym bojovým testovaním a je často aktualizovaný kvôli novým chybám zabezpečenia. Novšie Java EE Security API, vydané v septembri 2017, sa venuje zraniteľnostiam v architektúrach cloudu a mikroslužieb. Ekosystém Java obsahuje aj širokú škálu nástrojov na profilovanie a hlásenie bezpečnostných problémov.

Ale aj pri solídnej vývojovej platforme je dôležité zostať ostražití. Vývoj aplikácií je zložitý podnik a zraniteľné miesta sa môžu skrývať v pozadí. Mali by ste myslieť na bezpečnosť v každej fáze vývoja aplikácie, od jazykových funkcií na úrovni triedy až po autorizáciu koncového bodu API.

Nasledujúce základné pravidlá poskytujú dobrý základ pre vytváranie bezpečnejších aplikácií Java.

Pravidlo zabezpečenia Java # 1: Napíšte čistý a silný kód Java

Zraniteľnosti sa radi skrývajú v zložitosti, takže udržujte svoj kód čo najjednoduchší bez toho, aby ste obetovali funkčnosť. Používanie osvedčených princípov návrhu ako DRY (neopakujte sa) vám pomôže napísať kód, ktorý sa dá ľahšie preskúmať kvôli problémom.

Vo svojom kóde vždy zverejnite čo najmenej informácií. Skrytie podrobností implementácie podporuje kód, ktorý je udržiavateľný aj zabezpečený. Tieto tri tipy vám pomôžu pri písaní zabezpečeného kódu Java:

  • Využite dobre modifikátory prístupu Java. Vedieť, ako deklarovať rôzne úrovne prístupu pre triedy, metódy a ich atribúty, povedie k ochrane vášho kódu dlhá cesta. Všetko, čo sa dá zmeniť na súkromné, by malo byť súkromné.
  • Vyvarujte sa reflexii a introspekcii. Existujú prípady, kedy sú takéto pokročilé techniky zaslúžené, ale väčšinou by ste sa im mali vyhnúť. Použitím reflexie sa eliminuje silné písanie, ktoré môže do kódu vnášať slabé miesta a nestabilitu. Porovnávanie názvov tried ako reťazcov je náchylné na chyby a môže ľahko viesť ku kolízii menného priestoru.
  • Vždy definujte najmenšie možné povrchy API a rozhraní. Odpojte komponenty a umožnite im interakciu na najmenšej možnej ploche. Aj keď bude jedna oblasť vašej aplikácie napadnutá porušením, ostatné budú v bezpečí.

Pravidlo zabezpečenia Java č. 2: Vyhnite sa serializácii

Toto je ďalší tip na kódovanie, ale je dosť dôležité, aby ste boli jeho pravidlom. Serializácia vyžaduje vzdialený vstup a transformuje ho na plne obdarený objekt. Vynechá konštruktérov a modifikátory prístupu a umožňuje, aby sa prúd neznámych údajov stal bežiacim kódom v JVM. Výsledkom je, že serializácia Java je hlboko a inherentne nezabezpečená.

Koniec serializácie Java

Ak ste to ešte nepočuli, Oracle má dlhodobé plány na odstránenie serializácie z Javy. Mark Reinhold, hlavný architekt skupiny platforiem Java v spoločnosti Oracle, uviedol, že je presvedčený, že tretina alebo viac všetkých zraniteľností Java zahŕňa serializáciu.

Pokiaľ je to možné, vyhnite sa serializácii / deserializácii v kóde Java. Namiesto toho zvážte použitie formátu serializácie ako JSON alebo YAML. Nikdy nikdy nevystavujte nechránený koncový bod siete, ktorý prijíma a koná na základe toku serializácie. To nie je nič iné ako vítaná podložka pre chaos.

Pravidlo zabezpečenia Java č. 3: Nikdy nevystavujte nezašifrované poverenia ani údaje PII

Je ťažké tomu uveriť, ale táto chyba, ktorej sa dá vyhnúť, spôsobuje rok čo rok bolesť.

Keď používateľ zadá heslo do prehľadávača, odošle sa mu ako holý text na váš server. To by malo byť naposledy, čo uzrie svetlo sveta. Vy musieť zašifrujte heslo pomocou jednosmerného šifrovania pred tým, ako ho uložíte do databázy, a potom to urobte znova, kedykoľvek ho porovnáte s touto hodnotou.

Pravidlá pre heslá sa vzťahujú na všetky informácie umožňujúce identifikáciu osôb (PII): kreditné karty, rodné čísla atď. S osobnými údajmi, ktoré sú zverené do vašej žiadosti, by sa malo zaobchádzať s najvyššou opatrnosťou.

Nezašifrované poverenia alebo PII v databáze sú priepasťou v zabezpečení, ktorá čaká na odhalenie útočníka. Rovnako tak nikdy nezapisujte nespracované údaje do denníka ani ich inak neprenášajte do súboru alebo do siete. Namiesto toho pre svoje heslá vytvorte solený hash. Určite si urobte prieskum a použite odporúčaný hashovací algoritmus.

Skočíme na pravidlo č. 4: na šifrovanie vždy používajte knižnicu; nehádžte svoje.

Pravidlo zabezpečenia Java č. 4: Používajte známe a testované knižnice

Pochutnajte si na tejto otázke a odpovedi týkajúcej sa vytvorenia vlastného bezpečnostného algoritmu. Lekcia tl; dr je: používať známe a spoľahlivé knižnice a rámce, kedykoľvek je to možné. To platí v celom spektre, od hašovania hesiel po autorizáciu REST API.

Našťastie, Java a jej ekosystém tu máte chrbát. Pokiaľ ide o bezpečnosť aplikácií, Spring Security je de facto štandardom. Ponúka širokú škálu možností a flexibilitu, aby vyhovovala akejkoľvek architektúre aplikácií, a obsahuje celý rad bezpečnostných prístupov.

Prvým inštinktom v boji proti bezpečnosti by mal byť výskum. Preskúmajte osvedčené postupy a potom preskúmajte, ktorá knižnica tieto postupy za vás implementuje. Napríklad, ak sa pozeráte na používanie webových tokenov JSON na správu autentifikácie a autorizácie, pozrite sa na knižnicu Java, ktorá zapuzdruje JWT, a potom sa naučte, ako to integrovať do Spring Security.

Aj pri použití spoľahlivého nástroja je pomerne ľahké rozdeliť autorizáciu a autentizáciu. Určite sa pohybujte pomaly a dvakrát skontrolujte všetko, čo robíte.

Pravidlo zabezpečenia Java č. 5: Buďte paranoidní ohľadom externého vstupu

Či už to pochádza od používateľa, ktorý píše do formulára, dátového skladu alebo vzdialeného API, nikdy neverte externému vstupu.

Injekcia SQL a skriptovanie medzi servermi (XSS) sú iba najčastejšie známe útoky, ktoré môžu vyplynúť z nesprávneho zaobchádzania s externým vstupom. Menej známym príkladom - jedným z mnohých - je „útok na miliardu smiechu“, pri ktorom môže rozšírenie entity XML spôsobiť útok Denial of Service.

Kedykoľvek dostanete vstup, malo by to byť skontrolované a dezinfikované. To platí najmä pre všetko, čo by sa mohlo predložiť na spracovanie inému nástroju alebo systému. Napríklad ak by niečo mohlo skončiť ako argument pre príkazový riadok OS: pozor!

Špeciálnou a známou inštanciou je SQL injection, ktorej sa venuje ďalšie pravidlo.

Pravidlo zabezpečenia Java č. 6: Na spracovanie parametrov SQL vždy používajte pripravené príkazy

Kedykoľvek vytvoríte príkaz SQL, riskujete interpoláciu fragmentu spustiteľného kódu.

S týmto vedomím je osvedčený postup vždy na vytvorenie SQL použite triedu java.sql.PreparedStatement. Podobné zariadenia existujú aj v obchodoch NoSQL, ako je MongoDB. Ak používate vrstvu ORM, použije sa implementácia Pripravené vyhlásenieje pre vás pod kapotou.

Pravidlo zabezpečenia Java č. 7: Neodhaľujte implementáciu prostredníctvom chybových správ

Chybové správy pri výrobe môžu byť pre útočníkov úrodným zdrojom informácií. Najmä stopy v zásobníku môžu odhaliť informácie o technológii, ktorú používate, a o tom, ako ju používate. Vyvarujte sa odhalenia stohovacích zásob koncovým používateľom.

Do tejto kategórie spadajú aj upozornenia na zlyhanie prihlásenia. Všeobecne sa prijíma chybové hlásenie „Prihlásenie zlyhalo“ verzus „Nenašiel som tohto používateľa“ alebo „Nesprávne heslo“. Ponúknite čo najmenšiu pomoc potenciálne nepriaznivým používateľom.

V ideálnom prípade by chybové správy nemali odhaľovať základný technologický zásobník pre vašu aplikáciu. Tieto informácie udržujte čo najpriehľadnejšie.

Pravidlo zabezpečenia Java č. 8: Udržujte bezpečnostné vydania aktualizované

Od roku 2019 spoločnosť Oracle implementovala novú licenčnú schému a harmonogram vydávania pre Javu. Bohužiaľ pre vývojárov, kadencia nového vydania veci neuľahčuje. Napriek tomu nesiete zodpovednosť za častú kontrolu aktualizácií zabezpečenia a ich použitie vo vašom prostredí JRE a JDK.

Pravidelnou kontrolou bezpečnostných stránok na domovskej stránke Oracle sa uistite, že viete, aké kritické opravy sú k dispozícii. Spoločnosť Oracle každý štvrťrok dodáva automatickú aktualizáciu opráv pre súčasné vydanie Java LTS (dlhodobá podpora). Problém je v tom, že táto oprava je k dispozícii, iba ak platíte za licenciu podpory Java.

Ak vaša organizácia za takúto licenciu platí, postupujte podľa postupu automatických aktualizácií. Ak nie, pravdepodobne používate OpenJDK a opravu budete musieť urobiť sami. V takom prípade môžete použiť binárnu opravu alebo existujúcu inštaláciu OpenJDK jednoducho nahradiť najnovšou verziou. Prípadne môžete použiť komerčne podporovaný OpenJDK ako Azul's Zulu Enterprise.

Potrebujete každú bezpečnostnú záplatu?

Ak pozorne sledujete výstrahy zabezpečenia, môžete zistiť, že danú sadu aktualizácií nepotrebujete. Napríklad vydanie z januára 2020 objaví sa byť kritickou aktualizáciou Java; pozorné čítanie však ukazuje, že aktualizácia iba opravuje medzery v zabezpečení Java appletu a neovplyvňuje servery Java.

Pravidlo zabezpečenia Java č. 9: Hľadajte chyby zabezpečenia závislostí

Existuje veľa nástrojov na automatické skenovanie zraniteľností vašej základne kódov a závislostí. Musíte ich iba použiť.

OWASP, projekt zabezpečenia otvorených webových aplikácií, je organizácia zameraná na zlepšovanie zabezpečenia kódu. Zoznam dôveryhodných, vysoko kvalitných nástrojov na automatické skenovanie kódu spoločnosti OWASP obsahuje niekoľko nástrojov orientovaných na Javu.

Pravidelne kontrolujte svoju databázu kódov, ale sledujte aj závislosti tretích strán. Útočníci sa zameriavajú na knižnice s otvoreným aj uzavretým zdrojom. Sledujte aktualizácie svojich závislostí a aktualizujte systém, keď budú vydané nové opravy zabezpečenia.

Pravidlo zabezpečenia Java č. 10: Monitorujte a zaznamenávajte aktivitu používateľov

Aj jednoduchý útok hrubou silou môže byť úspešný, ak aplikáciu aktívne nesledujete. Pomocou nástrojov na monitorovanie a zaznamenávanie môžete dohliadať na zdravie aplikácie.

Ak by ste sa chceli presvedčiť, prečo je monitorovanie dôležité, stačí sedieť a sledovať pakety TCP na porte na počúvanie vašich aplikácií. Uvidíte všetky druhy aktivít, ktoré presahujú rámec jednoduchých interakcií používateľov. Niektoré z týchto aktivít budú roboti a zloduchovia, ktorí hľadajú chyby.

Mali by ste sa prihlásiť a monitorovať neúspešné pokusy o prihlásenie a nasadiť protiopatrenia, aby ste zabránili beztrestnému útoku vzdialených klientov.

Monitorovanie vás môže upozorniť na nevysvetliteľné hroty a protokolovanie môže pomôcť odhaliť, čo sa pokazilo po útoku. Ekosystém Java obsahuje množstvo komerčných riešení a riešení otvoreného zdroja na protokolovanie a monitorovanie.

Pravidlo zabezpečenia Java # 11: Dávajte pozor na útoky DoS (Denial of Service)

Kedykoľvek spracúvate potenciálne drahé zdroje alebo podnikáte potenciálne nákladné operácie, mali by ste sa chrániť pred využitím zdrojov na úteku.

Spoločnosť Oracle udržuje zoznam potenciálnych vektorov tohto typu problému vo svojich pokynoch pre bezpečné kódovanie pre dokument Java SE pod hlavičkou „Odmietnutie služby“.

V zásade by ste vždy, keď idete vykonávať náročnú operáciu, napríklad rozbalenie komprimovaného súboru, mali sledovať explodujúce využitie zdrojov. Neverte manifestom súborov. Dôverujte iba skutočnej spotrebe na disku alebo v pamäti, sledujte ju a chráňte sa pred nadmernými situáciami servera na kolená.

Podobne je pri niektorých procesoch dôležité sledovať neočakávané večné slučky. Ak je slučka podozrivá, pridajte strážcu, ktorý zabezpečí, že slučka bude napredovať, a skratujte ju, ak sa zdá, že už bola zombie.

Pravidlo zabezpečenia Java č. 12: Zvážte použitie správcu zabezpečenia Java

Java má správcu zabezpečenia, ktorým je možné obmedziť prostriedky, ku ktorým má prístup spustený proces. Môže izolovať program z hľadiska prístupu na disk, pamäť, sieť a JVM. Zúžením týchto požiadaviek na vašu aplikáciu sa zníži stopa možného poškodenia útokom. Takáto izolácia môže byť tiež nepohodlná, a preto SecurityManager nie je predvolene povolený.

Sami sa budete musieť rozhodnúť, či budete pracovať SecurityManagerSilný názor stojí za ďalšiu vrstvu ochrany vašich aplikácií. V dokumentoch Oracle sa dozviete viac o syntaxi a možnostiach správcu bezpečnosti Java.

Pravidlo zabezpečenia Java č. 13: Zvážte použitie externej cloudovej autentifikačnej služby

Niektoré aplikácie musia jednoducho vlastniť svoje používateľské údaje; pre zvyšok by mohol mať poskytovateľ cloudových služieb zmysel.

Ak sa porozhliadnete po okolí, nájdete množstvo poskytovateľov cloudovej autentifikácie. Výhodou takejto služby je, že za zabezpečenie citlivých údajov používateľa je zodpovedný poskytovateľ, nie vy. Na druhej strane pridanie autentifikačnej služby zvyšuje zložitosť vašej podnikovej architektúry. Niektoré riešenia, ako napríklad FireBase Authentication, zahŕňajú SDK pre integráciu naprieč hromadou.

Záver

Predstavil som 13 pravidiel pre vývoj bezpečnejších aplikácií Java. Tieto pravidlá sú osvedčené, ale najväčšie pravidlo zo všetkých je toto: buďte podozrivý. K vývoju softvéru pristupujte vždy obozretne a s ohľadom na bezpečnosť. Vyhľadajte zraniteľné miesta vo svojom kóde, využite výhody bezpečnostných rozhraní API a balíkov Java a pomocou nástrojov tretích strán sledujte a zaznamenajte svoj kód kvôli bezpečnostným problémom.

Tu sú tri dobré zdroje na vysokej úrovni, ktoré vám pomôžu držať krok s neustále sa meniacim prostredím zabezpečenia Java:

  • OWASP Top 10
  • CWE Top 25
  • Pokyny spoločnosti Oracle k zabezpečeným kódom

Tento príbeh „Trinásť pravidiel pre vývoj bezpečných aplikácií Java“ pôvodne publikoval server JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found