# JDBC - Direktzugriff auf MySQL



## RelaX (24. Sep 2012)

Hallo liebe Java-Community,

ich hab da mal eine kleine Frage bezüglich der Sicherheit von JDBC und mySQL.

Angenommen ich hab ein Programm, in Java geschrieben, das ich an x-beliebigen Leuten aushändigen möchte und veranker die Zugangsdaten im Quellcode. 
Oder mit anderen Worten: Ich erlaube jedem sich mit diesem mySQL-User einzuloggen. Über diesen Datenbank-User ist es möglich sich mit einem gültigen Username und einem dazugehörigen Passwort einzuloggen.

Hat er dies getan bekommt er Zugriff auf die Funktionen des Programmes. Da die Anwendung aber stark Datenbankbezogen ist braucht er für jede Aktion gültige Zugangsdaten. Soll heißen: Ohne die Datenbank macht das Programm einfach nichts.

Ich lass mir bei jeder aufgerufenen Procedure die User-Passwort-kombi mitgeben. Und nur wenn solches gültig ist bekommt er ein ergebnis.

Wenn ich jetzt, also in der Theorie, diesem Datenbank-Benutzer nur die execute-Rechte gebe und alles andere nicht erlaube, wie sicher ist soetwas?

Hoffe ihr habt so ungefähr verstanden was ich meine ;-)

Freue mich schon auf die ersten Antworten.

Mfg RelaX


----------



## nillehammer (24. Sep 2012)

Für den Schutz der Datenbank ist das wohl ausreichend. Mit EXECUTE kann der User ja nur Daten einfügen, ändern, löschen. Eine Veränderung der Datenbankstruktur (CREATE, ALTER, DROP) ist damit ja ausgeschlossen.

Den Rest habe ich leider nicht verstanden. Was meinst du mit hiermit?


> Ich lass mir bei jeder aufgerufenen Procedure die User-Passwort-kombi mitgeben. Und nur wenn solches gültig ist bekommt er ein ergebnis.


----------



## RelaX (24. Sep 2012)

Also sehe ich das nicht als Einziger so das die Datenbank somit vor Angriffen geschützt ist?

Das Problem ist ja das die Datenbank ja Informationen bereitstellt die nicht für Jedermann zugänglich sein soll. Da ja das Programm dekompiliert werden kann könnte sich ja jemand ohne Account Zugang zu diesen Daten verschaffen indem er sich z.b. mit MySQL Workbench einloggt und dort die Procedures aufruft. Und deshalb muss er bei jedem Procedure-Aufruf eine gültige User-Passwort-kombi mitliefern. Wenn keine gültige gefunden wurde liefert die Procedure keine Werte.. oder eben Falsche.

Nein er soll ja nichts einfügen können, sondern nur in der Lage sein die Procedures aufzurufen.


----------



## nillehammer (24. Sep 2012)

> Da ja das Programm dekompiliert werden kann könnte sich ja jemand ohne Account Zugang zu diesen Daten verschaffen indem er sich z.b. mit MySQL Workbench einloggt und dort die Procedures aufruft. Und deshalb muss er bei jedem Procedure-Aufruf eine gültige User-Passwort-kombi mitliefern. Wenn keine gültige gefunden wurde liefert die Procedure keine Werte.. oder eben Falsche.


Ok, das habe ich dann doch falsch verstanden. Das wäre natürlich möglich. Davor wärest Du nicht geschützt. Am zweckmäßigsten wäre aus meinr Sicht, jeden User mit eigenem Passwort bei MySQL einzupflegen und bei Start des Programms vom User abzufragen anstatt im Programm zu hinterlegen. Natürlich kann dann der jeweilige User auch mit anderen Clients als Deinem Programm arbeiten.


----------



## Pippl (24. Sep 2012)

Worum geht es dir genau? 

*Darf keiner etwas an der Datenbankstruktur ändern?*
Darf keiner die Datenbankstruktur ändern, reicht die Begrenzung der Rechte aus. Natürlich kannst du dann niemanden speziell weitere Rechte geben (entweder alle oder keiner).

*Dürfen nur ein paar spezielle Leute mit diesen Daten arbeiten?*
Wenn du die Frage mit "ja" beantworten kannst, überlege dir doch am Anfang des Programs den User nach entsprechenden User-Password Kombi zu fragen. (Somit werden diese Daten nirgends gespeichert - außer temporär)


----------



## RelaX (24. Sep 2012)

Mhh ich glaub ihr habt mich nicht verstanden.. Hab das auch irgendwie blöd erklärt.

Also ich hab eine Software und eine Datenbank. Die Zwei Sachen sind nicht zu trennen. Jeder Benutzer des Programmes arbeitet mit den selben Daten. D.h. es gibt nur eine Datenbank. Dieser Datenbank verpasse ich einem Datenbank-User mit execute-Rechte. Soll heißen: Er darf nur vorgefertigte Stored Procedures verwenden um auf die Daten zuzugreifen.

Und diesem User veranker ich hartcoded im Quelltext meines Javaprogrammes.

Sooweit so gut. Hier stellt sich die erste Frage. Durch dekompilieren gelangt man ja an die Zugangsdaten des Datenbank-Users. Wie gefährlich ist das? Unter Berücksichtigung des nächsten Punktes.

Die Benutzer des Java-Programmes loggen sich mit einer User-Passwort-kombi ein mit der sie sich registriert(anderes Thema) haben. Auf folgende Weise:
"Das Java-Programm schickt diese Kombi nun an die Datenbank(Connect mit dem Datenbank-User im hardcode) und ruft dort eine stored Procedure auf um dann zu checken ob diese Kombi stimmt."

Stimmt diese folge werden Funktionalitäten freigeschaltet. Da aber jede Funktionalität wieder rum Daten aus der Datenbank braucht werden diese Daten angefordert. Dies Funktioniert dann so:
"Es wird eine Stored Procedure aufgerufen die mindestens Username und passwort braucht bevor die eigentliche Select oder insert oder was auch immer durchgeführt wird, wird erst geprüft ob die User-Passwort-Kombi gültig ist. Ansonsten passiert nada."

Hoffe ich konnte mein Sicherheitsmodell jetzt näherbringen.


----------



## maki (24. Sep 2012)

Ich sehe keinen Vorteil mit der zus. User/Password Kombi.

Solange user und Passwort im Quelltext stehen, gibt es keine Sicherheit.
Wenn das passwort nicht im Quelltext steht, bringt der zus. Aufwand mit der Name/PW Kombi auf Stored Procedure Ebene doch keine Vorteile.


----------



## tfa (24. Sep 2012)

maki hat gesagt.:


> Ich sehe keinen Vorteil mit der zus. User/Password Kombi.


Wenn ich das richtig verstanden habe, steht die zusätzliche user/PW-Kombination nicht im Quelltext, sondern ist nur dem Anwender bekannt. Und zwar hat jeder Anwender sein eigenes Konto. Die Authentisierung übernimmt also die DB und die STPs. Nicht besonders schon, aber _halbwegs _sicher.


----------



## maki (24. Sep 2012)

tfa hat gesagt.:


> Wenn ich das richtig verstanden habe, steht die zusätzliche user/PW-Kombination nicht im Quelltext, sondern ist nur dem Anwender bekannt. Und zwar hat jeder Anwender sein eigenes Konto. Die Authentisierung übernimmt also die DB und die STPs. Nicht besonders schon, aber _halbwegs _sicher.


Ah.. jetzt verstehe ich.

D.h. aber im Endeffekt, der User ist fest, und man kann fröhlich Passwörter raten?
Denn diese entscheiden dann letztenendes über die Berechtigungen..


----------



## RelaX (24. Sep 2012)

Ja genau. Jeder user hat seine eigene User-Passwort-kombi. Raten könnte man mit sicherheit, wie bei jedem Account.

Ja was heißt denn halbwegs sicher? Welche Möglichkeiten gäbe es denn um sich Zutritt zu vertraulichen Daten zu verschaffen?

Worauf müsste ich achten?


----------



## Empire Phoenix (24. Sep 2012)

Wirklcih sicherer wäre auf serverseite eine anwendung dazwischen zu packen, die die Validierung und authorisation macht.

Warum ist das sicher?
Weil validierung serverseitig, wie bei den store procedures.
Warum besser? Weil einfach möglich jedem user saubere zugriffsrechte zu geben, (inclusive rollen wenn einige aktionen nur von einigen usern gemacht werden soll)
Zudem ist das ganze dann unabhängig von mysql fallst mal die db gewechselt werden soll.


----------



## RelaX (24. Sep 2012)

Mhh also das verstehe ich jetzt nicht. Bitte hab Rücksicht, ich gebe mir ja Mühe.

Also.. die Datenbank kann ja gewechselt werden, die Daten und die Procedures sind ja exportierbar, und mehr brauch ich nicht. Die Zugangsdaten stehen ja in der Table. z.b. kunde. Für jeden kunden einen eigenen Datensatz.

Ich glaub wir reden wieder aneinander vorbei.

Die Überprüfung findet doch serverseitig statt.. nämlich in der Procedure und diese entscheidet dann anhand der Einträge in der Table Kunde ob der Procedure gültige Daten mitgeliefert wurden.

Könntest du mir erklären wieso die Validierung in einer extra Anwendung sicherer ist als die Validierung direkt in MySQL über die Procedure zu machen?

Jetzt mal ein kleines Fallbeispiel einer Procedure wie ich mir das vorstelle.


```
PROCEDURE `anmelden`(IN uebname varchar(45), IN pw varchar(45))
BEGIN
    DECLARE gefundenerName varchar(45) DEFAULT '';
    DECLARE ergebnistemp int DEFAULT 0;
    DECLARE pwZuGefundenenNamen varchar(45) DEFault '';
    
-- Hier wird jetzt ueberprueft ob der Benutzername ueberhaupt existiert.
    SET gefundenerName = (SELECT Benutzername FROM kabum_kunde WHERE Benutzername = uebname);


-- Wenn der Benutzername vorhanden ist.
    If gefundenerName IS NOT NULL THEN

-- Jetzt wird das Passwort des Gefundenen Benutzers ueberprueft.
        SET pwZuGefundenenNamen = (SELECT Passwort FROM kabum_kunde WHERE Benutzername = gefundenerName);
        IF pwZuGefundenenNamen IS NOT NULL THEN
            IF pw = pwZuGefundenenNamen THEN

-- SET ergebnistemp = 1; wenn benutzer gefunden und mit dem uebergeben pw uebereinstimmt.
                SET ergebnistemp = 1;
            ELSE SET ergebnistemp = 4;
            END IF;
        ELSE SET ergebnistemp = 3;
        END IF;
    ELSE SET ergebnistemp = 2;    
    END IF;
    

    SELECT ergebnistemp;
END
```

Naja SQL-Injection ist ja bei einer Procedure ausgeschlossen. Finde zumindest keine Quelle die das wiederlegen kann.


----------



## Empire Phoenix (24. Sep 2012)

Nicht sicherer, flexibler, vonner sicherheit her ist das ok.

Aber entgegen der theorie kann ich dir versichern, wenn du jetzt zb nen postgresql server nimsmt wrid das zu 99% nicht funktionieren mit denselben stored procedures.

Mit einer anwendung kann man allerdings (wobei das in dienem fall wohl unwichtig ist) context analyse machen. zb jemand  versucht mit 50 passwörten pro minute login, -> ip ban.
Oder krams amchen wie per geo ip feststellen das wenn jemand der in deutschland ist, sich plötzlich aus china einloggt.


----------



## RelaX (24. Sep 2012)

Mhh also in der Theorie müsste das doch mit einem Trigger funktionieren. Könnte ja eine Tabelle anlegen mit anz. login und ip-adresse. Für jeden Procedure-aufruf ip speichern und anz. login hochsetzen. im falle eines erfolgreichen Login wird der Login-Eintrag gelöscht. Ich weiß ich bin gemein.. :-D Sowas ist doch auch möglich.

Wenn ich z.b. mit MyphpAdmin auf die Datenbank gehe und schaue welche Verbindungen Offen sind dann kann ich diese doch auch Händeln. Oder sehe ich das jetzt falsch?


----------



## Empire Phoenix (27. Sep 2012)

Ja kann man alles auch auf db ebene machen,

die frage ist, willst du deine Logicmti auf die datenbank zersplattern? erade bei groß systemen (die sowieso schon server logic haben) ist es schöner wenn alles an einer stelle ist.


----------



## RelaX (27. Sep 2012)

Okey. Also so wie ich das sehe ist meine Anwendung noch trivial genug um alles so auf der Datenbank zu bewerkstelligen. Da sollte man also immer im Hinterkopf haben wann ein umstieg Sinn machen würde.

Ein Vorteil hab ich damit aber sicher: Das direkt auf der Datenbank zu erledigen dürfte doch um einiges schneller sein. ODER?

Punkto mehr Arbeit: Durch die Procedures spare ich mir mehr Performance ein. Lohnt sich also sowieso. Egal ob ich eine Anwendung dazwischen hab oder nicht.


----------

