Wir speichern alle unsere Anwendungs- und Datenbankpasswörter im Klartext in der Quellcodeverwaltung. Wir tun dies, da unser Build/Deploy-Prozess die erforderlichen Konfigurationsdateien generiert und auch tatsächlich Deploys durchführt, die diese Kennwörter erfordern (dh, das Ausführen von sql für eine Datenbank erfordert die Anmeldung an der Datenbank mit gültigen Anmeldeinformationen). Hat jemand eine ähnliche Anforderung, wo Sie diese Art von Funktionalität implementieren konnten, während Sie die Kennwörter nicht im Klartext speichern?Passwortspeicher in der Quellcodeverwaltung
Antwort
Wenn Sie planen, den gesamten Code und die Konfigurationsinformationen zu speichern, um ein Produktionssystem direkt von der Versionskontrolle und ohne menschliches Eingreifen zu betreiben, sind Sie geschraubt. Warum? Dies alles ist nur eine Verletzung des alten Sicherheitsaxioms "schreibe niemals dein Passwort ab". Machen wir einen Beweis durch Negation.
Zuerst schneiden, haben Sie Klartext Passwörter in den Konfigurationsdateien. Das ist nicht gut, sie können von jedem gelesen werden, der die Dateien sehen kann.
Zweiter Schnitt, wir werden die Passwörter verschlüsseln! Jetzt muss der Code jedoch wissen, wie die Kennwörter zu entschlüsseln sind. Daher müssen Sie den Entschlüsselungsschlüssel irgendwo in den Code einfügen. Das Problem wurde gerade auf ein Niveau gedrückt.
Wie wäre es mit öffentlichen/privaten Schlüsseln? Das gleiche Problem wie die Passwörter, der Schlüssel muss im Code sein.
Die Verwendung einer lokalen Konfigurationsdatei, die nicht in der Versionskontrolle gespeichert ist, setzt das Kennwort und die Mittel zum Lesen, wenn sie verschlüsselt sind, auf der Festplatte und für einen Angreifer zur Verfügung. Sie können die Dinge ein wenig verhärten, indem Sie sicherstellen, dass die Berechtigungen der Konfigurationsdatei sehr begrenzt sind, aber wenn die Box rooted ist, sind Sie geschraubt.
Das bringt uns dazu, warum Passwörter auf der Festplatte ist eine schlechte Idee. Es verstößt gegen das Konzept einer Sicherheitsfirewall. Ein kompromittierter Computer mit Anmeldeinformationen bedeutet, dass andere Computer kompromittiert werden. Eine schlecht gewartete Maschine kann Ihre gesamte Organisation zerstören.
Irgendwann wird ein Mensch das entscheidende Geheimnis injizieren müssen, um die Vertrauenskette in Gang zu setzen. Was Sie tun könnten, ist, alle Geheimnisse im Code zu verschlüsseln und dann, wenn das System hochfährt, müssen Sie manuell den Schlüssel eingeben, um alle Kennwörter zu entschlüsseln. Dies ist wie das Master-Passwort-System, das Firefox verwendet. Es ist offen für Missbrauch, da, sobald ein Passwort kompromittiert ist, viele Systeme kompromittiert werden, aber es ist bequem und wahrscheinlich sicherer, da sich Benutzer nur an ein Passwort erinnern müssen und es weniger wahrscheinlich ist, es aufzuschreiben.
Der letzte Schritt ist sicherzustellen, dass, sollte die Login-Information kompromittiert werden (und Sie sollten immer davon ausgehen, dass es sein wird), dass A) der Angreifer nicht viel damit machen kann und B) Sie die kompromittierten schnell herunterfahren können Konten. Erstere bedeutet, den Konten nur so viel Zugang zu geben, wie sie benötigen. Wenn Ihr Programm beispielsweise nur aus einer Datenbank lesen muss, muss es sich bei einem Konto anmelden, das auf SELECT beschränkt ist. Im Allgemeinen entfernen Sie alle Zugriffe und fügen sie dann nur bei Bedarf hinzu. Seien Sie geizig über die Rechte zu löschen, damit Sie einen Besuch von little Bobby Tables bekommen.
Letzteres bedeutet, dass Sie jedem Benutzer/jeder Organisation/jedem Projekt eine eigene Anmeldung geben, auch wenn sie dieselben Rechte und Berechtigungen haben und auf dieselben Daten zugreifen können. Es ist ein bisschen mühsamer, aber es bedeutet, dass, wenn ein System kompromittiert ist, Sie dieses Konto schnell herunterfahren können, ohne Ihr gesamtes Unternehmen herunterzufahren.
"Aber sollte die Box verwurzelt sein, bist du verrückt" Ich bin verwirrt - gibt es Sicherheitsprotokolle, wo das Verwurzeln Teil des Bedrohungsmodells ist? Ich kann mir nicht vorstellen, wie Sie sich gegen einen Root-Angriff wehren könnten. – christianbundy
@christianbundy Wenn ein System durchdrungen wird, möchten Sie sicherstellen, dass es nicht in ein anderes System eindringen kann. In diesem Fall kann der Angreifer nun auf Ihre Datenbank zugreifen, wenn Sie Ihr Datenbankkennwort auf der Festplatte speichern und ein einzelner Computer durchsucht wird. Ich gehe davon aus, dass der Anwendungscode und die Datenbank auf verschiedenen Servern laufen. Auch müssen Sie nicht root sein, um die Anwendungskonfigurationsdatei zu lesen, Sie müssen nur der Anwendungsbenutzer sein, was viel einfacher ist. Sie brauchen das nicht einmal, Sie müssen nur die App täuschen, damit Sie ihre Konfigurationsdatei sehen können. – Schwern
Wenn Ihr System durchdrungen ist, wie kann der Angreifer das Passwort nicht lesen? Das Speichern im Dateisystem ist einfach über FS I/O zu lesen, das Speichern in einer Umgebung ist einfach über/proc/zu lesen und das Speichern im RAM ist einfach über '/ dev/mem' zu lesen. Welche Alternative schlagen Sie vor? – christianbundy
Wenn Sie in C arbeiten, können Sie in einem Array von Zeichen speichern und die Zeichen als Dezimalstellen eingeben. Ich bin mir nicht sicher, ob das die Strings bricht oder nicht, aber es könnte helfen, etwas von diesem Problem zu lösen.
char pass[]={72, 101, 108, 108, 111};
Boshfpngvba qbrf abg cebivqr frphevgl! – Schwern
eewwwwwwwwwwwww –
Kennwörter in verschlüsselter Form speichern. Schreiben Sie eine benutzerdefinierte Routine, die die Kennwörter entschlüsselt und die Konfigurationsdateien zum Zeitpunkt der Erstellung aktualisiert. Dies kann leicht mit dem Build-Tool wie Ant integriert werden.
Also, wo Sie den Entschlüsselungsschlüssel? – Schwern
Sie haben die Sprache nicht erwähnen, ist so hier eine vb.net Lösung, die wir verwenden:
Imports System.Web.Security
Imports System.Security.Cryptography
Imports System.Text
Imports Microsoft.Win32
Public Class myCrypt
Private myKey As String = "somekeyhere"
Private cryptDES3 As New TripleDESCryptoServiceProvider()
Private cryptMD5Hash As New MD5CryptoServiceProvider()
Private Function Decrypt(ByVal myString As String) As String
cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey))
cryptDES3.Mode = CipherMode.ECB
Dim desdencrypt As ICryptoTransform = cryptDES3.CreateDecryptor()
Dim buff() As Byte = Convert.FromBase64String(myString)
Decrypt = ASCIIEncoding.ASCII.GetString(desdencrypt.TransformFinalBlock(buff, 0, buff.Length))
End Function
Private Function Encrypt(ByVal myString As String) As String
cryptDES3.Key = cryptMD5Hash.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey))
cryptDES3.Mode = CipherMode.ECB
Dim desdencrypt As ICryptoTransform = cryptDES3.CreateEncryptor()
Dim MyASCIIEncoding = New ASCIIEncoding()
Dim buff() As Byte = ASCIIEncoding.ASCII.GetBytes(myString)
Encrypt = Convert.ToBase64String(desdencrypt.TransformFinalBlock(buff, 0, buff.Length))
End Function
End Class
Unser Build/Deploy-Prozess ist ANT. Unser Anwendungscode ist Java. –
MD5? TripleDES? Verdammt, MD5 ist bereits kompromittiert und 3DES ist auf dem Weg nach draußen. Verwenden Sie AES und SHA256. Noch wichtiger, nachdem Sie die Anmeldedaten verschlüsselt haben, wo legen Sie den Entschlüsselungsschlüssel ab? Hühnerei. – Schwern
Ich gehe davon aus das Ziel ist, dass Sie nicht in Ihrem Unternehmen privaten Passwörter verschlüsselt zur Verfügung, sein wollen , entschlüsselt oder auf andere Weise an jeden, der ansonsten Zugriff auf den Rest der Quelle erhalten sollte.
Hier ist, wie ich es mache. Ich habe dieses Muster von TikiWiki kopiert, was auch das tut.
in einer Datei, die normalerweise Passwörter enthält, setzen Sie sie auf Dummy-Werte, egal was. Stellen Sie es auf was auch immer Ihr Kunde sehen sollte. Setzen Sie einen Kommentar in der Nähe für Entwickler, um diese Datei in Ruhe zu lassen und eine zweite Datei zu ändern.
In der zweiten Datei, die erstellt wird, wenn sie nicht da ist, legen Sie die tatsächlichen Passwörter. sorge dafür, dass diese Datei von der ersten Datei eingeschlossen, importiert oder importiert wird.
Sorgen Sie dafür, dass Ihre Quellcodeverwaltung diese Datei ignoriert. Konnte in etwa so aussehen:
# in .gitignore
localsettings.py
# in settings.py
## Alter this value to log into the snack machine:
## developers: DON'T alter this, instead alter 'localsettings.py'
SECRET_VALUE = ""
try:
from localsettings import *
except:
pass
# in localsettings.py
SECRET_VALUE = "vi>emacs"
Ich habe Systeme gebaut, bei denen Datenbank-Benutzer-ID/Passwort-Paare nicht Teil des Code-Drop sind. Der Schlüssel besteht darin, einen standortspezifischen Konfigurationsmechanismus einzurichten. Dann können Sie solche Informationen auf die betreffende Box setzen, ohne dass sie Teil der Codebasis sind.
Es gibt einen Bonus: Sie können nicht nur verschiedene Passwörter für verschiedene Code-Drops, sondern auch für verschiedene Entwickler haben. :-)
Guter Punkt. Ein Szenario, das wir haben, ist, wo unser Deploy-Skript sql gegen eine db ausführt (könnte dev, qa, prod usw. sein). All dies geschieht auf einem einzigen Bereitstellungsserver. Nicht sicher, wie diese Lösung in diesem Fall implementiert wird. –
Die Vorgehensweise dafür besteht darin, dass das Skript sql-update auf dem Endzielserver ausgeführt wird. Dann kann es die lokale Konfiguration verwenden, um die Datenbank zu finden. :-) – staticsan
Setzen Sie die Kennwörter in Benutzerumgebungsvariablen o/s. –