Ist es sicher, Passwörter als Umgebungsvariablen (und nicht als Klartext) in Konfigurationsdateien zu speichern?

109

Ich arbeite an einigen Apps in Rails, Django (und ein bisschen PHP), und eines der Dinge, die ich in einigen von ihnen angefangen habe, ist das Speichern von Datenbanken und anderen Passwörtern als Umgebungsvariablen anstelle von einfachem Text in bestimmten Konfigurationsdateien ( oder in settings.py für Django-Apps).

Als er dies mit einem meiner Mitarbeiter diskutierte, schlug er vor, dass dies eine schlechte Praxis sei - dass dies möglicherweise nicht so sicher ist, wie es auf den ersten Blick scheinen mag.

Ich würde gerne wissen, ob dies eine sichere Praxis ist. Ist es sicherer, Passwörter als einfachen Text in diesen Dateien zu speichern (stellen Sie natürlich sicher, dass diese Dateien nicht in öffentlichen Repos oder Ähnlichem verbleiben)?

Jay
quelle

Antworten:

45

Auf einer theoretischeren Ebene neige ich dazu, über Sicherheitsstufen auf folgende Weise nachzudenken (in der Reihenfolge zunehmender Stärke):

  • Keine Sicherheit. Klartext. Jeder, der weiß, wo er suchen muss, kann auf die Daten zugreifen.
  • Sicherheit durch Verschleierung. Sie speichern die Daten (Klartext) an einem schwierigen Ort wie einer Umgebungsvariablen oder in einer Datei, die wie eine Konfigurationsdatei aussehen soll. Ein Angreifer wird irgendwann herausfinden, was los ist, oder darüber stolpern.
  • Sicherheit durch Verschlüsselung, die trivial zu brechen ist (denken Sie an Caesar-Chiffre!).
  • Sicherheit durch Verschlüsselung, die mit einigem Aufwand unterbrochen werden kann.
  • Sicherheit durch Verschlüsselung, die bei aktueller Hardware unpraktisch ist.
  • Das sicherste System ist eines, das niemand benutzen kann! :) :)

Umgebungsvariablen sind mehr sicherer als Klartext - Dateien, weil sie flüchtige / Einweg, nicht gespeichert; Wenn Sie also nur eine lokale Umgebungsvariable wie "set pwd = Whatever" festlegen und dann das Skript mit etwas ausführen, das Ihre Befehlsshell am Ende des Skripts verlässt, ist die Variable nicht mehr vorhanden. Ihr Fall fällt in die ersten beiden, was ich als ziemlich unsicher bezeichnen würde. Wenn Sie dies tun würden, würde ich nicht empfehlen, die Bereitstellung außerhalb Ihres unmittelbaren Intranets / Heimnetzwerks und dann nur zu Testzwecken durchzuführen.

John Carter
quelle
Dies hängt vom Betriebssystem ab. Im besten Fall sind Umgebungsvariablen genauso anfällig wie Klartextdateien, aber wahrscheinlich schlechter. Mit Klartextdateien können Sie die Leseberechtigungen für die Dateien / Verzeichnisse festlegen, um sie zu schützen. IIRC für Umgebungsvariablen leben sie im Speicherbereich für den Shell-Prozess, sodass ein unternehmungslustiger Cracker diesen Bereich nach ihnen durchsuchen kann.
John Carter
Warten Sie eine Minute: Wenn Sie die Anmeldeinformationen in einer Umgebungsvariablen speichern, müssen sie zuerst dort ankommen. Entweder von Hand oder per Skript. Um den Start Ihrer Software zu automatisieren, würde ich ein Skript empfehlen. Aber raten Sie mal, dann müssen Sie sie trotzdem in einer Konfigurationsdatei (für env-Variablen) speichern. Sofern Sie keine Werte für env-Variablen manuell bereitstellen, kann ich keinen Sicherheitsunterschied zu Konfigurationsdateien feststellen.
Mathe
59

Wie bereits erwähnt, bieten beide Methoden keine zusätzliche "Sicherheitsebene", sobald Ihr System gefährdet ist. Ich glaube, dass einer der stärksten Gründe für die Bevorzugung von Umgebungsvariablen die Versionskontrolle ist : Ich habe gesehen, dass viel zu viele Datenbankkonfigurationen usw. versehentlich im Versionskontrollsystem wie GIT gespeichert wurden, als dass jeder andere Entwickler sie sehen könnte (und whoops! Es ist passiert) ich auch ...).

Wenn Sie Ihre Passwörter nicht in Dateien speichern, können sie nicht im Versionskontrollsystem gespeichert werden.

Emrass
quelle
6
Eine recht vernünftige Alternative zu nicht geheimen Konfigurationseinstellungen in der Versionskontrolle zu speichern ist sie in einem Repository der Versionskontrolle zu speichern oder vorher getrennt für den Code aus dem Repository.
Kenny Evitt
1
@KennyEvitt, das immer noch ungesicherte Klartextkennwörter an einem freigegebenen Speicherort hinterlässt, den jeder mit Zugriff auf das Repository finden kann, und keine Möglichkeit hat, zu verfolgen, wer darauf zugegriffen hat.
FistOfFury
2
@FistOfFury Sicher, jeder mit Zugriff auf das Repository ... kann auf das Repository zugreifen. Das Speichern von Geheimnissen in einem separaten Repository dient genau dazu, den Zugriff auf diese Geheimnisse anders als mit dem Code selbst zu steuern. Repositorys können jedoch gesichert werden, z. B. können Sie die Geheimnisse verschlüsselt am "freigegebenen Speicherort" speichern. Sie können sogar Informationen zum Zugriff auf das Repository am freigegebenen Speicherort verfolgen. Wenn Sie jedoch jedem erlauben, auf Informationen zuzugreifen, bedeutet dies natürlich, dass er diese Informationen kopieren und somit jederzeit ohne Einschränkung oder Nachverfolgung darauf zugreifen kann.
Kenny Evitt
2
Ein guter Grund, eine Konfigurationsverwaltungslösung zu verwenden, mit der Sie verschlüsselte Geheimnisse speichern und diese beim Rendern in Konfigurationsvorlagen ersetzen können. Chefkoch hat Datentaschen verschlüsselt, Ansible hat Tresore usw.
Brian Cline
1
Dies wird als Privileged Access Management bezeichnet, bei dem Geheimnisse in einem zentralen PAM-Tresor mit umfassenden Zugriffskontrollen gespeichert werden. Gartner listet einige solcher Produkte auf .
Amit Naidu
44

Jedes Mal, wenn Sie ein Passwort speichern müssen, ist es unsicher. Zeitraum. Es gibt keine Möglichkeit, ein unverschlüsseltes Passwort sicher zu speichern. Welche Umgebungsvariablen im Vergleich zu Konfigurationsdateien "sicherer" sind, ist möglicherweise umstritten. IMHO, wenn Ihr System kompromittiert ist, spielt es keine Rolle, wo es gespeichert ist, ein fleißiger Hacker kann es aufspüren.

Chris Pratt
quelle
12
Für Umgebungsvariablen erwarte ich hier Unix ... Umgebungsvariablen sind viel weniger sicher als Dateien. Jeder kann die Umgebung eines laufenden Prozesses überprüfen, aber Dateien können mindestens ACLs haben.
Vatine
11
Da der Entwickler diese Passwörter speichern muss, ist dies keine besonders hilfreiche Antwort. Wo schlagen Sie vor, dass er sie aufbewahrt?
Peter Nixey
2
@Vatine Orte, die Umgebungsvariablen verfügbar machen, haben ebenfalls Berechtigungen. Versuchen Sie es cat /proc/1/environzum Beispiel.
Chris Down
4
@Vatine Wirklich? Ich sehe keine Umgebung für Prozesse, die mir nicht gehören ps axe. strace -e open ps axezeigt, dass es diese Informationen von erhält /proc/[pid]/environ, die die Durchsetzung von Berechtigungen haben (daher eine Reihe von open("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied)).
Chris Down
4
Huh. Schauen Sie sich das an, ein Problem wurde endlich behoben (früher war es ein Problem ps, das Ihnen gerne die Umgebung von so ziemlich allem zeigen würde).
Vatine
28

Es tut mir leid, dass ich nicht genug Repräsentanten hatte, um einen Kommentar abzugeben, aber ich wollte auch hinzufügen, dass Ihre Shell dieses Kennwort möglicherweise auch im Befehlsverlauf erfasst, wenn Sie nicht vorsichtig sind. So etwas wie $ pwd=mypassword my_progmanuell auszuführen ist also nicht so kurzlebig, wie Sie es sich erhofft haben.

Brianclements
quelle
21
Wenn Sie dem gesamten "env var + Befehl" ein Leerzeichen
voranstellen
danke @shadi. Lerne jeden Tag etwas Neues! Ich frage mich, ob das Shell-spezifisch / einfach auszuschalten ist oder ob es etwas ist, das man ziemlich konsequent erwarten kann.
Brianclements
4
Eine andere Möglichkeit ist die Verwendung, read -s MY_PASS_VARdie sowohl vor Shell-History-Suchen als auch vor Schulter-Surfern schützt.
MatrixManAtYrService
3
@brianclements Ich möchte hinzufügen, dass das Präfixieren des Befehls mit einem Leerzeichen nur funktioniert, wenn die aktuelle Shell HISTCONTROLauf ignorespaceoder gesetzt ist ignoreboth, so dass sie technisch ein- und ausgeschaltet werden kann.
Moses
13

Ich denke, wenn möglich, sollten Sie Ihre Anmeldeinformationen in einer gitignored Datei und nicht als Umgebungsvariablen speichern.

Wenn Sie Anmeldeinformationen in ENV-Variablen (Umgebungsvariablen) im Vergleich zu einer Datei speichern, sollten Sie berücksichtigen, dass ENV-Variablen sehr einfach von jeder von Ihnen verwendeten Bibliothek oder Abhängigkeit überprüft werden können.

Dies kann böswillig geschehen oder nicht. Zum Beispiel könnte ein Bibliotheksautor Stack-Traces und die ENV-Variablen zum Debuggen per E-Mail an sich selbst senden (keine bewährte Methode, aber möglich).

Wenn sich Ihre Anmeldeinformationen in einer Datei befinden, ist es viel schwieriger, sie abzurufen.

Denken Sie insbesondere an eine npm im Knoten. Für eine npm ist es eine einfache Sache, Ihre Anmeldeinformationen zu überprüfen, wenn sie in der ENV enthalten sind process.ENV. Wenn sie sich andererseits in einer Datei befinden, ist das viel mehr Arbeit.

Ob Ihre Anmeldeinformationsdatei versioniert ist oder nicht, ist eine separate Frage. Nicht die Versionskontrolle Ihrer Anmeldeinformationsdatei setzt sie weniger Personen aus. Es ist nicht erforderlich, dass alle Entwickler die Produktionsdaten kennen. Da dies dem Prinzip der geringsten Privilegien entspricht, würde ich empfehlen, dass git Ihre Anmeldeinformationsdatei ignoriert.

Peter Ajtai
quelle
5
+1 für "Ein Bibliotheksautor könnte Stapelspuren und die ENV-Variablen zum Debuggen per E-Mail an sich selbst senden". Ich habe nie über dieses Szenario nachgedacht.
Netishix
6

Dies hängt von Ihrem Bedrohungsmodell ab.

Versuchen Sie zu verhindern, dass Ihre Benutzer Kennwörter über ihre Dateisysteme verteilen, in denen sie wahrscheinlich vergessen und misshandelt werden? Wenn ja, dann ja, da Umgebungsvariablen weniger persistent sind als Dateien.

Versuchen Sie, sich gegen etwas Bösartiges zu schützen, das direkt auf Ihr Programm abzielt? Wenn ja, dann nein, da Umgebungsvariablen nicht die gleiche Zugriffssteuerung haben wie Dateien.

Persönlich denke ich, dass fahrlässige Benutzer häufiger sind als motivierte Gegner, daher würde ich mich für den Ansatz der Umgebungsvariablen entscheiden.

MatrixManAtYrService
quelle