Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Jan Novotný 23. 06. 2023, 00:14:55
-
Ahoj,
prosím, potřeboval bych poradit, jak se řeší situace, kdy do prográmku v c++ potřebuju zkompilovat hardcoded heslo pro připojení k (postgresql) databázi.
S použitím předpřipravené knihovny pgxx definuji connection string:
std::string connectionString = "host='server_ip_address' port='5432' dbname='database_name' user='username' password='Secret_12345'";
Pokud prográmek zkompiluju, heslo jde z binárky přečíst a to je problém.
Existuje nějaký nástroj, který by uměl pracovat jenom s HASHem hesla v connection stringu namísto vepsaného hesla?
Nebo jakým způsobem se tohle správně provádí?
Děkuji za radu.
-
Řekl bych, že většinou nejjednodušší způsob je nehardkódovat heslo do binárky, ale načíst konfiguraci z externího souboru. Tomu už se dají nastavit práva tak, jak je potřeba. Nevím ale, jestli to ve tvém případě jde udělat.
Jinak přímo s Postgresem zkušenost bohužel nemám, ale obecně by autentikátory neměly umět žrát hash hesla, protože je to bezpečnostní problém - pak útočníkovi stačí mít místo hesla jenom ten hash a nemusí ani nic lámat.
-
Pokud prográmek zkompiluju, heslo jde z binárky přečíst a to je problém.
keby slo len o pohlad volnym okom, mozte obfuskovat to heslo v zdrojovom kode :)
Existuje nějaký nástroj, který by uměl pracovat jenom s HASHem hesla v connection stringu namísto vepsaného hesla?
Nebo jakým způsobem se tohle správně provádí?
Skuste si obzriet pozriet subor pg_hba.conf a dokumentaciu k nemu. Mozno sa Vam tam nieco zazda.
-
To heslo můžete jenom lépe či hůře schovávat. Ale i kdyby tam byl jen hash hesla, pořád to bude znamenat, že k připojení k databází stačí znát hash hesla, takže kdo by ho zjistil, mohl by se k databázi připojit.
Tohle se dá opravdu bezpečně udělat jenom tak, že uživatel bude při startu aplikace zadávat jméno a heslo k databázi, každý uživatel bude mít v databázi svůj účet, a na úrovni databáze se bude kontrolovat přístup.
-
Tohle se dá opravdu bezpečně udělat jenom tak, že uživatel bude při startu aplikace zadávat jméno a heslo k databázi, každý uživatel bude mít v databázi svůj účet, a na úrovni databáze se bude kontrolovat přístup.
Jasne, ze nie :) staci povolit userovi v OS pod ktorym bezi aplikacia pristup do databazy.
-
Ahoj, v prvom rade treba uvazovat, ci naozaj chces mat hard-coded heslo, pretoze to ma velke dosledky, ak binarka unikne - heslo ani nebude treba ziskat na to, aby utocnik ziskal pristup k tvojej DB. Budes mat sancu v pripade utoku nahradit binarku novou s novym heslom?
Teraz k moznostiam:
1.) plaintext heslo + obfuskacia - najhorsia moznost ale marginalne lepsia ako cisty plaintext. Aby to malo nejaky zmysel, musis mat heslo, ktore je generovane nahodne (ziadne slovnikove slova alebo jednoducha kombinacia, proste nieco v style "mF0l1M4*6%uT") plus idealne aj obfuskovany kod. Odradi to beznych Ferkov uzivatelov aj vacsinu script kiddies.
2.) implementovat https://tools.ietf.org/html/rfc7677 a v Postgrese nastavit scram-sha-256 auth. Stale bude nejaky komponent hesla v kode,a le nebude zachytitelne po sieti.
3.) implementovat klientske SSL certifikaty kde CN bude obsahovat databazovy username a nemat heslo vobec.
4.) v pripade ak DB je na localhoste - nastavit autentifikaciu na peer a tym padom username v OS bude autentifikovany na rovnaky username v Postgrese.
-
Běžně se používají soubory načtené při startu aplikace (např. .env pro serverové). Šel bych touto cestou. Při instalaci si může aplikace vytvořit vlastní adresář/konfigurační soubory.
-
Jasne, ze nie :) staci povolit userovi v OS pod ktorym bezi aplikacia pristup do databazy.
To ovšem předpokládáte, že aplikace i databáze běží na stejném zařízení, a že databáze umožňuje přihlášení skrze OS. A pak je to pořád jenom tak, že se uživatel přihlásí do svého účtu v OS a tím je přístup chráněný.
To přihlášení jménem a heslem jsem uvedl jenom jako srozumitelný příklad pro tazatele. Jinak je samozřejmě úplně jedno, jakým způsobem přesně se uživatel přihlásí, zda to bude třeba USB token nebo otisk prstu – podstatné je, že se musí on sám nějak autentizovat vůči databázi. A databáze pak musí zajistit autorizaci.
-
Neco podobnyho jsem resil v Jave. Pokud jsi v korporatu a tvuj program pobezi na windows tak muzes pouzit SSPI, a OS ti poskytne kerberos ticket kterym se prihlasis do databaze.
To co ches je vlastne SSO a pro SSO potrebujes vyuzit nejakou stavajici infrastrukturu jako je AD, Kerberos, SAML, ...
-
len som citil potrebu nestastnika, co polozil uvodnu otazku upozornit, ze to ako ste to autoritativne a sirokospektralne sformulovali, je hlupost. Este by tomu mohol uverit :).
Samozrejme, nemusite to mat vsetko na jednom stroji na zbavenie sa problemu s heslom. Preto som pytajuceho upozornil na dokumentaciu, kde ma rozpisane moznosti. Je uz na nom, co sa mu infrastrukturne hodi.
Jasne, ze nie :) staci povolit userovi v OS pod ktorym bezi aplikacia pristup do databazy.
To ovšem předpokládáte, že aplikace i databáze běží na stejném zařízení, a že databáze umožňuje přihlášení skrze OS. A pak je to pořád jenom tak, že se uživatel přihlásí do svého účtu v OS a tím je přístup chráněný.
To přihlášení jménem a heslem jsem uvedl jenom jako srozumitelný příklad pro tazatele. Jinak je samozřejmě úplně jedno, jakým způsobem přesně se uživatel přihlásí, zda to bude třeba USB token nebo otisk prstu – podstatné je, že se musí on sám nějak autentizovat vůči databázi. A databáze pak musí zajistit autorizaci.
-
A) Pro uložení hesla je potřeba použít obecnou transobfuskační tříklíčovou polymonádní funkci.
B) Použít mozek a princip Good-Enough
Je to malý interní program?
Heslo proženeš funkcí XOR a uložíš ho reversibilně, ale nečitelně.
(Lze zjistit třeba debugováním, což IMHO nikdo nebude dělat.)
Je to částečně program?
Schovej to za webovou službu chráněnou SSL a token.
Prostě si polož základní otázky typu:
- je potřeba z databáze i číst?
- jsou tam zcizitelné věci?
- nelze v DB vytvořit VIEW a přes web REST ho publikovat
- pokud potřebuješ zapisovat, nestačí jen odeslat data? Z CRUD jen to C?
- bude narušena CIA triáda?
Pro interní použití může být xorované heslo dostatečně dobré.
https://www.tutorialspoint.com/cryptography_with_python/cryptography_with_python_xor_process.htm
Interní tool pro pár lidí: Xorované Heslo
Tool pro mnohem více lidí bez možnosti narušení CIA: https://pypi.org/project/aes-cipher/
Tool pro mnohem více lidí s možností narušení CIA: Uživatelské účty a přihlášení do databáze nebo SSO
Software: Webová služba s možností exportu dat
...
-
Děkuji vám za zamyšlení se a podnětné názory.
-
A) Pro uložení hesla je potřeba použít obecnou transobfuskační tříklíčovou polymonádní funkci.
B) Použít mozek a princip Good-Enough
Je to malý interní program?
Heslo proženeš funkcí XOR a uložíš ho reversibilně, ale nečitelně.
(Lze zjistit třeba debugováním, což IMHO nikdo nebude dělat.)
Je to částečně program?
Schovej to za webovou službu chráněnou SSL a token.
Prostě si polož základní otázky typu:
- je potřeba z databáze i číst?
- jsou tam zcizitelné věci?
- nelze v DB vytvořit VIEW a přes web REST ho publikovat
- pokud potřebuješ zapisovat, nestačí jen odeslat data? Z CRUD jen to C?
- bude narušena CIA triáda?
Pro interní použití může být xorované heslo dostatečně dobré.
https://www.tutorialspoint.com/cryptography_with_python/cryptography_with_python_xor_process.htm
Interní tool pro pár lidí: Xorované Heslo
Tool pro mnohem více lidí bez možnosti narušení CIA: https://pypi.org/project/aes-cipher/
Tool pro mnohem více lidí s možností narušení CIA: Uživatelské účty a přihlášení do databáze nebo SSO
Software: Webová služba s možností exportu dat
...
CPU děkuji za příspěvek, tohle je velmi použitelné a XOR v tomto případě bude postačovat.
Děkuji pěkně. :)
-
Ten zabudovaný db uživatel by neměl mí zbytečná práva do db. Budete mít méně problémů až to heslo praskne.
-
CPU děkuji za příspěvek, tohle je velmi použitelné a XOR v tomto případě bude postačovat.
Typický osud takového programu:
- Kvůli obfuskaci si lidi myslí že je to „good enough“ (zatímco když je někde - ideálně v konfiguráku, protože to přece nebudeš zakompilovávat do binárky - to heslo, tak je všem jasné, jak funguje řízení přístupu a na co si dávat pozor)
- Postupně zapomenou co tam je a není citlivé.
- Program se rozšíří i mimo původní účel a protože není jasně zdokumentované a vidět jak to funguje, tak nikoho nenapadne to řešit.
- Někdo přijde a „xor encryption“ crackne a je z toho průšvih.
Ty se tedy snažíš implementovat omezení, co může uživatel dělat s databází, tím, že mu dáš omezeného klienta, který si ale nese plná přístupová práva k databázi? Dochází ti, že i kdybys tu autentizaci nějak magicky vyřešil, stále uživatel může po navázání spojení program například zastavit v debugeru a volat libovolné funkce z té přibalené pgxx knihovny s libovolnými parametry?
-
Ježiš ::)
Ježiš ;D
Ježiš 8)
Chtěl jsem ti dát seznam toho, proč jsi vedle jako ta jedle, ale nebudu se namáhat.
neměl zbytečná práva do db... heslo praskne..
Rozhodně! To platí vždycky, protože "co kdyby", ale tak tragicky bych to s tím prasknutím neviděl, spousta mnohem horších čuňáren (Heslo napsané v plaintextu ve skriptu a podobně) nikdy nepraskla.
Taky bych byl pro SSO, ale SSO a řízení uživatelů je někdy nejen nevhodné, ale navíc i mimořádně zdlouhavé.
-
Tool pro mnohem více lidí bez možnosti narušení CIA: https://pypi.org/project/aes-cipher/
Reality check: dám si breakpoint na pgxx::connection a přečtu si jaké dostává parametry - jakým způsobem je program vymyslel je mi úplně jedno.
Na to tazatele určitě napadne, že tu funkci přejmenuje, aby nešla tak snadno najít. Na to já zareaguji tak, že program zastavím v okamžiku, kdy se začne ověřovat proti databázi a přečtu si stacktrace (všimněte si, že prezentovaný connection string má dost jasný a zjevný formát, takže půjde i třeba jednoduše grepnout v coredumpu programu). Na to tazatele napadne nějaké další geniální řešení.
A to jsme ještě ani nezabrousili do toho, jestli je ten protokol odolný proti MITM, případně jak složité je té knihovně vnutit vlastní certifikát a ten MITM si udělat.
Tazatel se brání proti „útočníkovi“ který dokáže na binárku programu spustit strings, spustit si vlastního postgresql klienta a se získanými údaji se připojit, ale současně je dostatečně neschopný na jednoduchou analýzu běžícího programu.
-
Musel bych ti bezpečnost vysvětlit od začátku a to zadarmo dělat nebudu.
-
Jeste bych upozornil, ze pokud tvurce dotazu chtel posilat hash, tak se zrejme bavi o md5 hashovani, coz je dira sama o sobe. Postgesql od 14/15 ma default scram-sha-256, takze zpusob overeni uzivatele je vyrazne zmenen a postup pro md5 tam jiz nefunguje.
-
Jak již bylo zmíněno, kdyby k autentizaci měl stačit hash hesla, pak by se ten hash vlastně stal heslem. Tudy cesta nevede.
Možná chcete mít nějakou embedded databázi, kterou budete dodávat přímo s aplikací, která by se zřejmě spouštěla a ukončovala zároveň s aplikací a která by se nepoužívala na nic jiného. To má lepší řešení než hardcodované heslo. Například se heslo může generovat náhodně a uložit do souboru (s vhodně omezeným oprávněním), případně na *NIXech by asi šlo nechat Postgres poslouchat jen na socketu, který by měl vhodně omezená oprávnění. Toto tahám z hlavy, možná by Google nasměroval i k jinému řešení.
-
Musel bych ti bezpečnost vysvětlit od začátku a to zadarmo dělat nebudu.
To by sis o tom musel nekde neco precist, ze?
Harcoded heslo je naprosto nejvetsi volovina kterou kdo muze udelat. Ve 100% pripadu to dopadne tak, ze nekdo to heslo zmeni, jednoduse proto, ze ty 3 pismenka uz neodpovidaji firemni policy, a pak bude resit, kde to ma nastavit ty aplikaci (pripadne ta aplikace proste jen vsem prestane fungovat).
Xorovat heslo, kdyz to za stejnou cenu muzu udelat dobre, je opravdu uzasnej napad ...
Takze, bud mam aplikaci, kterou pouzivaji uzivatele, a pak neresim aplikaci, ale toho uzivatele (to vubec neznamena, ze musi nekde zadavat nejaka hesla, treba si prevezmu jeho prihlaseni ze systemu).
Nebo mam nejakou servisu, pak resim autorizaci ty konkretni servisy, bez hesel.
-
Ahoj,
prosím, potřeboval bych poradit, jak se řeší situace, kdy do prográmku v c++ potřebuju zkompilovat hardcoded heslo pro připojení k (postgresql) databázi.
S použitím předpřipravené knihovny pgxx definuji connection string:
std::string connectionString = "host='server_ip_address' port='5432' dbname='database_name' user='username' password='Secret_12345'";
Pokud prográmek zkompiluju, heslo jde z binárky přečíst a to je problém.
Existuje nějaký nástroj, který by uměl pracovat jenom s HASHem hesla v connection stringu namísto vepsaného hesla?
Nebo jakým způsobem se tohle správně provádí?
Děkuji za radu.
Nenapsal jsi jestli tvoje aplikace pobezi na Windows anebo na Linuxu.
Pokud na Windows tak by doporucil jeste jednou se podivat na SSO, protoze AD udela hodne prace za tebe a rozbehat Kerberos autentizaci na PostgreSQL databazi je celkem jednoduchu.
Pokud to pobezi na Linuxu, tak bych doporucil aby tvoje aplikace mela SUID bit na "nobody". Aplikace s SUID bitem muze debugovat tak max. root. Beznej uzivatel kterej aplikaci spusti to bude mit mnohem tezsi se k heslu v aplikaci dostat.
-
Dost záleží na cílovém prostředí. V některých případech může SUID udělat svoje, ale uživatel nesmí mít možnost se dostat k binárce:
1. Musí mít oprávnění execute, nikoli read.
2. Nesmí mít binárku ke stažení.
3. Cokoli co zavání fyzickým přístupem k počítači, kde binárka běží, zavání průšvihem. Od čtení disku, bootu jiného OS, až po cold boot attack. Ano, vše lze nějak řešit, ale je potřeba na to myslet.
4. IIRC psaní aplikací, které počítají se SUID, je někdy trochu minové pole. Zkušenost nemám, ale rozhodně si to chce něco trochu předem nastudovat.
-
skus pozriet AWS Secret Manager a jeho implementaciu, podla mna najlepsie a najbezpecnejsie riesenie, tj. mimo ine aj automaticka zmena hesla po definovanom casovom obdobi