Jak na Hardcoded credentials

 

Mezi základní principy bezpečného software vývoje bezpochyby patří nevkládat citlivé informace do zdrojového kódu (hardcoded credentials). Co do této oblasti hardcoded credentials patří? Zpravidla cokoliv, co když někdo neoprávněný získá, tak z toho nemáme radost. Proč? Většinou s tím totiž získá přístupy nebo přihlašovací údaje (connection stringy do dalších vrstev, tokeny, loginy, hesla) atp.

Z jakého důvodu by někdo takové informace přímo do zdrojového kódu vkládal? Podle mého názoru pro to mohou existovat různé důvody či motivace. Může to být naprostý záměr (provedu to teď takto, pak to někdy změním, potřebuji to hlavně rychle dodat a otestovat), či nevědomost/nezkušenost (nikdo mě nevede k tomu, abych to nedělal a nevím, že to dělat nemám), nebo vím, že to není optimální, ale nevím prostě jak na to, jak to udělat jinak. Důvodů pro vložení citlivých údajů či hesel do kódu může být opravdu spousta.

Suma sumárum, když se nám takové hardcoded credentials objeví v nešifrované podobě přímo v kódu, který je pak sdílen interně či externě v tzv. repositářích zdrojového kódu (code repository), např. svn, github, gitlab instancích, je průšvih na světě.

Pojďme se nyní podívat, jak můžeme tuto oblast řešit v nativním cloudovém prostředí (cloud native), které je založené na:

  • architektuře mikro služeb ve smyslu architektonického konceptu majícího za cíl vytvářet software řešení na bázi malých oddělených služeb, kde může mít každá z nich svůj vlastní životní cyklus (opak monolitu)
  • kontejnerech, jako standardu pro abstrakci aplikace a jejich závislostí od infrastruktury
  • API specifikovaných jako rozhraní mezi jednotlivými službami
  • DevOps principech a kultuře

Abychom se mohli zamyslet nad nějakým typickým příkladem, představme si nasazení orchestrační platformy pro kontejnery Kubernetes jako PaaS (Platform as a Service) v cloud prostředí Microsoft Azure, což je Azure Kubernetes Service (AKS). K tomuto prostředí doplníme další nezbytné komponenty, tak aby prostředí bylo celistvé. Je nutné doplnit následující:

  • Azure Container Registry (ACR), jako registr pro ukládání binárních verzí kontejnerů (a případně dalších artefaktů)

  • Azure DevOps (ADO), jako nástroj obsahující další nezbytné služby, Code repository, orchestraci v rámci DevOps (CI, CD pipelines)

Takovou jednoduchou architekturu můžete vidět na obrázku níže:

Diagram showing the Azure DevOps workflow to build Docker images from source code, push images to Azure Container Registry, and deploy to Azure Kubernetes Service.

Obrázek 1: Referenční architektura AKS v Azure (zdroj Microsoft)

Obdobou samozřejmě může být jakékoliv IaaS řešení (např. nasazení Kuberenetes či jiné orchestrační platformy přímo na virtuální servery, či v on-premise), nebo využití jiných cloud poskytovatelů či jejich implementací Kubernetes jako PaaS, například Amazon Elastic Kubernetes Service (EKS), Google Kubernetes Service (GKE) atp. možností je dnes mnoho.

Máme tedy cílovou architekturu řešení, na které nám poběží kontejnerizované aplikace (AKS, ACR, ADO), je jedno v čem vyvíjím, zkrátka umím-li aplikaci psanou v daném zdrojovém kódu kontejnerizovat a dává-li to celé smysl, tak takovou architekturu použiji.

Předpokládejme nyní, že se snažíme vytvářet aplikace opravdu „cloud native“. Vše, co potřebujeme od aplikačního kódu samotného, přes konfigurace po softwarově definovanou infrastrukturu máme opravdu v kódu, prostě úplně vše. O životní cyklus aplikací nasazených do kontejnerů a o různé typy prostředí (např. dev, test, prod) se nám starají Continuous Integration / Continuous Deployment (CI/CD) pipelines, které jsme v našem Azure DevOps prostředí (či githubu nebo jinde) nastavili a ony pipelines jsou taktéž definované jako kód (v lepším případě).

Nikdo (ani administrátor, ani developer) neběhá po infrastruktuře a neprovádí nasazení čehokoliv jako patchů operačního systému, middleware, či nasazování aplikačního kódu ručně! Celou infrastrukturu včetně artefaktů máme ve verzích a parametrizovanou.

Infrastruktura nyní odpovídá nativní cloudové architektuře, co ale teď s těmi hardcoded credentials?

V kódu je prostě nikde nechceme.

Jaké ale máme možnosti?

Možností je vícero a my bychom měli vědět, kam chceme směřovat, abychom si nějakou možnost vybrali.

Můžeme začít od nejnižší úrovně bezpečnosti po nejvíce bezpečné řešení, například:

  • Řešení secrets na úrovni Azure DevOps

Jedná se o parametrizaci aplikačního prostředí, kde v pipelines parametrizujeme deployment taktéž pro secrets (connection stringy, tokeny, loginy, hesla) a tyto objekty ukládáme ve službě Azure DevOps jako secure files.

Alternativně máme službu Azure DevOps integrovanou na službu Azure KeyVault a secrets máme uložena ve službě Azure KeyVault, to znamená, že Pipeline musí mít přístup k tzv. service connection prostřednictvím kterých se pod přidělenou identitou integruje na Azure Key Vault.

  • Adopcí SDK (Software Development Kit) pro Azure KeyVault přímo v aplikačním kódu

Použijeme SDK pro daný programovací jazyk přímo v kódu aplikace https://docs.microsoft.com/en-us/azure/key-vault/general/client-libraries, a secrets jsou tudíž v Azure Key Vault

  • Řešení secrets na úrovni Kubernetes Secrets

Kubernetes nativně umí pracovat se secrets . Ty jdou pak mapovat ke kontejnerům jako “environment variables” či “volumes”. Otázkou však zůstává, jak je do Kubernetes dostaneme. Secrets samotné se ukládají do perzistentní vrstvy Kubernetes, tj. do databáze “etcd”, ke které přistupuje Kubernetes API server, secrets nejsou v této databázi šifrované, ale pouze encodované BASE64 algoritmem. V prostředí PaaS jsou master nody spravované cloud providerem (v tomto případě společnosti Microsoft), tj ETCD databáze je hostovaná na master nodech u Cloud poskytovatele.

  • Řešení secrets na úrovni Kubernetes Secrets s integrací na Azure KeyVault

Existují řešení třetích stran, které umožňují integraci mezi Kubernetes secrets a službou Azure KeyVault, či umožňují pro mapování secrets ze služby Azure KeyVault přímo do kontejneru, tak aby se přeskočilo (bypass) uložení secrets do Kubernetes Secrets.

Takové řešení umožní nezasahovat do zdrojového kódu aplikace (ta si bude brát secrets z proměnných) a přitom přesune životní cyklus secrets do instance Azure KeyVault.

Mezi takové řešení patří např. akv2k8s

  • Jakékoliv jiné Vaulty

Existuje spousta dalších Vault řešení pro ukládání secrets, např. HashiCorp Vault a další. Vždy je zásadní přistupovat do Vaultu bezpečně, aniž bychom tím sami způsobili hardcoded credentials.

  • Mozilla SOPS, či jiné šifrovací nástroje

Můžeme šifrovat, což znamená šifrovat samotné konfigurační soubory, ve kterých jsou dané secrets, Pipelines, pak musí mít možnost dešifrovat daný obsah, stejně tak, jako osoba, které prostředí spravuje/konfiguruje, můžete použít např. https://github.com/mozilla/sops .

  • Určitě existuje mnoho dalších přístupů k problematice či způsobů, které jsem neuvedl.

Jakou možnost si tedy vybereme?

Určitě se mnou budete souhlasit, že bychom vždy měli mít na paměti, bezpečnostní požadavky společnosti, s ohledem na nutné regulace, které musí splňovat. To znamená, že ve větších společnostech nám může (by měl) jít naproti někdo, kdo je zodpovědný za informační bezpečnost, či mu můžeme dané možnosti navrhnout a společně vybrat nejvhodnější možnost dle potřeb a požadavku společnosti.

Co bychom však neměli opomíjet?

  • Vybrat nějakou z možností a po implementaci provést osvětu na všechny interní/externí strany, které pro společnost vyvíjí
  • DevSecOps: Zapojit do pipelines i další část bezpečnosti jako je minimálně statická analýza kódu, kde můžeme v nástrojích rozpoznat hardcoded credentials a pipelines nastavit, tak aby nebylo možné přejít do dalších fází (merge mezi jednitlivými větvěmi kódu, přechod mezi build a release fázemi, atp.) až k deploymentu v případě výskytu Vulnerabilit (v tomto případě hardcoded credentials)
  • Používání Integrated Development Environment (IDE) ve kterém vzniká zdrojový kód infrastruktury či aplikace s doplňky, které již na samém počátku upozorňují na výskyt takových “hardcoded credentials”

My si nyní vybereme např. volbu Řešení secrets na úrovni Kubernetes Secrets s integrací na Azure KeyVault a to z důvodů:

  • Nechceme dle https://12factor.net/ do aplikačního kódu přidávat jakékoliv závislosti na místním prostředí (např. použití SDK na AzureKeyVault)
  • Chceme eliminovat hardcoded credentials ve formě domluvy s Developery o používání variables a čerpání secrets z variables (opět zachování přenositelnosti, při přesunu kontejneru do jiné orchestrační platformy, či k jinému poskytovateli, nebude muset developer zasahovat do zdrojového kódu)
  • Chceme vytáhnout secrets do odděleného bezpečného prostředí a nechceme, aby byl jejich obsah přímo součástí pipelines a repository.

Reálnou implementaci si ukážeme v dalším článku.

Nevíte si rady s výběrem vhodného řešení jak předcházet Hardcoded credentials v Kubernetes v Azure, obraťte se na nás a rádi Vám pomůžeme.

Sdílej v médiích

hardcoded-credentials

Kontakt

Nenašli jste, co hledáte? Pošlete nám zprávu a zůstaneme s vámi ve spojení.

* Vyžadované pole. Osobní data použijeme pouze pro vypracování odpovědi na dotaz. Pravidla zpracování osobních údajů.

* Souhlas se zpracováním údajů

map us
map eu