Datenbank/Scriptsicherheit Datenbankfunktionen
MichiLee
- datenbank
Hallo Forum,
heute habe ich mich versucht in Datenbanken einzulesen und hätte vorerst eine Frage zum Design eines Programmes mit einer Datenbankverbindung.
1. Bisher habe ich kleinere Programme erstellt, bei dem man mittels einer properties Datei die Zugangsdaten zu einer Datenbank angeben konnte.
Wie schaut es jedoch aus, wenn der Benutzer oder sogar mal der Kunde keine Zugangsdaten sehen sollte. Dann könnte man es zwar "hart" in den Javacode schreiben. Man kann aber Javacode dekompilieren oder könnte bei Java/JSP die JSP-Seiten evtl. so erweitern, dass man über die JSP-Seite eine Datenbankverbindung aufbaut und so Inhalt auslesen kann. Was könnte man hier machen?(Der Sinn des Schutzes der Datenbank sei mal dahingestellt)
Diese Frage stelle ich mir, falls der Entwickler bestimmte Daten für eine Datenbank zukauft (EAN Codes, Geografiedatenbank, Schuldatenbank) und eine Applikation dazu schreibt. Habe mich auch schon in Datenbankberechtigungen GRANT eingelesen, bei der man bestimmte Funktionen untersagen kann. Die Applikation selber braucht aber bestimmte Funktionen. Und wenn ein Endbenutzer die Zugangsdaten für die Datenbank einesehen könnte über die properties zum Beispiel, würde er den Inhalt der Datenbank problemlos auf einen Schlag kopieren können oder keine Ahnung was man da anstellen kann. (Wie gesagt, ich möchte da jetzt keinen Kunden oder Benutzer einschränken, sondern darum, was man beachten sollte, wenn es sich mal um etwas sensiblere Daten handeln würde)
2. Habe mir Trigger und Stored Prozedures angeschaut. Der Unterschied wäre ja, dass man einen Trigger (Bsp. Select, Insert) anlegt und einer Tabelle zuordnet. Sobald nun ein Select auf diese Tabelle erfolgt, wird der Trigger aufgerufen. Bei Stored Prozedures hingegen, wird die Prozedur von der Applikation aufgerufen, die dann erst den Select, Insert, was auch immer aufruft. Sollte man mit Grant ein Insert verbieten, würde er auch die Stored Prozedure mit einem Insert verbieten ne?
Wäre alles richtig, was ich von mir gegeben habe?
3. Wobei ich nicht fündig wurde, ist "(+)" und "SELECT NULL .. from..."
Vielleicht gebe ich das (+) auch nur falsch bei Google ein. Für was steht dieses (+), wenn man dies bei einer SQL (zum Beispiel in der where Verbindung) angibt? Oder ich frage mich, was ein SELECT NULL bezweckt?
4. Ist die Perfomance bei eienr ORACLE Datenbank durch die Trennung von Datendaten und Tablespaces eigentlich nicht schlechter, anstatt wenn man diese Trennung nicht hätte?
5. Über das Befehl "STORAGE(INITIAL 1234567 NEXT 12345678 PCTINCREASE 300)" wurde ich auch nicht fündig.
6. ~~~sql
insert into test ( id, text )
select rownum, 'Blabla' || to_Char(rownum)
from all_objects
where rownum <= 1000;
commit;
Irgendwie verstehe ich das Select in dem INSERT INTO nicht. Er selectiert rownum, und 'Blabla" oder rownum in einen Buchstaben abgewandelt?
7\. Sind wieder leider viele Fragen geworden. Aber folgende SQL ist gegeben:
~~~sql
select first.*, second.*
from db_first first, db_second second
where first.id = second.id
and second.adate= (
select max( adate)
from db_second
where id = first.id
and adate <= sysdate
);
In der Tabelle first gibt es nur die Spalte ID, Name und in second auch eine ID und ein aDate.
Nun soll folgende Query doppelt so schnell sein:
select first.*, second.*
from db_first first,
( select *
from ( select bla.*, max( adate) over ( partition by id ) max_date from db_second bla )
where adate= max_date
) second
where first.id = second.id (+);
Liegt das daran, dass er im oberen Beispiel für jede Zeile aus der Tabelle first jedesmal ein Select ausführen muss, wohingegen er beim zweiten, das nur einmal im FROM tut, bzw. zweimal. Wobei mir das "OVER" auch überhaupt nichts sagt (Irgend eine Fensterrangfunktion, wo ich noch kein Beispiel dafür gefunden habe)
Es gab zwar noch dieses Beispiel, aber da muss ich mich in Bindvariable einlesen, für was das gut ist:
select first.*, second.*
from db_first first,
(
select * from
(
select *
from second
where id = :Bindvariable
and adate <= sysdate
order by adate desc
)
where rownum = 1
) second
where first.id = second.id (+);
Viele Grüße
Hallo MichiLee,
ich kann Die leider nur drei Deiner Fragen beantworten. Und dabei die erste nicht einmal komplett.
- Wobei ich nicht fündig wurde, ist "(+)" und "SELECT NULL .. from..."
Das "(+)" in der where Bedingung ist ein outer join.
Also:
select t1.*, t2.*
from t1, t2
where t1.id = t2.id(+)
würde bedeuten, dass auch die Datensätze aus t1 selektiert werden, die keinen entsprechenden Datensatz in t2 haben
insert into test ( id, text )
select rownum, 'Blabla' || to_Char(rownum)
from all_objects
where rownum <= 1000;
commit;
> Irgendwie verstehe ich das Select in dem INSERT INTO nicht. Er
> selectiert rownum, und 'Blabla" oder rownum in einen Buchstaben
> abgewandelt?
Nein. Er macht einen insert in die Tabelle test mit den ersten 1000 Sätzen aus der Tabelle all\_objects. In das Feld ID schreibt er dabei die Rownum der all\_objects und in das Feld text schreibt er 'Blabla' und hängt an dieses Blabla die Rownum dran. "||" ist in Oracle das Zeichen für Concat also anhängen
Hi,
- Habe mir Trigger und Stored Prozedures angeschaut. Der Unterschied wäre ja, dass ... ...Sollte man mit Grant ein Insert verbieten, würde er auch die Stored Prozedure mit einem Insert verbieten ne?
Wäre alles richtig, was ich von mir gegeben habe?
Das ist davon abhängig, wie die Prozedur angelegt wurde.
Du hast die Möglichkeit, beim Anlegen einer Prozedur, zu sagen, dass sie mit den Rechten des Aufrufers, den Rechten des Eigentümers bzw. mit den Default Aufrufeinstellungen erstellt werden soll. Dabei ist default, glaube ich zumindest, gleich Eigentümer.
Somit kannst Du jemandem mit Grand revoke die Insert rechte entziehen, und er kann trozdem noch über eine Applikation welche eine Insert Prozedur nutzt immer noch Daten einspielen lassen. Dazu benötigt er dann jedoch die Execute Rechte auf diese Prozedur.
gruß emetiel
moin,
- Habe mir Trigger und Stored Prozedures angeschaut. Der Unterschied wäre ja, dass man einen Trigger (Bsp. Select, Insert) anlegt und einer Tabelle zuordnet. Sobald nun ein Select auf diese Tabelle erfolgt, wird der Trigger aufgerufen.
weniger von einem SELECT, mehr von DML befehlen wie INSERT, UPDATE und DELETE.
Bei Stored Prozedures hingegen, wird die Prozedur von der Applikation aufgerufen, die dann erst den Select, Insert, was auch immer aufruft.
es muss nicht immer eine applikation sein, die eine stored procedure aufruft. jeder der auf irgendeine weise zugriff auf die datenbank hat und die sp ausführen darf, kann sie aufrufen.
- Wobei ich nicht fündig wurde, ist "(+)" und "SELECT NULL .. from..."
Vielleicht gebe ich das (+) auch nur falsch bei Google ein. Für was steht dieses (+), wenn man dies bei einer SQL (zum Beispiel in der where Verbindung) angibt?
das (+) Zeichen ist ein relikt von oracle aus alten zeiten, es war vor 9i der einzige weg in oracle OUTER JOINS zu bilden. mit 9i hat oracle sich der schreibweise von ANSI SQL angepasst, sprich du kannst nun auch in oracle LEFT JOIN schreiben anstelle in der WHERE klausel die (+) schreibweise zu benutzen.
Oder ich frage mich, was ein SELECT NULL bezweckt?
NULL ist in kontext von datenbanken ein besonderer wert. er wird unterschiedlich interpretiert. ich empfehle immer nur eine interpretation und zwar immer, nämlich das der wert für keine information steht, sprich es ist keine aussage über den inhalt möglich. man könnte auch sagen unbekannt. SELECT NULL ist zum beispiel bei unterabfragen in kombination mit EXISTS abfragen interessant. da spielt es dann keine rolle, ob in der unterabfrage werte zurückzugeben werden. alleine die tatasache, ob es einen datensatz gbt ist dabei interessant, aber nicht welchen wert irgendeine spalte hat.
SELECT t1.*
FROM tablle1 t1
WHERE EXISTS (SELECT NULL
FROM tabelle2 t2
WHERE t2.id = t1.id
)
;
- Ist die Perfomance bei eienr ORACLE Datenbank durch die Trennung von Datendaten und Tablespaces eigentlich nicht schlechter, anstatt wenn man diese Trennung nicht hätte?
was sind den datendaten oder meinst du datendateien ? grundsätzlich stehen tablespaces anders in verbindung zu datendateien, nämlich ein tablespace hat ein oder mehre datendateien und eine datendatei gehört genau zu einem tablespace. ein tablespace kann mal also als gruppierung von datendateien ansehen.
- Über das Befehl "STORAGE(INITIAL 1234567 NEXT 12345678 PCTINCREASE 300)" wurde ich auch nicht fündig.
wenn du mal ohne die spezifischen zahlen suchst, wirst du viele treffer haben. grundsätzlich ist es die erweiterung einer CREATE anweisung, die objekte wie tabellen oder indexe erstellt und du damit angeben kannst, wie sich die speicherung des objektes verhält, zum beispiel wie groß die erste speichereinheit (extent) ist, wie groß die folegende, ob sie dynamisch immer größer werden, etc.
insert into test ( id, text )
select rownum, 'Blabla' || to_Char(rownum)
from all_objects
where rownum <= 1000;
commit;
> Irgendwie verstehe ich das Select in dem INSERT INTO nicht. Er selectiert rownum, und 'Blabla" oder rownum in einen Buchstaben abgewandelt?
grundsätzlich kann man die daten, die an in einer abfrage selektiert auch gleich in eine tabelle einfügen. dazu mussse die anzahl der spalten übereinstimmen und auch die datentypen. rownum ist eine pseudospalte in oracle, sie nummeriert die ergebnisdatensätze hoch. dabei wird am text 'Blabla' zusätzlich die ROWNUM hinten "angeklebt", sprich zum beispiel 'Blabla1', 'Blabla2', etc.. ROWNUM kann auch in der WHERE klausel benutzt werden, allerdings ist diese verwendung ein wenig tricky, da kann man leicht was falsch machen.
> Nun soll folgende Query doppelt so schnell sein:
die beiden abfragen können meiner meinung auch unterschiedliche ergebnise liefern, insofern hinkt ein vergleich.
> Es gab zwar noch dieses Beispiel, aber da muss ich mich in Bindvariable einlesen, für was das gut ist:
bindvariablen sind wichtig, damit das dbms die abfrage mit unterschiedlichen parametern als gleiche abfrage deutet, sprich nicht immer wieder neu parsen muss. das kann einen nicht unerheblichen geschwindigkeitzsvorteil bringen.
Ilja
Hi,
danke Euch beiden für Eure Antworten. Hat mir sehr geholfen.
- Habe mir Trigger und Stored Prozedures angeschaut. Der Unterschied wäre ja, dass man einen Trigger (Bsp. Select, Insert) anlegt und einer Tabelle zuordnet. Sobald nun ein Select auf diese Tabelle erfolgt, wird der Trigger aufgerufen.
weniger von einem SELECT, mehr von DML befehlen wie INSERT, UPDATE und DELETE.
Bei Stored Prozedures hingegen, wird die Prozedur von der Applikation aufgerufen, die dann erst den Select, Insert, was auch immer aufruft.
es muss nicht immer eine applikation sein, die eine stored procedure aufruft. jeder der auf irgendeine weise zugriff auf die datenbank hat und die sp ausführen darf, kann sie aufrufen.
verstehe. Ich könnte praktisch für alle Benutzer einer bestimmten Tabelle die DML Befehle verbieten (GRANT) aber Stores Prozedures erlauben. Von einer Applikation oder ein Benutzer könnte dann nur bestimmte gespeicherte SP ausführen. Ob das Sinn macht oder nicht, weiß ich jetzt nicht, da man in den SP ja auch viel mist in die Variablen einfügen kann.
Ansonsten habe ich mich noch informiert, wie man Java-Klassen schützen kann. Diese seien aber nur bedingt schützbar, da man im Endeffekt den Maschinencode in den Registern, Prozesse und Speichern per Reverse Engineering mit viel Mühe etwas aufschlüsseln kann.
Ich frag mich aber, was man mit solchen Befehlen anfangen kann? Daraus kommt man ja schlecht zu nem Programm oder wenn dort Zahlen addiert oder so werde auf Maschinencodeebene?
Bzgl. der Datenbankauthentifizierung, die man im Code dann hat, kann man dann genauso wenig machen. Hart in den Code reinschreiben, einen Obfuscator drüberlaufen lassen, dann hätte man sich etwas von Ahnungslosen gesichert, die nur die Klassen decompilieren können.
Grüße