2010-09-07 3 views
5

Ich bin kein Java-Entwickler, aber mein Kunde hat einen angeheuert, um einige JAR-Dateien auf ihrer Website zu aktualisieren. Zuvor haben wir den bestehenden Code geprüft und eine Reihe von Sicherheitslücken gefunden. Eine der Lösungen, mit denen wir die Dateien sicherer machen, besteht darin, einen neuen Datenbankbenutzer mit schreibgeschütztem Zugriff auf die Datenbank und nur für die Tabellen zu erstellen, für die die JAR-Dateien benötigt werden. Ich fand dann heraus, dass sie diese Anmeldeinformationen neben den JAR-Dateien in reinen Textdateien speichern, nur eine fundierte Vermutung von der breiten Öffentlichkeit. Und schließlich fordern sie heute viel lockere Datenbankprivilegien, aber ich denke nicht, dass sie versteht, dass sie sie wirklich für eine richtig geschriebene JAR-Datei nicht brauchen sollte.Wie werden sichere Datenbankverbindungen normalerweise in JAR-Dateien implementiert?

Wie auch immer, ich bin ziemlich sicher, dass dieser Entwickler keine Sicherheitslücke kennen würde, wenn er sie auf der Rückseite biss. Und ich weiß nicht genug über Java/JAR-Dateien, um sie richtig zu beraten, was sie tun sollte, nur genug über infosec, um ihr zu sagen, was sie nicht tun sollte tun.

Was sind die typischen Sicherheitsaspekte beim Schreiben einer verteilten JAR-Datei, die eine Verbindung zu einer entfernten MySQL-Datenbank herstellt? Gibt es eine Standardmethode zum Verschlüsseln der Verbindungsdetails (Benutzername und/oder Passwort)? IIRC, sind keine .jar-Dateien gerade verherrlichte ZIP-Archive, und konnte deshalb niemand die Datei entpacken und die Verbindungsdetails im Quellcode einsehen? Gibt es eine Möglichkeit, den JAR-Dateiinhalt zu verschlüsseln?


UPDATE: Ich erhielt die folgende Klarstellung vom Entwickler. Klingt das richtig?

Alle Klassen in der JAR-Datei sind verschlüsselt. Ich habe immer alle Klassendateien verschlüsselt, bevor ich sie in einer JAR-Datei archiviere. Wenn Sie ein [redacted] jar öffnen, sehen Sie nur verschlüsselten Code. Es besteht also keine Möglichkeit für einen Benutzer, den Quellcode durch Dekompilieren der Klasse anzuzeigen. Die Klassen verwenden jdbc, um eine Verbindung zur db herzustellen, die Suche muss mit der Datenbank verbunden sein, um sqls ausführen zu können. Diese sqls befinden sich in den verschlüsselten casees in der jar-Datei.

Als ich Sie nach der Verschlüsselung des DB-Passworts fragte, meinte ich, was Sie unten sagen. Wir werden einen Verschlüsselungscode in Java schreiben und benutzen. Die kompilierte Klasse aus diesem Quellcode wird erneut als Teil des Routinen-Verschlüsselungsverfahrens verschlüsselt. Wir verwenden ein Java-Verschleierungstool namens Retroguard, um alle Klassen zu verschlüsseln. Wir integrieren auch einen Schlüssel in die HTML-Seite, um sicherzustellen, dass die Anwendung nur funktioniert, wenn sie von der Website [redacted] heruntergeladen wurde. Wenn der Benutzer das Glas auf seinen lokalen Computer kopiert und versucht, es auszuführen, wird es fehlschlagen.

+0

Welche Anmeldeoptionen unterstützt Ihr DB-System? Unterstützt es die Verwendung signierter Schlüssel (a la SSH) anstelle von user/pass? Gibt es andere Authentifizierungsmechanismen (LDAP, AD, PAM) in der Umgebung, die anstelle von DB-Authentifizierung verwendet werden können? – Freiheit

+2

Wenn Sie die Details verschlüsseln, müssen Sie sie auf dem Client entschlüsseln. Spiel ist aus. Dann werden Sie sie wahrscheinlich im Klartext über den Draht schicken - was bedeutet, dass ein Gegner nicht einmal die Mühe haben muss, Java installiert zu haben. –

+0

Dank Tom, ich hatte nicht gedacht, dass das Endergebnis irgendeine Sicherheit übertrifft, die wir im Design implementieren. Dieser spezielle mysql-Benutzer hat nur Lesezugriff, daher bin ich fast versucht zu sagen "OK, was auch immer, zumindest können sie die Daten nicht ändern, wenn sie die Verbindungsparameter erhalten", aber ich fühlte mich nicht gut es auf lange Sicht. –

Antwort

3

Ja, JARs sind nur ZIP-Dateien, es ist also durchaus möglich, eine mit WinZip zu öffnen und den Inhalt anzusehen. Wenn Sie wissen, was Sie tun, können Sie ein einfaches Textpasswort darin finden.

Es klingt, als ob Ihre JAR einen Client enthält, der direkt mit einer Datenbank verbunden ist. Sie sagen nicht, ob dies über das Internet oder ein VPN oder ein LAN geschieht. Wird die Datenbank remote vom Client bereitgestellt?

Dies ist einer der Gründe, warum Client/Server-Apps weggegangen sind: Es ist schwierig, sie über das Internet zu sichern.

Ihre App klingt für mich wie ein klassischer Client-Server. Habe ich das richtig?

Eine mittlere Schicht wird normalerweise zwischen dem Client und der Datenbank eingeführt, um die Sicherheit zu überprüfen, Eingaben zu validieren und zu binden und die Anforderungen an den entsprechenden Handler zur Erfüllung zu senden.Lassen Sie die Benutzer Anmeldeinformationen vorlegen, die Ihre mittlere Stufe validieren muss, bevor Sie sie an die Datenbank weiterleiten.

Es kann Ihnen auch eine Chance gegen SQL-Injection-Angriffe geben.

Wenn Sie den JAR-Inhalt verschlüsseln, müssen Sie einen benutzerdefinierten Klassenlader schreiben, um sie beim Laden zu entschlüsseln. Nicht für schwache Nerven.

Wenn es sich bei Ihrem Client um eine Swing-App handelt, bei der alle Logik- und Datenbankfunktionen in die Listener und Event-Handler für jede Komponente integriert sind, haben Sie eine ernsthafte Überarbeitung. Sie werden zu einer eher serviceorientierten Architektur übergehen, bei der alle Arbeiten von Diensten auf der Serverseite ausgeführt werden. Der Client macht nur das, was er in der klassischen MVC haben soll: er gibt Ereignisse an den Server weiter und zeigt Ergebnisse an. Ihr Kunde wird viel leichter sein.

Das wird der größte Schock für Ihr Entwicklungsteam und das Geschäft sein.

+0

Das jar wird in eine HTML-Seite eingebettet und stellt Anfragen an die MySQL-Datenbank zurück, die der Rest der Website verwendet. Ehrlich gesagt bin ich mir nicht sicher, warum sie mit Java dabei waren. Meine Vermutung ist, dass ein Ingenieur es wusste und nicht mit PHP lernen wollte. Bitte beachten Sie mein Update in der ursprünglichen Nachricht für weitere Informationen. –

+0

Wie wäre PHP besser? Ich sehe nicht, dass mir das Update viel besser geht. Berechnen Sie für dieses Produkt? Haben Sie wirklich eine MySQL-Datenbank, die dem gesamten Internet zugänglich ist? Viel Glück damit. Sie haben keine Ahnung wer in diese Datenbank hackt. Es ist möglich, dies mit Java zu tun, aber es klingt wie Ihr Design von Anfang an fehlerhaft ist. – duffymo

+0

Nein, die Datenbank befindet sich derzeit hinter einer Firewall mit einigen IP-Ausnahmen. Aber jetzt, wo du es erwähnst, müssten wir es komplett öffnen, damit das funktioniert. In Bezug auf PHP wäre es besser, weil alle Datenbankverbindungen hinter der Szene direkt auf dem Server stattfinden würden und nur die Enddaten übertragen würden (alias wie jede andere PHP/MySQL-Anwendung im Internet) –

-1

Um es im Klartext zu setzen ist (ich denke) ernsthafte anfällig. In der Tat kann man das Glas extrahieren und lesen, was in diesem Klartext geschrieben ist.

Wenn ein Jar ein Muss ist, empfehle ich, eine Klasse (nur eine einfache Klasse) zu erstellen, die den Benutzernamen, das Passwort, die URL usw. mit dem endgültigen Schlüsselwort enthält. Obwohl diese Methode nicht wirklich sicher ist, kann zumindest eine kompilierte Klasse nicht leicht gelesen werden. Ein weiterer Vorteil (oder vielleicht ein Nachteil) ist, dass die "hartcodierten" Verbindungseigenschaften nicht einfach geändert werden können. Selbst wenn Sie den Quellcode haben, müssen Sie ihn noch einmal kompilieren und neu kritzeln.

+0

Bitte beachten Sie mein Update auf die ursprüngliche Frage für weitere Informationen darüber, wie das Glas verpackt wird. –

0

Ich denke, die Konvention für diese Art von Sache für die meisten Entwickler ist es, eine Konfigurationsdatei außerhalb des Stammverzeichnisses des Webverzeichnisses zu speichern. Natürlich, wenn dies eine Desktop-Anwendung ist und kein Web, das ist nicht möglich. Etwas, was ich zuvor in einer SWING basierten MySQL-basierten App mit einer begrenzten Anzahl von Benutzern getan habe, war die Verwendung einer mittleren Ebene zur Authentifizierung und Darstellung von Daten als Dienst, unter Verwendung der eingebauten Authentifizierung von MySQL, so dass die gesamte Sicherheit in der Schema und duplizieren dann die Berechtigungseinstellungen für jeden Benutzer. Eine Art hackischer, aber zuverlässiger Ansatz.

+0

Die JAR-Datei verwendet ein eigenes separates MySQL-Benutzerkonto mit schreibgeschütztem Zugriff auf die Datenbank. Aber es wird auf einer Webseite laufen, und so ist meine Vermutung, dass es keine Möglichkeit gibt, die Ressourcendatei außerhalb der Webroot zu speichern, weil dann die JAR-Datei auch nicht darauf zugreifen kann (da sie als lokale Anwendung läuft) Client-Ende) –

+0

Ah, dann ist es für alle Absichten und Zwecke durch Design gebrochen, nichts, was Sie oder die Berater tun können, um es meiner Meinung nach zu beheben. – Novikov

2

Ich beginne meine Antwort mit der Aussage, dass oft gesagt wird: "Jede Person kann ein Sicherheitsschema erstellen, das sie nicht kaputt machen kann".

Wenn Sie nun das Update notieren, in dem die Erwähnung von Verschlüsselung und Verschleierung im selben Update erwähnt wird, wäre es klug zu beachten, dass Verschlüsselung nicht dasselbe wie Verschleierung ist. Technisch gesehen beinhaltet die Verschlüsselung die Verwendung eines Schlüssels, um einen Klartext in einen verschlüsselten Text umzuwandeln, wobei der Klartext nur mit Kenntnis des ursprünglichen Schlüssels wiederhergestellt werden kann. Verschleierung ist definitionsgemäß nirgendwo eng mit der Verschlüsselung verbunden - es beinhaltet die Entfernung von Informationen aus ausführbarem Quellcode, die die ausführbare Datei angeblich "schwierig" zum Reverse-Engineering machen. Üblicherweise beinhaltet die Verschleierung das Ersetzen von Symbolen durch kleinere und manchmal das Neuordnen von Quellcode, der den reverse-engineeren Quellcode schwer lesbar macht, während das Ausführungsprofil des Originals beibehalten wird (der verschleierte Quellcode hat die gleichen Code- und Datenflusspfade) als das Original).

Wichtig ist hier, dass das Passwort im Quellcode codiert ist. Es ist davon auszugehen, dass der verschleierte Quellcode auch das fest codierte Passwort enthält. Diese Annahme ist vernünftig, da die meisten Obfuscatoren nie versucht haben, die constant pool within a class file zu mutieren - das Mutieren eines konstanten Pools ist gefährlich, da dies zu Änderungen im Laufzeitverhalten führen kann. Wenn das Passwort fest in den Quellcode als String kodiert wurde, dann wird die Klassendatei (verschleiert oder nicht) das Passwort in String constant pool haben, das von der JVM in den Speicher geladen wird (ohne Entschlüsselung oder Decodierung in zwischen).

Die beste Vorgehensweise in diesem Fall besteht darin, die Endbenutzer zur Angabe der Datenbankbenutzer-ID und des Kennworts (falls sie das Anwendungssetup verwalten) zu veranlassen, diese vom Benutzer bereitgestellten Anmeldeinformationen sicher zu speichern (abhängig von der Art der Java-EE-Anwendungen sollten versuchen, dass der Container diese Anmeldeinformationen verwaltet) und diese Anmeldeinformationen sicher verwalten, wenn sie aus dem sicheren Speicher abgerufen werden. Vielleicht möchten Sie einen Blick auf den OWASP-Artikel unter Insecure Storage werfen, um weitere Hinweise zu erhalten.

Angesichts der Verwendung eines Applet wird nicht empfohlen, die Datenbank-Benutzer-ID und das Kennwort im Applet zu haben. Dies muss aus verschiedenen Gründen geschehen - gute Anwendungen ermöglichen die Änderung der Datenbank-Benutzer-ID und des Kennworts mit bloßen Konfigurationsänderungen an der Anwendung. Die harte Codierung des Passworts im Quellcode erhöht zwangsläufig den Verwaltungsaufwand. Möglicherweise müssen Sie die Endbenutzer dazu auffordern, ihren Java-Applet-Cache jedes Mal zu löschen, wenn der Datenbankadministrator das Kennwort ändern möchte (und dies wird gelegentlich in einem normalen Rechenzentrum passieren). Darüber hinaus müssen Sie möglicherweise auch vor Datenbankkontensperren schützen, wenn die Änderungen am Applet bereitgestellt werden. Wie bei anderen Empfehlungen auch, wäre es sehr sinnvoll, die Datenbankverbindungen innerhalb der mittleren Ebene zu verwalten.