it-swarm.com.de

Wie kann ich vermeiden, das Datenbankkennwort in ein Perl-Skript einzufügen?

Ich habe ein überarbeitetes Perl-Skript, das eine Verbindung zu unserer Datenbank herstellt und verschiedene Arten von Suchvorgängen und Integritätsprüfungen durchführt. Das ursprüngliche Skript wurde vor langer Zeit von jemandem geschrieben. Meine Aufgabe ist es, einige Änderungen daran vorzunehmen. Aber ich mag es wirklich nicht, auf die username="foo", password="bar" Parameter, die dort für den Zugriff auf die Datenbank fest codiert sind.

Es muss einen sichereren Weg geben, dies zu tun. Alles, was ich mir jetzt vorstellen kann, ist, den Cron-Job zu kommentieren, die Zeile im Skript mit dem Kennwort zu löschen und ein Brainstorming darüber durchzuführen, wie dies sicherer gemacht werden kann. In der Zwischenzeit müssen die Dinge, die das Skript tut, von Hand erledigt werden.

Irgendwelche Ideen?

23
Luke Sheppard

Die Standardmethode besteht darin, die Anmeldeinformationen in eine Konfigurationsdatei einzufügen und zu versuchen, die Konfigurationsdatei vor einer besseren Lesbarkeit als die Perl-Datei zu schützen. Dies bietet eine moderate Erhöhung der Sicherheit; Beispielsweise befindet sich der Code möglicherweise in der Quellcodeverwaltung und ist für Entwickler zugänglich. Die Konfigurationsdatei wäre dies nicht. Der Code muss sich im CGI-Stammverzeichnis des Webservers befinden und unter bestimmten Fehlkonfigurationen möglicherweise herunterladbar sein. Die Konfigurationsdatei muss dies nicht sein.

Der ehrgeizige Weg besteht darin, die Anmeldeinformationen reversibel zu verschlüsseln und in eine Konfigurationsdatei zu kopieren. Natürlich kann alles, was reversibel verschlüsselt ist, entschlüsselt werden. Die BladeLogic-Anwendung hat dies getan, und es war für mich trivial (<1 Tag), ihre Java genug) zu dekompilieren, um die Funktion zum Entschlüsseln von Anmeldeinformationen herauszufinden und sie zu meiner Zufriedenheit zu entschlüsseln Keine Marke gegen sie, das ist nur der Name des reversibel verschlüsselten Spiels.

Eine weitere Option ist die Verwendung der betriebssystembasierten Autorisierung in Verbindung mit streng begrenzten Datenbankbeschränkungen. Beschränken Sie beispielsweise den Zugriff des Datenbankclientbenutzers auf eine Reihe gespeicherter Prozeduren, um das Missbrauchspotenzial zu begrenzen, und ermöglichen Sie diesem Benutzer den Zugriff auf die Datenbank ohne Kennwort. Dies funktioniert nicht, wenn Sie Client-Server über das Netzwerk ausführen, wodurch die Häufigkeit begrenzt wird. Außerdem neigen die Leute dazu, den "passwortlosen" Zugriff von Betriebssystembenutzern schief zu betrachten, als wenn sie das Passwort wohl oder übel aufschreiben. Es ist nicht ganz logisch, aber es gibt Standards, die besagen, dass alle Datenbankbenutzer Kennwörter haben müssen.

24
gowenfawr

Ich übergebe das Kennwort häufig in einer Umgebungsvariablen an das Skript, sodass das Skript keinen Zugriff auf den sicheren Speicherort haben muss, der das Kennwort enthält.

PASSWORD=`cat passwd_file`  Perl_script.pl

dann liest das Skript das Passwort

my $password = $ENV{'PASSWORD'}

bonuspunkte, wenn das Perl-Skript Berechtigungen verliert

8
Arthur Ulfeldt

Wie andere bereits gesagt haben, legen Sie die Anmeldeinformationen in einer separaten Datei ab, die vom Skript geladen wird. Zu den Risiken, das Passwort im Skript zu haben, gehört, dass es dem Schulter-Surfen ausgesetzt ist, in Revisionskontrollsystemen oder Konfigurationsmanagementsystemen festgeschrieben und weit über das hinaus verteilt wird, was versehentlich sein sollte, versehentlich an einen anderen Ort kopiert wird, wenn ein Teil des Codes wiederverwendet wird usw.

Die Anmeldeinformationsdatei sollte über die erforderlichen Mindestberechtigungen verfügen. Es sollte möglicherweise nicht von Konfigurationsmanagementsystemen aufgenommen oder anders behandelt werden.

Wenn verfügbar, sollten Sie eine Betriebssystemfunktion verwenden, die den Zugriff auf die Anmeldeinformationsdatei über die Berechtigungen hinaus weiter einschränkt. Beispielsweise kann AppArmor oder SELinux unter Linux den Zugriff auf die Anmeldeinformationsdatei auf das eine Skript beschränken, das sie benötigt. Dies schützt nur vor einem Angreifer, der die Kontrolle über das legitime Skript nicht übernehmen kann. Stellen Sie daher sicher, dass das legitime Skript nicht dem Benutzer gehört, der es ausführt (dies ist eine allgemeine Empfehlung: Sie dürfen keine ausführbaren Programme haben, die dem Benutzer gehören, der sie ausführt ).

Der Konsens scheint zu sein:

  1. Das Kennwort sollte sich in einer separaten Datei befinden, die nicht Teil der Versionskontrolle ist, und mit Berechtigungen geschützt sein, die restriktiver sind als die des Skripts.
  2. Das Verschlüsseln des gespeicherten Passworts ist Zeitverschwendung, da das Skript das Passwort ohnehin entschlüsseln muss.

Aber ich denke darüber nach, ein drittes Steuerelement hinzuzufügen: Zeitbasierte (zeitliche) Zugriffssteuerung könnte auch hier ein bisschen helfen. Wenn Sie die Zeitspanne begrenzen, in der das Klartextkennwort für Benutzer mit niedrigeren Berechtigungen verfügbar ist, wird eine weitere (wenn auch kleine) Ebene der Zugriffskontrolle zwischen dem Kennwort und einem lokalen Angreifer hinzugefügt.

Meine Idee ist, dass root die Passwortdatei besitzt, die auf Modus 04 gesetzt ist. Und dann haben Sie einen Root-Cronjob, der ein chmod 0404 für die Kennwortdatei ausführt, kurz vor dem Cronjob mit den niedrigeren Berechtigungen, der das Skript ausführt. In einem bestimmten Intervall später (hoffentlich nachdem das Skript ausgeführt wurde) führt ein zweiter Root-Cronjob einen chmod 0400 für die Kennwortdatei aus. Dies alles setzt voraus, dass das Skript nur das Passwort für einige Zeiträume benötigt, die kürzer als immer sind. Ihre Gedanken zu diesem Schema?

2
Luke Sheppard

Wäre dies eine angemessene Lösung:

  1. Das Passwort wird in einem kompilierten C/C++ - Programm gespeichert, das wie folgt verschleiert ist: char password [100]; Passwort [0] = 'a'; Passwort [1] = 'b'; Passwort [2] = 'c'; Passwort [3] = '\ 0';

Oder eine andere Art, das Passwort zu verschleiern. (Das Passwort sollte nicht verfügbar sein, wenn "Strings" in der ausführbaren Datei ausgeführt werden.)

  1. Das C/C++ - Programm gibt das Kennwort nur an vertrauenswürdige, registrierte Skripte zurück: A. Holen Sie sich ppid und überprüfen Sie/proc // cmdline,/proc // comm usw. B. Holen Sie sich den Inode des Anruferskripts und vergleichen Sie ihn mit der registrierten Identität, um dies sicherzustellen Das Skript wurde nicht geändert.

Ich mag es, Konfigurationen in ~/config/appname und eine generische Konfiguration für meine lokale MySQL-Verbindung (oder eine andere). Wenn Sie Ihrem Zuhause keine X-Berechtigung erteilen und die App als anderer Benutzer ausführen möchten, haben Sie irgendwo einen Standardkonfigurationsordner. Ich mache das, damit ich nicht versehentlich Passwörter oder Benutzernamen an andere Programmierer verpacke oder weitergebe. Ich denke nicht, dass es eine große Sache ist, aber mein Chef ist ein Sicherheitsfreak und es ist eine gute Angewohnheit, besonders wenn er etwas im Web veröffentlicht.

Es ist ratsam, einen Standard-Oneliner oder Twoliner für Ihre Konfigurationsdateien zu schreiben und diese in alle neuen Skripte, die Sie schreiben, zu kopieren/einzufügen

0
user5575

Dies ist, was ich für ein Skript plane, das eine Verbindung zu einer entfernten Datenbank herstellt. Es sind 2 Server erforderlich, um den Schlüssel getrennt vom verschlüsselten Wert zu speichern.

  1. Erstellen Sie auf Server 2 (wo der Schlüssel gespeichert wird) ein Skript, das einen Schlüsselparameter akzeptiert und lokal speichert.
  2. Erstellen Sie auf Server 1 (wo das Skript gespeichert ist) ein Skript, das die Verbindungszeichenfolge (Host, Datenbankname, Benutzername, Kennwort) als Parameter akzeptiert und einen zufälligen Schlüssel zum Verschlüsseln der Verbindungszeichenfolge generiert. Wir speichern die verschlüsselte Zeichenfolge lokal, hashen den Schlüssel und speichern sie lokal. Anschließend senden wir den Schlüssel (über SSL) an Server 2. Dieses Skript muss manuell mit der tatsächlichen Verbindungszeichenfolge ausgeführt werden, um sie zu initialisieren, und kann erneut ausgeführt werden Setzen Sie den Schlüssel zurück, wenn der zweite Server irgendwie kompromittiert wird.
  3. Auf Server 1 Richten Sie das ursprüngliche Skript so ein, dass ein Schlüsselparameter akzeptiert wird, überprüfen Sie den Schlüssel anhand des gespeicherten Hashs und verwenden Sie den Schlüssel zum Entschlüsseln der verschlüsselten Verbindungszeichenfolge.
  4. Auf Server 2 Richten Sie einen cURL-Aufruf für das Skript auf Server 1 (über SSL) ein, der den Schlüssel sendet und das Skript ausführt. Dies kann auf cron eingerichtet werden oder wie auch immer Sie es ausführen möchten.
0
knsheely