Forum: PC-Programmierung Datenbankverschlüsselung MySQL


von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Ich bin gerade am Überlegen, wie man am besten eine 
Datenbankverschlüsselung für einige Felder auf die Reihe bekommt und ob 
sich da überhaupt eine gute Sicherheit erreichen lässt.

Das Ziel wäre eine Datenbank, in der persönliche Daten wie Klarnamen, 
Adress- und Bankdaten sowie Login-Daten (Kennwort-Hashes) enthalten 
sind, die sich aber nur mit einem korrekten Login lesen lässt. Also so, 
daß ein möglicher Angreifer die Daten nicht Personen zuordnen kann, 
selbst wenn er die gesamte Datenbank in die Finger bekommt. Oder selbst 
wenn er einzelne Datensätze einer bestimmten Person zuordnen kann (z.B. 
bekannte ID), daß die persönlichen Daten weiterhin geschützt sind und 
sich ohne ein gültiges Kennwort nicht dekodieren lassen.

Meine momentanen Ideen gehen dahin, einen Datenbankschlüssel aus dem 
Kennwort-Hash zu errechnen, so daß der Datenbankschlüssel selbst nur mit 
einem Hashwert dekodiert werden kann. Wenn man dann bei der 
Kennwortprüfung und der Erzeugung des Datenbankschlüssel-Hashes 
verschiedene Verfahren anwendet, sollten beide Objekte sicher sein, man 
kann von einem (dem bekannten und in der Datenbank im Klartext 
abgelegten Kenntwort-Hash) nicht auf den Datenbankschlüssel-Hash 
schließen.

Damit sollte sich eine so hohe Sicherheit erreichen lassen, daß man zum 
Brechen des Schutzes den laufenden Server angreifen und die Scripte 
kompromittieren müsste, um das Datenbank-Kennwort zu erhalten. Gegen 
einen kompromittierten Webserver gibt es auch wenig Schutzmechanismen, 
das Abfangen eines gültigen Logins wäre einem solchen Server auch 
möglich.

Am besten wäre, wenn man das ganze in PHP hinbekommt, es gibt für PHP 
bestimmt entsprechende AES-Plugins (habe ich noch nicht nachgeschaut, 
mache ich aber demnächst noch), so daß man durch die Verschlüsselung 
nicht zuviel Rechenleistung verbraucht.

Was haltet ihr von dem Ansatz? Machbar oder sinnlos?

Gibts bessere Ansätze?

von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
> Ich bin gerade am Überlegen, wie man am besten eine
> Datenbankverschlüsselung für einige Felder auf die Reihe bekommt

Vor ein paar Jahren habe ich einen verschlüsselten, transparenten 
Datentyp für PostgreSQL geschrieben, aber der leider hat nur die Daten 
auf der Disk symmetrisch gecryptet und den Schlüssel aus dem TPM 
bezogen. War für eine HIPAA-konforme Hostinglösung, bei der die Daten 
auch gegen Diskdiebstähle von authorisiertem Personal unseres Hosters 
sichern sollte, wurde dann aber nicht benutzt, weil der Kunde das lieber 
doch intern machen wollte. (HIPAA kann bei Verstößen sehr, sehr teuer 
und rufschädigend sein.)

> Damit sollte sich eine so hohe Sicherheit erreichen lassen, daß man zum
> Brechen des Schutzes den laufenden Server angreifen und die Scripte
> kompromittieren müsste

Du bist mir bisher meistens als helles Köpfchen aufgefallen, daher geh 
ich davon aus, daß wir über "security by obscurity" nicht reden müssen, 
oder? Wenn der Server kompromittiert ist, ist er kompromittiert, dann 
sind auch Deine Skripte etc. kompromittiert. (Und gerade PHP ist 
vermutlich die mit Abstand ungeeignete Technologie, um Sicherheit 
implementieren zu wollen, ganz am Rande bemerkt...)

> [...]
> Was haltet ihr von dem Ansatz? Machbar oder sinnlos?
> Gibts bessere Ansätze?

Ja, unter gewissen Voraussetzungen: die Daten werden clientseitig ver- 
und entschlüsselt, und zwar ohne Cookies oä, denn die werden bei jedem 
Request wieder zum Server übertragen. Wenn man es wirklich hart machen 
will, nimmt man für Authentifizierung und Authorisierung eigene 
Benutzerzertifikate, und für die symmetrische Verschlüsselung eine nur 
dem User bekannte und separat einzugebende Passphrase. Nachteil: man 
kann halt in der DB nicht mehr einfach serverseitig in den 
verschlüsselten Feldern suchen... Aber grundsätzlich kenne ich keine 
andere Methode, die eine nur ansatzweise ähnliche Sicherheit 
gewährleisten kann. Alles serverseitige ist Unsinn, sofern man von einem 
kompromittierten Server ausgehen muß.

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Meine momentanen Ideen gehen dahin, einen Datenbankschlüssel aus dem
> Kennwort-Hash zu errechnen, so daß der Datenbankschlüssel selbst nur mit
> einem Hashwert dekodiert werden kann.

Kann man vermutlich hier benutzen, sollte man wie alle kryptographischen 
Primitive aber nicht selber erfinden. Es gibt gängige Möglichkeiten, 
Stichwort key derivation function (KDF).

> Wenn man dann bei der
> Kennwortprüfung und der Erzeugung des Datenbankschlüssel-Hashes
> verschiedene Verfahren anwendet, sollten beide Objekte sicher sein, man
> kann von einem (dem bekannten und in der Datenbank im Klartext
> abgelegten Kenntwort-Hash) nicht auf den Datenbankschlüssel-Hash
> schließen.

Wie gesagt -- nicht selber erfinden. Wenn man ein anderes Verfahren 
benutzen muss damit es sicher wird klingt das schonmal schlecht.

> Am besten wäre, wenn man das ganze in PHP hinbekommt, es gibt für PHP
> bestimmt entsprechende AES-Plugins (habe ich noch nicht nachgeschaut,
> mache ich aber demnächst noch), so daß man durch die Verschlüsselung
> nicht zuviel Rechenleistung verbraucht.

Ungh, wenn's sein muss. Hast du nicht die Möglichkeit, eine weniger 
furchtbare Sprache zu verwenden?

: Bearbeitet durch User
von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Wenns für's Internet sein soll, find ich PHP nicht schlecht.

Mit "anderem Verfahren" meinte ich nichts selbst gestricktes, sondern 
eine andere Anzahl Runden, andere Salts, ggf. eine andere geeignete 
Hashfunktion. Ziel davon wäre, daß hinterher zwei verschiedene Hashes 
rauskommen, die nichts miteinander zu tun haben. Weil einen davon muß 
man unverschlüsselt in der Datenbank ablegen, sonst funktionieren keine 
Logins.

Ich kann auch nicht verhindern, daß der Server das Datenbankkennwort für 
die Zeit des Script-Ablaufs im Speicher halten muß. Das ist eben so, 
100%ige Sicherheit gibts nicht, aber ich möchte möglichst nah dran.

Ein kompromittierter Server ist halt defintiv unsicher bzw. würde das 
Verfahren spielend brechen. Aber das wäre bei jedem Verfahren der Fall 
und sowas sollte das einzige Sicherheitsrisiko bleiben.

Der Angreifer soll quasi die Scripte und die Datenbank in den Händen 
halten können, ohne wirklich sensible Daten (vor allem Adresse und 
Bankverbindung) auslesen zu können. Jedenfalls nicht, solange er keine 
gültigen Login-Daten hat. Wenn er die hat, bräuchte er den ganzen Rest 
erst gar nicht, aber dagegen kann ich auch nicht viel machen wenn 
irgendwer seinen Login verwammst.

Das mit der Suche ist ein Problem, mir ist dazu noch nichts brauchbares 
eingefallen. Evtl. müssen die Namen im Klartext erhalten bleiben (nach 
denen suchen zu können ist wichtig) oder man müsste für sowas die 
komplette Datenbank laden, die Namen dekodieren und dann in diesem Array 
suchen. Für ein paar tausend Leute geht das vielleicht wenn nicht 
zuviele Suchanfragen sind, das müsste man ausprobieren was es an 
Performance kostet. Praktisch finde ich das jedenfalls nicht. Dann 
lieber die Namen als Klartext lassen, die sind nicht sonderlich geheim 
und die meisten mit der ID abrufbaren Sachen wären sowieso öffentlich 
bzw. nicht sonderlich schützenswert. Das gilt wirklich nur für Adressen 
oder Bankdaten. Die Namen dazu wären nice-to-have, aber was nicht geht, 
geht halt nicht.

Nachtrag:
Die Sicherheit des Datenbankschlüssels soll darauf beruhen, daß man ihn 
für jeden Benutzer (der ihn braucht, also nur die Admins) mit einem Hash 
verschlüsselt, der aus den Login-Daten gewonnen wird, aber nicht als 
Login-Prüf-Hash in der Datenbank steht. Dem Angreifer, der alle Scripte 
und die Datenbank einsehen kann, fehlt dann dieser Hash und damit ein 
sehr langes Kennwort zur Enschlüsselung des Datenbankschlüssels.

: Bearbeitet durch User
von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
> Wenns für's Internet sein soll, find ich PHP nicht schlecht.

Ja, das haben schon viele gedacht. Deswegen wimmelt das Internet von so 
vielen PHP-Sicherheitsproblemen... und die "Sprache" selbst hat eine 
Sicherheitshistorie, die von hier bis zum Pluto und zurück reicht.

> Mit "anderem Verfahren" meinte ich nichts selbst gestricktes, sondern
> eine andere Anzahl Runden, andere Salts, ggf. eine andere geeignete
> Hashfunktion.

Das von mir erähnte Problem hat nichts mit der Algorithmik zu tun. Wenn 
Dein Server das Zeug entschlüsseln kann, kann es auch jeder Angreifer, 
der Deinen Server kompromittiert hat.

> Ich kann auch nicht verhindern, daß der Server das Datenbankkennwort für
> die Zeit des Script-Ablaufs im Speicher halten muß. Das ist eben so,
> 100%ige Sicherheit gibts nicht, aber ich möchte möglichst nah dran.

Dann hast Du meine Einlassungen nicht verstanden.

> Ein kompromittierter Server ist halt defintiv unsicher bzw. würde das
> Verfahren spielend brechen.

Nur dann, wenn die Ver- und Entschlüsselung clientseitig passiert.

von Sheeva P. (sheevaplug)


Lesenswert?

Sheeva P. schrieb:
> Nur dann, wenn die Ver- und Entschlüsselung clientseitig passiert.

... NICHT clientseitig ... Entschuldigt bitte.

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Das mit der Suche ist ein Problem, mir ist dazu noch nichts brauchbares
> eingefallen. Evtl. müssen die Namen im Klartext erhalten bleiben (nach
> denen suchen zu können ist wichtig) oder man müsste für sowas die
> komplette Datenbank laden, die Namen dekodieren und dann in diesem Array
> suchen.

Hä, ich dachte die Idee ist dass man das nur mit dem Klartext-Passwort 
kann. Wenn das Skript diese Fähigkeit hat, verstehe ich nicht, was die 
ganze Idee soll.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Das Script könnte es nur, wenn es dazu vorher gültige Login-Daten 
bekommen hat. Ansonsten fehlt auch dem Script ein nötiges Kennwort zum 
Entschlüsseln des eigentlichen Datenbankschlüssels.

Wenn die Entschlüsselung clientseitig gemacht wird, könnte man auch 
nicht in den Daten suchen bzw. hätte die verschlüsselten Daten auf dem 
Server gar nicht zur automatischen Verarbeitung zur Verfügung - was z.B. 
bei den Kontodaten aber erforderlich wäre. Dabei entsteht sowieso das 
Problem, daß die verschlüsselten Daten nur "unter Aufsicht" zur 
Verfügung stehen würden und nicht z.B. Cronjobs. Allerdings denke ich, 
daß ich das passend hinbekomme bzw. keine Cronjobs haben werde, die 
verschlüsselte Daten brauchen. Falls man das nicht hinbekommt hat sich 
das Problem Verschlüssung erledigt, dann ist es nicht praktikabel oder 
man erreicht nur ein geringeres Maß an Sicherheit wenn man z.B. dem 
Cronjob sein eigenes Kennwort hinterlegen muß. Das würde dann wieder im 
Klartext irgendwo auf dem Server liegen (oder von wo der Cronjob 
gestartet wird) und dann kann man sich das schenken.

Außerdem verlagere ich das Problem mit clientseitiger Verschlüsselung 
doch nur - dann wäre die Unsicherheit nicht mehr ein kompromittierter 
Server, sondern ein kompromittierter Client.

Desweiteren sehe ich nicht, wo PHP bei einem dem Angreifer bekannten 
Quelltext unsicherer sein soll als andere Sprachen. Wahrscheinlich 
müsste ich sowas einfach mal bauen und dann könnt ihr probieren, es zu 
brechen.

Die Frage hier ist ja auch nicht muss das sein, sondern ist es überhaupt 
möglich bzw. sinnvoll, das zu probieren. Oder ist der Versuch Quatsch 
weil der Effekt vernachlässigbar gering ist?

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Das Script könnte es nur, wenn es dazu vorher gültige Login-Daten
> bekommen hat. Ansonsten fehlt auch dem Script ein nötiges Kennwort zum
> Entschlüsseln des eigentlichen Datenbankschlüssels.

Aber dann doch nur den Datensatz des betreffenden Benutzers? Oder 
entschlüsselt irgendein Passwort alle Daten? Ich habe das Konzept noch 
nicht ganz verstanden.

> Außerdem verlagere ich das Problem mit clientseitiger Verschlüsselung
> doch nur - dann wäre die Unsicherheit nicht mehr ein kompromittierter
> Server, sondern ein kompromittierter Client.

Der dann aber nur Daten von 1 Benutzer hat.

> Desweiteren sehe ich nicht, wo PHP bei einem dem Angreifer bekannten
> Quelltext unsicherer sein soll als andere Sprachen. Wahrscheinlich
> müsste ich sowas einfach mal bauen und dann könnt ihr probieren, es zu
> brechen.

Weil die Implementierung an sich super buggy ist. Vergleiche mal
  https://www.cvedetails.com/vulnerability-list/vendor_id-74/product_id-128/opec-1/PHP-PHP.html
mit
  https://www.cvedetails.com/vulnerability-list/vendor_id-10210/opec-1/Python.html
Plus die ganzen Security-Bugs die dein eigener Code garantiert haben 
wird, z.B. wegen des verkorksten Typsystems.

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

Ben B. schrieb:
> Der Angreifer soll quasi die Scripte und die Datenbank in den Händen
> halten können, ohne wirklich sensible Daten (vor allem Adresse und
> Bankverbindung) auslesen zu können.

Bei solchen Sicherheitsthemen finde ich es immer sehr sinnvoll mir die 
Angriffsszenarien zu überlegen und den Schutz dann gezielt daran 
auszurichten.

In was für Szenarien hat ein Angreifer die Scripte und die Datenbank in 
den Händen, kann aber keine Änderungen daran vornehmen?

Mir fällt da eigentlich vor allem der Fall ein, wenn dem Angreifer ein 
unverschlüsselter Backupsatz in die Hände fällt. Das könntest Du aber 
lösen in dem Du alle Backups ausschließlich voll verschlüsselt 
erstellst.

Sobald Du irgendwo ein eval() aus der Datenbank drin hast (was ich bei 
PHP leider sehr sehr oft sehe), bedeutet jede SQL Injection gleich dass 
der Server kompromittiert ist.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Angehängte Dateien:

Lesenswert?

Okay machen wir das doch mal so (Siehe oben).

Verratet mir bitte den Inhalt des verschlüsselten Feldes.

Falls ihr es herausbekommt, verratet auch bitte wie. Oder falls ihr 
generell Anmerkungen, Verbesserungen habt - immer her damit.

von Weg mit dem Troll ! Aber subito (Gast)


Lesenswert?

Der Poster scheint nicht wirklich eine grosse Ahnung zu haben. Einfach 
mal etwas verschluesseln, egal wie und wozu ..

von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> falls ihr
> generell Anmerkungen, Verbesserungen habt - immer her damit.

wenn jemand Zugriff auf Deinen Server hat, dann kann er auch die 
Passworte und Keys lesen. Das muss ja irgendwo hinterlegt sein, damit 
die Skripte damit arbeiten zu können (die verwendete Sprache ist da 
übrigens komplett Wumpe).

Ich halte die Idee mit der Verschlüsselung für den falschen Ansatz. 
Wenn, dann solltest Du verhindern, dass jemand überhaupt auf Deine 
Maschine kommt. Ein gängiger Ansatz ist es, sie in ein geschlossenes 
Netz zu stellen und nur definierte Zugriffe über die tatsächlich 
notwendigen Ports durchzulassen (80, 443).

Natürlich gibt es auch dann noch Möglichkeiten gehackt zu werden. Aber 
wenn das ordentlich konfiguriert ist und regelmäßig Updates eingespielt 
werden, dann ist liegt die Schwelle schonmal ordentlich hoch.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Wenn ich keine Ahnung habe, dann knack den undurchdachten Schnellentwurf 
doch einfach mal kurz zwischendurch und beweise mir das. Ansonsten kann 
jeder hier große Töne rausspucken.

Zu dem Szenario oben kann man auch annehmen ihr habt es geschafft, 
Datenbank und Script zu kopieren, aber euch fehlt ein Account-Kennwort. 
In dem Beispiel wird lediglich keine Datenbank verwendet, die Felder 
werden einfach so definiert, wie man sie auch aus einer Datenbank laden 
könnte. Für die Verschlüsselung macht das keinen Unterschied.

von ThomasW (Gast)


Lesenswert?

Es ist ne nette Fingerübung und bestimmt auch interessant. Ich glaub Dir 
sofort, dass Du das ganz toll gelöst hast.

Leider übersiehst Du immer noch das eigentliche Problem: wer Zugriff auf 
das Filesystem Deines Servers hat, der hat auch Passwort und Skript.

Was genau hindert diesen Angreifer daran, das bei sich lokal laufen zu 
lassen?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Du kannst dieses Script problemlos bei Dir lokal laufen lassen. Deswegen 
verwendet es extra keine echte Datenbank, das braucht nur ein aktuelles 
PHP mit OpenSSL.

Nochmal: Der Server wird als so sicher wie möglich angenommen. Der steht 
in einem Rechenzentrum, so daß seine Sicherheit einem größeren 
Dienstleister obliegt. Die Sicherheit des Servers liegt damit nicht in 
meiner Hand. Wenn der Angreifer zum Brechen dieser Verschlüsselung die 
Scripte auf dem Server modifizieren müsste (etwa so, daß die Login-Daten 
irgendwo hin geschickt werden oder was auch immer), dann reicht mir das, 
weil sicherer bekommt man die Sache unter gegebenen Umständen sowieso 
nicht.

Ich kann mich auch nicht davor schützen, daß irgend ein DAU sowas wie 
"xxx" oder "admin" als Kennwort verwendet. Bzw. nur begrenzt indem ich 
so einfache Zeichenketten abweise. Es gibt nie absolute Sicherheit, ich 
möchte lediglich mit vertretbarem Aufwand so dicht wie möglich 
herankommen.

von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> Nochmal: Der Server wird als so sicher wie möglich angenommen. Der steht
> in einem Rechenzentrum, so daß seine Sicherheit einem größeren
> Dienstleister obliegt.

Sorry, aber dann versteh ich das ganze Thema nicht so richtig. Bevor 
jemand an die DB kommt ist er auf dem Filesystem. Üblicherweise 
jedenfalls. Weil die meisten DB-Server (also die Programme selbst) recht 
solide und sicher sind. Angriffsvektoren sind meist völlig andere Dinge. 
Sowas wie fehlende oder schlechte Validierung von Usereingaben z.B. 
damit man - Du ahnst es schon - Zugriff aufs Filesystem bekommt.

Deshalb halte ich Deinen Ansatz für ne nette Fingerübung. Mit wirklich 
wenig Sicherheitsgewinn. Eher mit Problemen in Sachen Performanz und 
Skalierbarkeit.

Das erinnert mich an all die witzigen Tricks, die verhindern sollen dass 
User die Bilder aus einer Webseite bei sich Speichern. Tolle Ideen und 
coole Scripte und keines funktioniert wirklich.

Ben B. schrieb:
> Es gibt nie absolute Sicherheit, ich
> möchte lediglich mit vertretbarem Aufwand so dicht wie möglich
> herankommen.

Genau deshalb rate ich Dir: schau Dir an, wie es die anderen gelöst 
haben. Da gibt es geprüfte und ausgereifte Ansätze. Und die willst Du 
toppen? Das finde ich mutig!

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Was ich erreichen möchte ist lediglich ein wenig mehr Sicherheit falls 
irgendwer die Datenbank und möglicherweise die Scripte dazu in die 
Finger bekommt. Sowas ist ja schnell mal spurenlos kopiert. Er soll 
allein damit keine wirklich kritischen Daten gewinnen können wie 
beispielsweise vollständige Adressen oder Bankdaten. Mehr nicht. 
Irgendwas zu toppen war gar nicht beabsichtigt, ich habe mich nirgendwo 
mit irgendwas anderem gemessen.

von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> falls
> irgendwer die Datenbank und möglicherweise die Scripte dazu in die
> Finger bekommt. Sowas ist ja schnell mal spurenlos kopiert.

und warum genau sind die Konfigurationsdateien nicht dabei? Warum wurden 
die nicht mitkopiert?

Aber weisste, es scheint hier mehr um Dein Bauchgefühl zu gehen. Ist ja 
nicht so schlimm. Nur wirklich mehr Sicherheit bringt sowas halt nicht!

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Wenn ich keine Ahnung habe, dann knack den undurchdachten Schnellentwurf
> doch einfach mal kurz zwischendurch und beweise mir das. Ansonsten kann
> jeder hier große Töne rausspucken.

Das ist für Security nicht der richtige Denkansatz. Du musst beweisen, 
dass dein System sicher ist. Es muss sich nicht für jedes hingehackte 
5-Zeilen-Konstrukt jemand 3d hinsetzen und einen Exploit schreiben und 
es wird als sicher angenommen wenn dazu niemand Lust hat. Das ist Unfug.

Das ist wie bei den Kreationisten: Quatsch produzieren geht einfach 
fünftausend mal so schnell wie ihn fundiert zu widerlegen. Deshalb 
kannst du aus "keiner hat meinen Quatsch widerlegt" keinesfalls 
schließen, dass es kein Quatsch ist.

Dazu erfordert das Erstellen eines Exploits erheblich höhere 
Qualifikation als das Produzieren des Codes.

: Bearbeitet durch User
von Weg mit dem Troll (Gast)


Lesenswert?

Ich würde die Datenbank auf einer abgesetzten Maschine laufen lassen, 
welche von einer Gateway Maschine angesteuert wird. Die Datenbank 
maschine wird exklusiv von der Gateway maschine angesprochen. Das ist 
machbar. Und die Gateway maschine filtert die Anfragen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Das machen viele Webhoster zwangsweise so.

Ich hab das Beispiel nur schnell geschrieben damit meine Idee verstanden 
wird. So kann sich das jeder Interessierte anschauen oder selbst dran 
herumprobieren. Ähnlich wie die Frage nach einem Schaltplan als Bild 
wenn jemand seine Schaltung sonst nur in Prosa beschreibt und niemand 
nachvollziehen kann, was er da aneinandergelötet hat.

Ich denke auch, daß jemandem schon aufgefallen wäre wenn das Beispiel 
grobe Fehler enthalten hätte. Insofern sehe ich das nicht als voll krass 
120pro sicher an, aber die Idee scheint auch nicht 120pro absolut Quark 
zu sein.

@Thomas
> und warum genau sind die Konfigurationsdateien nicht dabei?
Was brauchst Du denn oder was möchtest Du wissen? Das Script oben 
verwendet keine Konfigurationsdateien für eine Datenbank oder ähnliches, 
es ist so wie es da steht lauffähig. Deswegen habe ich die später evtl. 
möglichen Datenbankfelder ja mit den base64-Konstrukten simuliert.

Ansonsten ist der Server nichts besonderes,
Apache2.4.41, PHP7.4.0, OpenSSL 1.1.1c

Wenn Du mehr wissen möchtest dann sag mir bitte was.

von Sven B. (scummos)


Lesenswert?

Ich verstehe immer noch nicht, wie du "durchsuchbar" und "jedes Passwort 
entschlüsselt nur ein Feld" erreichen willst.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Nicht jedes Passwort entschlüsselt nur ein Feld. Das Beispiel enthält 
nur ein Feld, aber später könnten das viele sein, die sich alle mit im 
Beispiel $db_key entschlüsseln lassen.

Der db_key wird für jeden (berechtigten) Benutzer einzeln verschlüsselt, 
mit einem zu seinem Accountpasswort passenden Schlüsseltext, das sind 
die $db_userpass-Felder im Beispiel. Von denen könnte man beliebig viele 
erzeugen, die alle $db_key entschlüssen können.

Edit:
Durchsuchbar in verschlüsselten Feldern geht natürlich nicht. Die 
Klarnamen kann ich dadurch nicht verschlüsseln, aber Adressen und 
Bankdaten sollten sich damit schützen lassen.

: Bearbeitet durch User
von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> Was brauchst Du denn oder was möchtest Du wissen?

Du, das sollte ein Denkanstoss sein: wieso sollte jemand das Skript und 
die DB kopieren - die Datei mit dem Passwort aber liegen lassen? Ich geh 
jedenfalls davon aus, dass es eine solche Datei gibt. Irgendwo her muss 
das Skript ja zur Laufzeit das Passwort kennen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Welche Datei mit dem Passwort?

Wenn Du das Datenbank-Verbindungspasswort meinst, das kann er gerne 
haben. Damit kann er evtl. die Datenbank zerstören, dagegen kann man 
dann nicht viel machen - aber er hätte es trotzdem schwer, die 
verschlüsselten Inhalte aus der DB auszulesen - und darum geht es mir.

von MD5(Passwort) (Gast)


Lesenswert?

Sinn macht das erst richtig, wenn die Entschlüsselung Client-Seitig, 
also z.B. im Browser per Javascript, stattfindet.

Übliches Vorgehen: Aus dem Passwort wird Client-Seitig (z.B. per HKDF 
mit verschiedenen Salts, am besten mit vorgeschaltetem high-round 
PBKDF2) ein Login-Token und ein Encryption Key gewonnen.

Das Login-Token wandert zum Server, der Encryption-Key verbleibt beim 
Client, geheime Daten die der Client schreiben oder lesen will 
verschlüsselt er damit.

Vorteil:
- Benutzer braucht nur Login + Passwort.
- Der Server hat keine unverschlüsselten Daten.
- Der "Vertrauensbedürftige" Software-Teil ist Client-Seitig, wo er in 
Theorie im Quelltext (JS) vorliegt und geprüft werden kann.

https://tools.ietf.org/html/rfc5869

Mit der Vorgabe jedoch:

Ben B. schrieb:
> Der Server wird als so sicher wie möglich angenommen.

Kann man sich das auch alles sparen. Mysql, PHP, LetsEncrypt, HTTPS und 
gut.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Wahrscheinlich ist eine Entschlüsselung auf dem Server mit HTTPS nicht 
viel unsicherer. Ich muß die Daten leider auf dem Server entschlüsseln 
können um z.B. Kontodaten automatisch verarbeiten zu können.

von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> Welche Datei mit dem Passwort?

okay, letzter Versuch: es geht um das Passwort/den Schlüssel oder wie 
immer Du jene Zeichenkette nennst, die Dein Skript zum Ver- und 
Entschlüsseln nutzt. Irgendwie muss diese Zeichenkette zur Laufzeit zu 
Deiner Funktion gelangen. Und wenn Dein Skript darauf Zugriff hat, wieso 
dann nicht der Bösewicht, der Skript und Datenbank kopiert?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Weil der Schlüssel zum Schlüssel der Datenbank das Login-Passwort des 
Benutzers ist. Und davon bekommt der Angreifer nur einen Hashwert, aber 
nicht den Klartext.

von MD5(Passwort) (Gast)


Lesenswert?

Ben B. schrieb:
> Weil der Schlüssel zum Schlüssel der Datenbank das Login-Passwort
> des
> Benutzers ist. Und davon bekommt der Angreifer nur einen Hashwert, aber
> nicht den Klartext.

Aber dann kann dein Cronjob nur laufen, wenn der Benutzer grad 
angemeldet ist, und sein Passwort eingibt?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Korrekt. Entweder muß man dem Cronjob sein eigenes Kennwort zuweisen 
(das muß nicht zwangsweise auf dem gleichen Server liegen, sonst wäre 
die Verschlüsselung wirklich hinfällig) oder man kann keine Cronjobs 
ausführen, die Zugriff auf verschlüsselte Felder brauchen.

Alle automatisierten Arbeiten, die Zugriff auf verschlüsselte Felder 
brauchen, müssen von einem Admin angestoßen werden. Aber das stört evtl. 
nicht, kann sein, daß das sowieso der Fall ist.

von ThomasW (Gast)


Lesenswert?

Ben B. schrieb:
> Alle automatisierten Arbeiten, die Zugriff auf verschlüsselte Felder
> brauchen, müssen von einem Admin angestoßen werden. Aber das stört evtl.
> nicht, kann sein, daß das sowieso der Fall ist.

Ich glaub, ich verstehe das gesamte Konstrukt nicht so recht. Lass mich 
mal zusammenfassen was ich jetzt verstanden hab: Du willst 
Datenbankzugriffe auf bestimmte Felder nur ermöglichen, wenn der User 
angemeldet ist und für jeden Zugriff (auch Lesenden) auf eines der 
Felder jedesmal sein Passwort eingibt. Automatisierte Verarbeitung ist 
nur möglich wenn der Ausführende ebenfalls das Passwort kennt. Ist also 
nicht vorgesehen und vermutlich auch nicht notwendig.

So etwa? ... denn so würde das für mich Sinn machen und so sieht es für 
mich erstmal sicher aus! Zumindest wenn das Handling mit dem 
User-Passwort und dem Inhalt der Felder ordentlich gelöst ist (kein 
mögliches Auftauchen in Logfiles, nicht in der Session speichern, ...).

von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
> Wenn die Entschlüsselung clientseitig gemacht wird, könnte man auch
> nicht in den Daten suchen bzw. hätte die verschlüsselten Daten auf dem
> Server gar nicht zur automatischen Verarbeitung zur Verfügung - was z.B.
> bei den Kontodaten aber erforderlich wäre. Dabei entsteht sowieso das
> Problem, daß die verschlüsselten Daten nur "unter Aufsicht" zur
> Verfügung stehen würden und nicht z.B. Cronjobs.

Wenn die Daten tatsächlich weiterverarbeitet werden müssen, kann man sie 
einmal -- zum Beispiel bei der Anmeldung -- auf den Server übertragen, 
von dort aus in ein Write-Only-System auf einer anderen Maschine 
schreiben, und dann wieder vergessen. Das erhöht den Aufwand für einen 
Angreifer, weil er dann noch in das zweite System eindringen muß, das -- 
es muß ja nicht viel anderes tun als die Daten entgegennehmen und 
persistieren -- eine kleinere Angriffsoberfläche haben kann als ein 
Webserver, welcher eine vollständige Webseite betreibt. Aber das 
Suchproblem auf dem Webserver bleibt natürlich, wenn es denn eines ist.

> Außerdem verlagere ich das Problem mit clientseitiger Verschlüsselung
> doch nur - dann wäre die Unsicherheit nicht mehr ein kompromittierter
> Server, sondern ein kompromittierter Client.

Der Client kennt nur seinen einen Datensatz, den er entschlüsseln kann. 
Wenn also ein Client kompromittiert ist, bekommt der Angreifer nur genau 
diesen einen Datensatz in die Hände -- den Datensatz desjenigen, dem die 
Daten gehören und der seinen Rechner nicht abgesichert hat.

> Desweiteren sehe ich nicht, wo PHP bei einem dem Angreifer bekannten
> Quelltext unsicherer sein soll als andere Sprachen.

Dann solltest Du Dich vielleicht mal informieren. "php insecure" ist ein 
ganz guter Anfang für eine Google-Suche. Nur so als Hinweis: schon der 
Interpreter ist kaputt, oder seit wann ist 3 + "4" = 7?

> Wahrscheinlich
> müsste ich sowas einfach mal bauen und dann könnt ihr probieren, es zu
> brechen.

Du kannst ja eine Bounty ausloben.

von Sheeva P. (sheevaplug)


Lesenswert?

Sven B. schrieb:
> Ben B. schrieb:
>> Das Script könnte es nur, wenn es dazu vorher gültige Login-Daten
>> bekommen hat. Ansonsten fehlt auch dem Script ein nötiges Kennwort zum
>> Entschlüsseln des eigentlichen Datenbankschlüssels.
>
> Aber dann doch nur den Datensatz des betreffenden Benutzers? Oder
> entschlüsselt irgendein Passwort alle Daten? Ich habe das Konzept noch
> nicht ganz verstanden.

Wenn es sich um mein Konzept der clientseitigen Verschlüsselung handelt: 
doch, das hast Du genau richtig verstanden. Die Daten des Benutzers 
werden mit seinem individuellen und nur ihm bekannten Schlüssel 
clientseitig ver- und entschlüsselt.

von ThomasW (Gast)


Lesenswert?

Sheeva P. schrieb:
> Dann solltest Du Dich vielleicht mal informieren. "php insecure" ist ein
> ganz guter Anfang für eine Google-Suche.

und bei welcher Sprache gibt es da keine Treffer?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

@Thomas: Genau.
Die automatisierten Scripte werden so wie es im Moment aussieht sowieso 
von einem Admin angestoßen, und der hat auch ein Kennwort. Mir muß nur 
noch was einfallen, wie ich das baue, daß man nicht ständig sein 
Kennwort neu eingeben muß. In den Logfiles wird das natürlich nie 
auftauchen, auf dem Server speichern ist keine Option und in der Session 
ablegen hätte ich auch kein gutes Gefühl. Dann hab ich gleich wieder das 
Problem wie ich die Session schützen soll.

Wie machen das Banken mit ihren Onlinebanking-Sessions?

> "php insecure" ist ein ganz guter Anfang für eine Google-Suche.
> oder seit wann ist 3 + "4" = 7?
Das ist doch Quark. Das ist z.B. eine Sache, die ich an PHP liebe. 
Endlich mal keine beschissene Typendeklaration erforderlich bzw. falls 
man sie wirklich mal braucht, kann man sie auch in PHP erzwingen.

3+(int)"4" wäre z.B. nicht 7.

Aber wenn es danach geht, das casting von C soll ja da auch so seine 
Schwächen haben. Wenn ich das bei Google eingebe, explodiert irgendwo 
auf der Welt einer ihrer Server. Ich finde nicht unbedingt, daß die 
Auswahl der Sprache ein Kriterium für eine sichere Verschlüsselung sein 
soll.

Ansonsten brauche ich das evtl. für eine Mitgliederverwaltung falls ich 
diese denn schreiben muß. Sprich die Admin-Zugänge müssen zwangsweise 
Einsicht in den kompletten Datenbestand haben und nicht nur in einen 
bestimmten Datensatz. Bzw. es gibt nur einen Datensatz, der dann aber 
alle Daten enthält.

Deswegen macht es auch keinen Sinn, alle Daten zur automatischen 
Verarbeitung erst auf den Server hochzuladen. Bzw. ich müßte sie erst 
vom Server verschlüsselt herunterladen, auf dem Client entschlüsseln und 
dann unverschlüsselt wieder zum Server. Das wäre nicht sicherer (für 
einen kompromittierten Server mit gefälschten Scripten z.B.) als die 
direkte Entschlüsselung auf dem Server.

> Du kannst ja eine Bounty ausloben.
Auf mein Beispiel oben?
Deinen Stolz... und von meinem ein bißchen. :D

von Andreas M. (amesser)


Lesenswert?

Wenn es für einen Angreifer möglich ist, sämtliche (außer den 
Passwörten) für die Entschlüsselung notwendigen Informationen von dem 
Server zu laden und zusätzlich die Skripte zu modifizieren, dann kommt 
er problemlos an die Daten.

Er kann die PHP Skripte so umschreiben, dass diese alle Hashes, die von 
den Clients kommen irgendwohin umleiten oder abspeichern. Er kann 
natürlich auch das an den Client ausgelieferte Javascript so 
modifizieren, dass es Ihm die Hashes schickt auch wenn es das 
normalerweise nicht tun würde.

Und dann muss er nur warten und evtl. noch dafür sorgen, dass sich ein 
Admin zeitnah anmeldet.

von Sheeva P. (sheevaplug)


Lesenswert?

ThomasW schrieb:
> Sheeva P. schrieb:
>> Dann solltest Du Dich vielleicht mal informieren. "php insecure" ist ein
>> ganz guter Anfang für eine Google-Suche.
>
> und bei welcher Sprache gibt es da keine Treffer?

Keine Ahnung, Brainfuck vielleicht... aber bei PHP gibt es da erstens 
viel mehr Treffer als bei anderen Sprachen -- Python, Ruby und Perl 
kommen auf jeweils gut zwei bis knapp drei Millionen Treffer, PHP 
hingegen auf über sechzehn (!) -- und zweitens befinden sich in den 
Suchergebnisse auch ein paar ziemlich aufschlußreiche Argumentationen. 
;-)

von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
> Wie machen das Banken mit ihren Onlinebanking-Sessions?

Sie sichern die mit einem kryptografischen CSRF-Token ab.

>> "php insecure" ist ein ganz guter Anfang für eine Google-Suche.
>> oder seit wann ist 3 + "4" = 7?
> Das ist doch Quark.

Ja, das ist Quark, weil es zu schwer entdeckbaren logischen Fehlern 
führt. Ansonsten sind die Ergebnisse der vorgeschlagenen Google-Suche 
reich an teilweise sehr detaillierten Argumentationen -- wenn Du es also 
wirklich wissen willst, dann lies sie halt.

> Das ist z.B. eine Sache, die ich an PHP liebe. Endlich mal keine
> beschissene Typendeklaration erforderlich bzw. falls man sie
> wirklich mal braucht, kann man sie auch in PHP erzwingen.

Ich kenne keine modernere Skriptsprache, in der man Typdeklarationen 
braucht. Python3 kann mit den sogenannten type hints überprüfen, ob 
Funktionsargumente vom richtigen Typ sind, aber das ist eine andere 
Veranstaltung und natürlich optional.

> Aber wenn es danach geht, das casting von C soll ja da auch so seine
> Schwächen haben.

Hat es, aber die Zeiten, in denen man Websoftware in C geschrieben hat, 
sind glücklicherweise schon seit geraumer Zeit vorbei. ;-)

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Ich denke viele Dinge sind dabei einfach Geschmackssache. Man kann sich 
mit jeder Programmiersprache in die Nesseln setzen wenn man ihre Macken 
nicht kennt.

In PHP z.B. prüfe ich übergebene Variabeln sehr sehr gründlich und führe 
auch eine Typumwandlung auf den erwarteten Typ durch. Beispielsweise 
$zahl=floor(@$_POST['zahl']); - wenn der Benutzer da Quark oder Späße 
wie "dreihundertachtundzwanzigkommafuennef" sendet, kommt eine Null 
wieder raus und damit kann ich leben. Schlimmstenfalls bekommt der 
Benutzer in seinem Ergebnis dann Quark zurück, aber er wollte es ja 
nicht anders.

Kritischen Anfragen (oder wenn man schon mal bei ist einfach allen) ein 
Token mitzuschicken wäre kein Problem, führt aber zum Verlust der 
Session wenn die Kette einmal abreißt. Einmal Seite aktualisieren, 
danach darf man von vorne anfangen.

Naja mal sehen. Das Optimum sollte ein gesundes Mittelmaß zwischen 
Benutzerfreundlicheit und Sicherheit sein.

Edit:
Nochmal der Vollständigkeit halber, die Sicherheit des Servers 
dahingehend, daß HTTPS funktioniert und die Scripte nicht geändert 
werden, muß ich als gegeben ansehen. Wenn das nicht der Fall ist, kann 
ich nichts gegen Angriffe machen, das liegt einfach nicht in meiner Hand 
wenn andere (z.B. Webhoster) für diesen Bereich zuständig sind.

: Bearbeitet durch User
von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Beispielsweise
> $zahl=floor(@$_POST['zahl']); - wenn der Benutzer da Quark oder Späße
> wie "dreihundertachtundzwanzigkommafuennef" sendet, kommt eine Null
> wieder raus und damit kann ich leben.

Wenn er also in das Feld für seinen Geburtsmonat "April" eintippt, ist 
er einfach im Januar geboren und es gibt keine Fehlermeldung? Klingt 
gut.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Soso, Du hältst mich also für total bescheuert, oder? Soll ich jetzt 
ernsthaft alle Möglichkeiten aufzählen, die es gibt, um ein Geburtsdatum 
korrekt zu speichern oder zu prüfen? Mal so als Denkanstoß für diesen 
Fall: Es gibt nur zwölf Monate. Durch die geringe Anzahl könnte man 
entweder Eingabefelder als Drop-Down vorgeben (was bei 128 Bit Zahlen 
mit Nachkommastellen evtl. etwas umständlich wird) oder auch probieren, 
die paar Monate als String zu interpretieren wenn man sie denn numerisch 
haben und trotzdem Stringeingaben akzeptieren möchte. Man könnte das 
Geburtsdatum auch einfach als String speichern, von mir aus ohne weitere 
Kontrolle wenn man es nicht sicher oder genau braucht. Jeder so wie er 
will.

Außerdem hast Du Dein Beispiel nicht mal korrekt zuende gedacht.
floor("April") oder intval("April") ergibt nicht 1 (für Januar), sondern 
0 und 0 ist als Monat kein zulässiger Wert. Warum Du mir jetzt noch 
unterstellst, daß ich das einfach so stehenlasse und dem Benutzer keine 
Fehlermeldung vor die Fresse halte, weißt nur Du alleine. Und ehrlich 
gesagt... interessiert's mich auch gar nicht.

von ThomasW (Gast)


Lesenswert?

Sven B. schrieb:
> Wenn er also in das Feld für seinen Geburtsmonat "April" eintippt, ist
> er einfach im Januar geboren und es gibt keine Fehlermeldung? Klingt
> gut.

Du meinst, Du arbeitest mit Benutzereingaben ohne sie zu Validieren? Ja, 
dann ist PHP für Dich nicht geeignet! ;-)

Ansonsten: PHP ist eben eine Skriptsprache und zu der Zeit als sie 
entstanden ist, da war Sicherheit nicht oberste Priorität. Inzwischen 
gibt es sowohl Typisierung als auch alle weiteren Möglichkeiten um 
sicher zu programmieren. Man muss es halt nur tun und bezahlt bekommen.

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

Ich habe einige Jahre Penetrationstests gemacht, vorwiegend im 
Web-Umfeld.
Ich behaupte: PHP, die Sprache und Laufzeitumgebung an sich, ist 
eigentlich kein Security-Problem.
Auch die auf cvedetails veröffentlichten Schwachstellen betreffen i.d. 
Regel  nur irgendwelche Subsysteme und sind normalerweise auch kein 
langanhaltendes Problem.

Das Problem sind eher die beschissenen PHP-Programme von Webentwicklern, 
die kein Problembewußtsein haben.

Und Patch-Management. Es ist anscheinend immer noch nicht verstanden, 
dass man einen öffentlichen Server laufend aktuell halten muss.

Und dann kommen noch die generellen Web-Probleme dazu: XSS, XXE, die 
schwierige Authentisierung/Authorisierung etc.

Und allgemeine Programmierprobleme, z.B. mangelhafte Eingabevalidierung, 
SQL-Injection, Directory-Path-Traversal.

Und Fehler bei der sicheren Serverkonfiguration: offene Ports, 
Versionsinformationen, sichtbare Fehlermeldungen, sichtbare 
Statusseiten, ausführbare Files im Upload-Verzeichnis. Code- und 
Konfigurationsdateien, sogar Backups in der Webroot u.v.a.


Denn Sinn, Datenbankfelder zu verschlüsseln, stelle ich mal in Frage.
Wenn der Server kompromittiert ist, dann kann man auch die 
unverschlüsselten Daten bzw. den Schlüssel bei der Benutzung abfangen. 
Gegen die typischen Security-Programmierfehler hilft die Verschlüsselung 
auch nix.

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Soso, Du hältst mich also für total bescheuert, oder?

Ne, aber dein Beispiel ist halt schon wieder so ein Paradebeispiel von 
PHP-Fehlerbehandlung. Allein dieser @-Operator ist ein unglaublicher 
Hack und ja, wenn du den als Demo für deine ordentliche Fehlerbehandlung 
bringst, fällt es mir schwer nicht darauf zu antworten. ;)

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Du willst mich nicht verstehen...

Das @ ist in diesem Fall lediglich ein Ersatz für z.B.

if (isset($_POST['monat'])) {
 $monat=floor($_POST['monat']);
} else {
 $monat=0;
}

in einem einzigen Zeichen und liefert eine Null, einen definitiv 
ungültigen Wert für einen Monat. Dadurch wird der DAU später noch 
geschlachtet wenn das gesamte Geburtsdatum geprüft wird und er am 
Nullten Nullten NullundNullzig geboren ist.

In dem Beispiel wäre das sogar aufs Jahr anwendbar, da es verdammt 
unwahrscheinlich ist, daß eine im Jahre Null geborene Person sich heute 
noch auf meiner Webseite anmeldet.

@Tilo: (Ist hier das @ erlaubt oder werd ich gleich wieder erschossen?)
Danke für den Beitrag, sehr interessant. Wie gesagt, gegen einen zur 
Laufzeit kompromittierten Server kann ich nicht viel machen. Aber das 
sollte die einzige Fehlerstelle bleiben da ich davon ausgehen muß, daß 
die Leute vom Webhoster das schon im Griff haben.

Ich möchte mich damit gegen Anfälligkeiten wehren wenn z.B. mehrere 
Webprojekte in der Server-Umgebung laufen und eine davon so schlecht 
programmiert ist, daß bspw. das Kopieren aller auf dem DB-Server 
liegenden Datenbanken für einen Angreifer möglich wird. Dann soll er die 
Datenbank haben, aber keine extrem sensiblen Benutzerdaten daraus 
gewinnen können, mit denen er evtl. weiteren Schaden anrichten könnte 
(z.B. Lastschrift-Abbuchungen zu seinen Gunsten im Namen der Firma).

: Bearbeitet durch User
von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> in einem einzigen Zeichen und liefert eine Null, einen definitiv
> ungültigen Wert für einen Monat. Dadurch wird der DAU später noch
> geschlachtet wenn das gesamte Geburtsdatum geprüft wird und er am
> Nullten Nullten NullundNullzig geboren ist.

Aber was ist das denn für eine Validierungslogik? Warum validierst du 
nicht an einer Stelle, ob die Eingabe für dieses Formularfeld einen 
gültigen Wert hat und wirfst einen entsprechenden Fehler falls nicht?

Stattdessen erzeugst du aus einem ungültigen Wert ("April" oder "Feld 
nicht gesetzt") einen anderen (0), der dann keinen Rückschluss mehr 
darauf zulässt was eigentlich das Problem ist.

Genau so fühlen sich die meisten Web-Formulare dann nacher auch an ...

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Weil mir beim Geburtsdatum eine einzige Fehlermeldung reicht nachdem ich 
alle drei Bestandteile davon geprüft habe.

von Sven B. (scummos)


Lesenswert?

Ben B. schrieb:
> Weil mir beim Geburtsdatum eine einzige Fehlermeldung reicht
> nachdem ich
> alle drei Bestandteile davon geprüft habe.

Womit sich der Kreis schließt -- das ist halt so der PHP-Stil. 
Funktioniert schon irgendwie, aber wirkt am Ende immer alles fragil und 
zusammengekleistert. Python hat es mit Django vielleicht in die andere 
Richtung etwas übertrieben, aber da kann man sich Anregungen holen, wie 
man sowas strukturieren könnte, sodass es ordentlich funktioniert.

Ist meine Meinung, du kannst ja eine andere haben.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

... womit das Thema dann durch wäre.

von Sheeva P. (sheevaplug)


Lesenswert?

Sven B. schrieb:
> Ben B. schrieb:
>> Weil mir beim Geburtsdatum eine einzige Fehlermeldung reicht
>> nachdem ich alle drei Bestandteile davon geprüft habe.
>
> Womit sich der Kreis schließt -- das ist halt so der PHP-Stil.

Ich fürchte, das ist es. Wer sich einmal den Code von PHP-Projekten wie 
OsCommerce oder dem Nachfolger XtCommerce, Typo3 und ähnlichen angesehen 
hat, den beschleicht der Verdacht, daß PHP insbesondere solche Menschen 
anzieht, die sich diverse Themen in der Softwareentwicklung wie Entwurf, 
Design, Patterns und Security nicht wirklich erschließen wollen. 
Immerhin hat der TO ein gewisses Sicherheitsbewußtsein, was er mit 
seiner Frage und seinem Konzept beweist, wenngleich ich das Konzept 
immer noch für etwas problematisch halte, denn wenn der Angreifer an die 
Datenbankinhalte, den Scriptcode und das Secret kommt... aber, ja, das 
erhöht die Schwelle für den Angreifer und ist somit grundsätzlich ein 
Gewinn an Sicherheit, selbst wenn er bei einem großen Teil der möglichen 
Angriffsszenarien wohl nicht sonderlich groß sein dürfte.

Andererseits halte ich es nicht für sonderlich vertrauenswürdig, wenn 
ein Entwicklungsteam einer Sprache sich jahrelang ziert, endlich 
Namespaces zu implementieren, weil einige Leute das Projekt verlassen 
haben und darum niemand mehr dabei ist, der den Parser versteht. Nun, 
Namespaces sind nun drin -- nach wie langer Zeit und mit dem häßlichsten 
und unüblichsten Operator, den man sich nur vorstellen kann -- weswegen 
ich hoffe, daß sie mittlerweile mit ihrem Parser weitergekommen sind. 
Aber am Ende leidet das Projekt laut übereinstimmender Aussage mehrerer 
mir persönlich bekannter Coreentwickler leider immer noch darunter, daß 
dabei zu viele Leute in zu viele unterschiedliche Richtungen ziehen: die 
einen wollen eine richtige, vollständige Allround-Programmiersprache 
daraus machen, andere hingegen wollen nicht über einfache 
Webfunktionalität hinaus gehen, auch das ist einer der Gründe, warum das 
mit den Namespaces so lange gedauert hat...

> Funktioniert schon irgendwie, aber wirkt am Ende immer alles fragil und
> zusammengekleistert. Python hat es mit Django vielleicht in die andere
> Richtung etwas übertrieben, aber da kann man sich Anregungen holen, wie
> man sowas strukturieren könnte, sodass es ordentlich funktioniert.

In Python setzen sich seit geraumer Zeit anstelle von Monstern wie 
Django und Zope kleinere Microframeworks wie Bottle.py, Pyramid, 
CherryPy und insbesondere anscheinend Flask durch. Mit Flask habe ich 
selbst sehr gute Erfahrungen gemacht; für die Login-Funktionalität gibt 
es eine Erweiterung namens Flask-Login, die sich sehr einfach einbauen 
und auch sehr leicht erweitern läßt. Dazu noch ein beliebiger ORM für 
eine SQL-Datenbank oder eine Anbindung an eine moderne NoSQL-Datenbank 
wie MongoDB, Elasticsearch oder Redis -- und, ja, alle diese 
funktionieren prima mit Flask-Login -- und schon hat man eine schicke 
Infrastruktur für eine (oder mehrere) dynamische Webseiten.

Dazu gibt es mit WTForms ein Framework für klassenbasierte 
HTML-Formulare mit Möglichkeiten zur Validierung, Konvertierung und 
Filterung. WTForms liefert dazu mit jedem Formular ein Hiddenfield mit 
einem kryptografisch gesicherten CSRF-Token aus. Das klappt ziemlich 
gut, auch wenn man die Seite aktualisiert. Außerdem kann man an jedes 
Formularfeld und an das ganze Formular bereits vorhandene, oder auch 
eigene Validatoren binden, welche im Fehlerfall auch wahlweise 
zusammengefaßt und / oder an ihren jeweiligen Feldern ausgeben kann. Bei 
bestimmten Feldtypen wie <select> wird sogar automatisch ein Validator 
erzeugt, der sicherstellt, daß das Formularfeld nur die in der 
Definition angegebenen Werte liefern darf -- und für Date-, Time- und 
DateTime-Felder gibt es natürlich auch moderne HTML5-Versionen.

Für PHP würden mir als Template-Engine das gute alte Smarty oder auch 
PHP selbst einfallen, das ja im Wesentlichen ebenfalls eine 
Template-Engine ist, als OR-Mapper war Doctrine immer meine erste Wahl 
(wenn ich denn mal gezwungen war, mit PHP zu arbeiten, was lange her 
ist) und früher gab es einmal ein brauchbares Formularframework namens 
HTML_QuickForm -- damals während des Übergangs von PHP4 zu PHP5.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> denn wenn der Angreifer an die Datenbankinhalte, den Scriptcode
> und das Secret kommt...
Bitte entschuldige, aber diese Argumentation ist doch auch ziemlich 
sinnbefreit. Welche Verschlüsselung ist denn bitte noch sicher, wenn der 
Angreifer das alles in den Händen hält? Keine.

von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
>> denn wenn der Angreifer an die Datenbankinhalte, den Scriptcode
>> und das Secret kommt...
> Bitte entschuldige, aber diese Argumentation ist doch auch ziemlich
> sinnbefreit. Welche Verschlüsselung ist denn bitte noch sicher, wenn der
> Angreifer das alles in den Händen hält? Keine.

Eine clientseitige.

Oder man könnte die Daten einfach separieren. Warum muß der Nutzer seine 
Bankverbindung abrufen können? Er kennt sie doch. So macht das zum 
Beispiel Amazon: immer wenn ich dort bezahlen will, werde ich gefragt, 
mit welcher Bankverbindung ich zahlen möchte: mit dem Konto, dessen 
Nummer auf ...123 endet, oder mit jenem, das auf ...456 endet. Auf den 
Frontend-Servern sind diese Daten gar nicht drauf, nurmehr die Kürzel.

Nebenbei: Web- und Datenbankserver zu separieren, einen Reverse Proxy 
und womöglich eine Web Application Firewall zu nutzen, hilft bei 
geringerem Aufwand vermutlich mehr als Deine Idee mit der serverseitig 
gecrypteten Datenbank...

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Der stino-User muß da gar nichts abrufen oder eintragen können, 
zumindest nichts von den schützenswerten Daten. Von vielleicht 500 
Einträgen sind vielleicht 5 Admins, und die müssen das können - lesend 
und schreibend.

Eine clientseitige Verschlüsselung macht auch keinen Sinn wenn man die 
Daten auf dem Server verarbeiten möchte. Spätestens dann könnte ein 
kompromittierter Server das Datenpaket abfangen.

Eine clientseitige Verschlüsselung hilft auch nicht gegen einen 
kompromittierten Client. Wie man das dreht, es bleiben immer 
Unsicherheiten.

Bei den meisten Webhostern sind Web- und Datenbankserver sowieso 
getrennt. Selbst bei mir zuhause kommt man an den Webserver von außen 
nur auf Ports 80 und 443 dran. Alles andere wird vom Router 
weggeschmissen.

von ThomasW (Gast)


Lesenswert?

Sheeva P. schrieb:
> Für PHP würden mir als Template-Engine das gute alte Smarty oder auch
> PHP selbst einfallen, das ja im Wesentlichen ebenfalls eine
> Template-Engine ist, als OR-Mapper war Doctrine immer meine erste Wahl
> (wenn ich denn mal gezwungen war, mit PHP zu arbeiten, was lange her
> ist) und früher gab es einmal ein brauchbares Formularframework namens
> HTML_QuickForm -- damals während des Übergangs von PHP4 zu PHP5.

Es hängt doch sehr davon ab, was Du machen willst. Ich entwickle 
Web-Applikationen. Da kommt PHP überhaupt nicht mehr mit dem View in 
Berührung. Denn das Frontend wird in Angular oder React geschrieben und 
sämtliche Kommunikation mit dem Backend findet über REST statt. Da sind 
mir Formularfelder im Backend egal, solange die Pattern für die 
Validierung identisch sind.

Bei einem CMS sind die Anforderungen sicher anders, das muss ein 
Template gerendert werden. Aber wenn ich mir die aktuellen Systeme so 
anschaue, dann kommen fast alle Sicherheitsprobleme durch Plugins von 
Drittanbietern hinein.


Das eigentliche "Problem" von PHP ist doch, dass es eine gute Sprache 
für Einsteiger ist. Mit wenig Code hast Du schnelle Ergebnisse. Und so 
gibt es da viele Leute die sich das Programmieren selbst beigebracht 
haben. Mehr als in den meisten anderen Sprachen. Und wenn solche Leute 
ihre Projekte ins Netz stellen, dann ist das oft ein einziges 
Scheunentor. Klar ist das bitter, aber das ist kein Fehler in der 
Sprache! Diese Leute würden das auch in Python oder Java falsch machen. 
Nicht weil sie dumm sind, sondern weil es ihnen nie jemand anders 
beigebracht hat.

P.S.: wenn Du hier von Problemen in PHP von vor 10 Jahren sprichst (denn 
so lange gibt es Namespaces bereits) dann hast Du sicher Recht - so war 
das damals - aber es wirkt immer etwas konstruiert wenn da so alte 
Sachen rausgekramt werden.

von Sven B. (scummos)


Lesenswert?

ThomasW schrieb:
> Das eigentliche "Problem" von PHP ist doch, dass es eine gute Sprache
> für Einsteiger ist. Mit wenig Code hast Du schnelle Ergebnisse. Und so
> gibt es da viele Leute die sich das Programmieren selbst beigebracht
> haben. Mehr als in den meisten anderen Sprachen. Und wenn solche Leute
> ihre Projekte ins Netz stellen, dann ist das oft ein einziges
> Scheunentor.

Ich denke diese Beobachtung ist korrekt.

> Klar ist das bitter, aber das ist kein Fehler in der
> Sprache! Diese Leute würden das auch in Python oder Java falsch machen.

Bei dieser hingegen bin ich mir nicht so sicher. Das Sprachdesign von 
PHP legt für viele Problemstellungen Pfusch-Lösungen nahe. Laufzeit- 
oder Compilerfehler gibt es kaum; stattdessen werden irgendwelche 
Warnungen gedruckt, für die es dann sogar Syntax (!) in der Sprache 
gibt, um sie zu verbergen. Das lehrt den Anfänger nicht gerade 
ordentliche Fehlerbehandlung. Das Typsystem ist bestenfalls verwirrend; 
ich halte schwache Typisierung generell für einen großen Fehler, und 
glaube für Anfänger ist sie besonders schlimm, wenngleich vielleicht auf 
ersten Blick angenehm. Ich glaube, wenn der Anfänger mit Python 
programmieren lernt, läuft das schon anders.

: Bearbeitet durch User
von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
> Der stino-User muß da gar nichts abrufen oder eintragen können,
> zumindest nichts von den schützenswerten Daten.

Wenn die User nichts eintragen können, wie kommst Du dann an deren 
Daten? Was ist mit Namensänderungen (zB. durch Heirat) oder 
Adreßänderungen (zB durch Umzug)? Oder mit einer neuen Kontoverbindung 
oder einem Wechsel der Kreditkarte?

> Von vielleicht 500
> Einträgen sind vielleicht 5 Admins, und die müssen das können - lesend
> und schreibend.

Angesichts der Tatsache, daß etwa sechzig und je nach Schätzung sogar 
bis zu neunzig Prozent der Angriffe von innen kommen, ... und warum 
Admins schreibend auf Userdaten (abseits des Zurücksetzens) zugreifen 
müssen, erscheint mir auch als eher seltener (und seltsamer) 
Anwendungsfall.

> Eine clientseitige Verschlüsselung macht auch keinen Sinn wenn man die
> Daten auf dem Server verarbeiten möchte. Spätestens dann könnte ein
> kompromittierter Server das Datenpaket abfangen.

Um Datenpakete "abzufangen", muß der Server sie erstmal lesen können. 
Das heißt entweder, daß der Angreifer Deine Skripte oder Deine 
Serversoftware modifizieren kann (dann hast Du allerdings eh völlig 
verloren), oder daß unverschlüsselt kommuniziert wird und der Angreifer 
die Daten auf dem Netzwerkgerät abfangen kann (aber nur root kann ein 
Netzwerkinterface in den promiscuous mode setzen, und wenn Dein 
Angreifer Root-Rechte hat, ... siehe wie vor). Mir fallen ansonsten noch 
ein paar andere Szenarien ein, wie der Angreifer Deinen Datenverkehr 
abfangen könnte, aber jedem dieser Szenarien ist gemeinsam: wenn er 
Deinen Datenverkehr entschlüsseln kann, hast Du ohnehin alles verloren. 
SSL (bzw heute: TLS) ist ja genau dazu entwickelt worden, um exakt dies 
zu verhindern...

> [...]
> Bei den meisten Webhostern sind Web- und Datenbankserver sowieso
> getrennt. Selbst bei mir zuhause kommt man an den Webserver von außen
> nur auf Ports 80 und 443 dran. Alles andere wird vom Router
> weggeschmissen.

Ben, es ist wirklich nicht ganz einfach mit Dir. Einerseits hörst Du mir 
nicht richtig zu, und andererseits mißverstehst Du, was ich sage...

Schau, mit einer "Trennung von Web- und Datenbankserver" meine ich, daß 
diese beiden auf zwei (oder mehr) unterschiedlichen physikalischen (oder 
virtuellen) Maschinen vorgehalten werden. Dann hat jemand, der in Deinen 
Webserver eingestiegen ist, immer noch keinen Zugang auf das Dateisystem 
des Datenbankservers und kann daher auf und mit der Datenbank nur 
machen, was die Credentials des Webservers zulassen. Es sei denn, er 
knackt auch die zweite Maschine, aber das verdoppelt seinen Aufwand.

Mit einer "Trennung von einfachen und sensiblen Daten" meine ich, daß so 
ein Webserver ja nicht nur eine Datenbank nutzen kann, sondern durchaus 
auch mehrere. So ließe sich mit vergleichsweise geringem Aufwand ein 
Datenbankserver mit Schreib- und Lesezugriffen aufsetzen, der nur die 
weniger sensiblen Daten enthält, sowie ein weiterer Datenbankserver, der 
ausschließlich Schreibzugriffe zuläßt und auf dem dann natürlich auch 
die Weiterverarbeitung der Daten stattfindet. Sowas ist heutzutage im 
Umfeld hochsicherer Server durchaus üblich und geht dabei auch in die 
Richtung moderner Microservice-Architekturen.

> Eine clientseitige Verschlüsselung hilft auch nicht gegen einen
> kompromittierten Client. Wie man das dreht, es bleiben immer
> Unsicherheiten.

Gegen einen kompromittierten Client hast Du ohnehin keine Chance, auch 
mit Deinem Ansatz nicht. Es erscheint mir ein bisschen unfair, an meinen 
Ansatz plötzlich neue Anforderungen zu stellen, die Deiner allerdings 
leider auch nicht zu erfüllen vermag.

Insgesamt glaube ich zwar, daß Dein Ansatz den Aufwand für den Angreifer 
ein wenig erhöht und bestimmte Angriffsszenarien wirksam verhindern 
kann. Andererseits glaube ich aber auch, daß verschiedene andere Ansätze 
wie die Härtung des Servers (think: Entfernung und / oder Deaktivierung 
von allem Überflüssigen, Permissions, ständige Aktualisierungen, sichere 
Paßworte oder besser eine Authentifizierung mit paßwortgeschützten 
SSH-Keys, und so weiter -- der übliche Standardkram eben -- oder 
vielleicht sogar so etwas wie AppArmor, SELinux, RSBAC, grsecurity), ein 
Paketfilter- und ein Web Application Firewall (think mod_security und / 
oder OWASP), eine Host- und eine Network Intrusion Detection, womöglich 
auch proaktiv, das Sperren von Accounts nach einer bestimmten Anzahl 
fehlgeschlagener Login-Versuche, und womöglich zusätzliche Techniken wie 
GEOIP, um definierte Länder / Regionen gleich den Zugriff auf die Seite 
zu verweigern, und womöglich auch ein Reverse Proxy (think HAProxy) und 
natürlich die Trennung von Systemen und eventuell Daten vermutlich 
besser investierte Energie sind. Ach ja, und natürlich ein Monitoring, 
sowohl des Systems und seiner Performancedaten (think System Activity 
Reporter) als auch der Applikation(en) und ihrer Logdateien (think 
logcheck).

Wie man es dreht und wendet: grundsätzlich fängt jede Verbesserung der 
Sicherheit erst einmal mit einer Risikoanalyse an. Ich persönlich würde 
(okay, in meinem beruflichen Umfeld ist das ohnehin durch Regularien wie 
PCI-DSS, SOC, HIPAA, ISO27k, und hierzulande durch das 
Grundschutzhandbuch des Bundesamtes für Sicherheit in der 
Informationstechnologie vorgegeben, siehe dazu auch deren Software 
Verinice) mir also zunächst meine Daten vornehmen und genau über das 
Schutzniveau meiner Datenfelder nachdenken. Personenbezogene Daten 
beispielsweise unterliegen dem Schutz durch die DSGVO, aber etwa 
Kreditkartendaten unterliegen zudem den Regularien des 
Industriestandards PCI-DSS...

Und wenn Du es wirklich ernst meinst, dann würde ich während oder nach 
der Implementierung mal einen zertifizierten Auditor und einen 
professionellen Penetrationstester beauftragen, und regelmäßig einen 
voll automatisierten Sicherheitscheck mit einer Software wie etwa Nessus 
durchführen.

von Sheeva P. (sheevaplug)


Lesenswert?

ThomasW schrieb:
> Es hängt doch sehr davon ab, was Du machen willst. Ich entwickle
> Web-Applikationen. Da kommt PHP überhaupt nicht mehr mit dem View in
> Berührung. Denn das Frontend wird in Angular oder React geschrieben und
> sämtliche Kommunikation mit dem Backend findet über REST statt. Da sind
> mir Formularfelder im Backend egal, solange die Pattern für die
> Validierung identisch sind.

Aber gerade mit modernen Single-Page-Webapplikationen ist es doch ganz 
besonders einfach, eine clientseitige Verschlüsselung zu implementieren. 
Das ist dann nur ein zusätzlicher Layer über Deiner REST-API...

> Bei einem CMS sind die Anforderungen sicher anders, das muss ein
> Template gerendert werden. Aber wenn ich mir die aktuellen Systeme so
> anschaue, dann kommen fast alle Sicherheitsprobleme durch Plugins von
> Drittanbietern hinein.

In jeder meiner Rollen -- Sysop, Architekt, Entwickler, Securitytyp und 
Kunde -- ist es mir völlig egal, wo ein Sicherheitsproblem herkommt. ;-)

> Das eigentliche "Problem" von PHP ist doch, dass es eine gute Sprache
> für Einsteiger ist. Mit wenig Code hast Du schnelle Ergebnisse. Und so
> gibt es da viele Leute die sich das Programmieren selbst beigebracht
> haben. Mehr als in den meisten anderen Sprachen. Und wenn solche Leute
> ihre Projekte ins Netz stellen, dann ist das oft ein einziges
> Scheunentor. Klar ist das bitter, aber das ist kein Fehler in der
> Sprache! Diese Leute würden das auch in Python oder Java falsch machen.
> Nicht weil sie dumm sind, sondern weil es ihnen nie jemand anders
> beigebracht hat.

True, true, true! Der Unterschied ist: mit PHP kann auch Oma Erna eine 
"Webapplikation" schreiben und sogar ins Netz bekommen, und das hätte 
sie mit Java, Python, Perl oder Ruby wahrscheinlich nicht geschafft, 
ohne sich vorher zumindest mit ein paar grundsätzlichen Themen zu 
beschäftigen.

Richtig ist auch, daß die PHP-Leute im Laufe der Jahre einige Dinge dazu 
gelernt und neue Sicherheitsfeatures eingeführt haben. Leider lassen 
sich (oder ließen sich damals, jedenfalls) einige dieser Features 
mithilfe der Interpreterkonfiguration wieder abschalten...

> P.S.: wenn Du hier von Problemen in PHP von vor 10 Jahren sprichst (denn
> so lange gibt es Namespaces bereits) dann hast Du sicher Recht - so war
> das damals - aber es wirkt immer etwas konstruiert wenn da so alte
> Sachen rausgekramt werden.

Das ist richtig und andererseits dann auch wieder nicht so ganz, denn es 
zeigt IMHO auf strukturelle Probleme innerhalb des Projekts. Und ganz am 
Ende beginnt das Problem ja schon damit, daß PHP so etwas wie eine große 
Template-Engine ist, bei der zunächst verschiedene Aspekte und Layer der 
Applikation -- Stichwort MVC -- vermischt werden, daß also Code, der bei 
einem sauberen Applikationsdesign in Model oder Controller gehört, in 
die View geschrieben wird. Sorry, ich bin und bleibe darum skeptisch, 
und auf meinen Servern gibt es daher keinen, auf dem PHP installiert ist 
-- oder FTP, mal ganz am Rande bemerkt. ;-)

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> Wenn die User nichts eintragen können,
> wie kommst Du dann an deren Daten?
Kann alles nur von Admins eingetragen oder geändert werden,
ist aber so vorgesehen und stört daher nicht.

Was die Risikoanalyse angeht: Ich schätze das so ein, daß es definitiv 
wichtigere, größere und wertvollere Datenbanken gibt. Ich weiß aber auch 
nicht, was Angreifer mit solchen Daten evtl. genau wollen und an welchem 
Punkt solche Datenbanken für sie interessant werden.

Für die Sicherheit des Web- oder Datenbankservers werde ich nicht 
verantwortlich sein, das ist Sache des Webhosters, seine Dateisysteme 
sicher zu haben. Die größte Gefahr hierbei sind aus meiner Sicht 
unsichere Kennwörter bei den FTP/SSH-Zugängen.

Bei meiner Kiste zuhause komme nicht mal ich von außen an das 
Dateisystem dran, auf dem Ding läuft nichts was das ermöglich würde 
(auch kein SSH/FTP), nur Ports 80 und 443 sind von außen erreichbar. Ich 
muß "nur" wirksam verhindern, daß irgendjemand irgendwelche Injections 
in meinen Projekten schafft, dann sollte die Kiste ziemlich sicher sein.

Ich sehe jedenfalls dauernd irgendwelche Angriffe in den Logs, die nach 
irgendwelchen Scripten (PHPMyAdmin ist der Favorit) suchen. PHPMyAdmin 
ist drauf, aber in einer aktuellen Version und weit ab der 
Standard-Pfade. Ich habe schon oft überlegt, einfach mal ein Fake-Script 
hinzustellen und zu schauen, was dann hinterherkommt, wenn diese 
Scan-Tools "fündig" werden.

Wie gesagt, ich weiß noch nicht ob das ganze wirklich sinnig ist oder ob 
der allgemein-Schutz ausreichend ist. Es würde halt die Latte für 
jemanden deutlich höher legen, der nur die Datenbank oder eine 
Sicherheitskopie davon in die Finger bekommen hat.

von Sheeva P. (sheevaplug)


Lesenswert?

Ben B. schrieb:
>> Wenn die User nichts eintragen können, wie kommst Du dann an
>> deren Daten?
> Kann alles nur von Admins eingetragen oder geändert werden,
> ist aber so vorgesehen und stört daher nicht.

Gut, lieben Dank. Das beantwortet zwar nicht die Frage, warum Admins die 
Daten lesen müssen, aber... nungut.

> Was die Risikoanalyse angeht: Ich schätze das so ein, daß es definitiv
> wichtigere, größere und wertvollere Datenbanken gibt. Ich weiß aber auch
> nicht, was Angreifer mit solchen Daten evtl. genau wollen und an welchem
> Punkt solche Datenbanken für sie interessant werden.

Oh... wenn einer meiner Admins so etwas sagen würde, hätte er in dreißig 
Sekunden seine Entlassungspapiere. Ben, Du bist für die Sicherheit der 
Daten Deiner User verantwortlich. Ist Dir das klar?

> Für die Sicherheit des Web- oder Datenbankservers werde ich nicht
> verantwortlich sein, das ist Sache des Webhosters, seine Dateisysteme
> sicher zu haben. Die größte Gefahr hierbei sind aus meiner Sicht
> unsichere Kennwörter bei den FTP/SSH-Zugängen.

Dem würde man professionell begegnen, indem man keine unsicheren 
Paßworte zuläßt. Noch viel professioneller wäre es allerdings, FTP ganz 
wegzuwerfen und SSH... ;-)

> Bei meiner Kiste zuhause komme nicht mal ich von außen an das
> Dateisystem dran, auf dem Ding läuft nichts was das ermöglich würde
> (auch kein SSH/FTP), nur Ports 80 und 443 sind von außen erreichbar.

Uiuiui, und wer durch Dein Portmapping kommt, hat Vollzugriff auf Dein 
komplettes internes Netzwerk. Wow. Ist das segmentiert?

> Ich
> muß "nur" wirksam verhindern, daß irgendjemand irgendwelche Injections
> in meinen Projekten schafft, dann sollte die Kiste ziemlich sicher sein.

Klar, SQL Injection ist das einzige Szenario... Alter!

> Ich sehe jedenfalls dauernd irgendwelche Angriffe in den Logs, die #
> nach irgendwelchen Scripten (PHPMyAdmin ist der Favorit) suchen.

Nö, siehst Du nicht. Du siehst nur ein paar automatisierte Idioten, die 
Deine Büchse mal freundlich befummeln.

> PHPMyAdmin ist drauf, aber in einer aktuellen Version und weit ab der
> Standard-Pfade.

die nach
> irgendwelchen Scripten (PHPMyAdmin ist der Favorit) suchen.

Security by Obscurity!

> Ich habe schon oft überlegt, einfach mal ein Fake-Script
> hinzustellen und zu schauen, was dann hinterherkommt, wenn diese
> Scan-Tools "fündig" werden.

Das ist eine tolle Idee für jemanden, der nicht den leisesten Hauch 
einer Ahnung von IT-Sicherheit hat. Also, "toll" hier für Bedeutungen 
äquivalent zu "Tollkische", "Tollhaus", "Tollwut"...

> Wie gesagt, ich weiß noch nicht ob das ganze wirklich sinnig ist

Haben das nicht genug Leute beantwortet?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> Ben, Du bist für die Sicherheit der
> Daten Deiner User verantwortlich. Ist Dir das klar?
Wenn nicht, würde ich mir über solchen Aufwand keine Gedanken machen - 
sondern die Daten unverschlüsselt speichern und davon ausgehen, der 
Webhoster kümmert sich schon um die Sicherheit.

Irgendwer muß die Daten lesen können - sei es nur zur Kontrolle wenn 
z.B. Unklarheiten über eine Bankverbindung besteht. Nur die Admins die 
Daten lesen zu lassen ist einfacher und meiner Meinung nach sicherer, 
als jeden einzelnen Benutzer nur seine Daten. Ansonsten müsste ich die 
doppelt speichern, einmal mit dem Benutzerkennwort verschlüsselt und 
dann nochmal für Admins oder zur automatisierten Verarbeitung. Da bringt 
nichts einen zusätzlichen Sicherheitsgewinn.

> Uiuiui, und wer durch Dein Portmapping kommt, hat Vollzugriff auf Dein
> komplettes internes Netzwerk. Wow.
Dieses Problem dürfte jeder Router haben.

> Ist das segmentiert?
Zwei Router und ein Gastnetz.

> Haben das nicht genug Leute beantwortet?
Nicht mit einem klaren ja  nein  wieso nicht.

So und wenn Du ja angeblich so viel Ahnung davon hast wie Du hier tust 
und ich ja so der IT-Security-Volldoof bin: Dann pack doch mal aus was 
ich machen soll. Ansonsten reagiere ich auf Deine Postings nicht mehr 
und dann hat sich das Problem erledigt. Dann mache ich mir das einfach 
und schiebe es dem Webhoster in die Schuhe. Soll der sich 'nen Kopf 
machen, daß die Datenbank und sein Server sicher ist.

von Sheeva P. (sheevaplug)


Angehängte Dateien:

Lesenswert?

Ben B. schrieb:
> Wenn nicht, würde ich mir über solchen Aufwand keine Gedanken machen

Okay, touche, da hast Du Recht. Entschuldige bitte.

> sondern die Daten unverschlüsselt speichern und davon ausgehen, der
> Webhoster kümmert sich schon um die Sicherheit.

Der kann und wird sich aber nur um die Sicherheit von System, 
installierten Standardpaketen (Apache/Nginx, MySQL/PostgreSQL, 
Python/PHP) kümmern. Wenn er sich auch um die interne Sicherheit Deiner 
Applikation(en) kümmern soll, dann bieten manche besseren Hoster das an, 
aber nur gegen den Einwurf von erheblichen Mengen sehr großer Münzen.

> Irgendwer muß die Daten lesen können - sei es nur zur Kontrolle wenn
> z.B. Unklarheiten über eine Bankverbindung besteht.

Ja. Sowas machen aber gemeinhin die Backoffice-Benutzer und nicht die 
Admins. Je kleiner der Kreis der Menschen ist, die diese Daten offen 
lesen können, desto besser. Nicht vergessen: je nach Schätzung kommen 60 
bis 90 Prozent aller erfolgreichen IT-Angriffe von innen.

> Nur die Admins die Daten lesen zu lassen ist einfacher

Ja, natürlich.

> und meiner Meinung nach sicherer, als jeden einzelnen Benutzer nur seine
> Daten.

Warum sollte es sicherer sein, wenn ein -- wie auch immer begrenzter -- 
Personenkreis die Daten aller Benutzer auslesen kann? Außerdem, wie soll 
das bitte stattfinden -- über ein eigenes Webfrontend für die Admins? 
Wie wird der Zugriff darauf geschützt, wie findet die Authentifizierung 
und Authorisierung statt -- etwa mit eigenen TLS-Zertifikaten?

> Ansonsten müsste ich die doppelt speichern, einmal mit dem
> Benutzerkennwort verschlüsselt und dann nochmal für Admins oder zur
> automatisierten Verarbeitung. Da bringt nichts einen zusätzlichen
> Sicherheitsgewinn.

Au contraire: wenn Du die verschlüsselten und die unverschlüsselten 
Daten -- bitte sieh oben unter "Trennung" -- auf verschiedenen Hosts 
speicherst. Es ist ohnehin immer eine gute Idee, den Webserver- und 
Applikationshost von dem Datenbankhost zu trennen, schon damit sie bei 
Zugriffen nicht um dieselben Ressourcen (CPU, Memory, I/O) konkurrieren 
müssen. Aber auch für die Sicherheit bietet das, wenn man es richtig 
macht, große Gewinne. (Und, ach ja: verschiedene VMs auf demselben Host 
sind dabei Augenwischerei.)

>> Haben das nicht genug Leute beantwortet?
> Nicht mit einem klaren ja  nein  wieso nicht.

Die Antwort ist ja auch ein klares Jaein. Ja, es hilft Dir vielleicht 
ein wenig gegen bestimmte Angriffsmuster. Aber, nein, gegen andere 
Muster wie eine Übernahme Deines Hosts nutzt das gar nichts. Die Frage 
ist hier, und sie bleibt es auch, welches Sicherheitsniveau Du erreichen 
möchtest.

> So und wenn Du ja angeblich so viel Ahnung davon hast wie Du hier tust
> und ich ja so der IT-Security-Volldoof bin: Dann pack doch mal aus was
> ich machen soll.

Trenn' das Zeug doch einfach, ein- oder zweistufig... siehe dazu unten.

> Ansonsten reagiere ich auf Deine Postings nicht mehr
> und dann hat sich das Problem erledigt.

Das löst nur das Problem, daß Du Dich über mich ärgerst. ;-)

> Dann mache ich mir das einfach
> und schiebe es dem Webhoster in die Schuhe. Soll der sich 'nen Kopf
> machen, daß die Datenbank und sein Server sicher ist.

Das tut jeder gute Hoster ohnehin so nach seinen besten Kräften. Schon 
weil es für den Hoster ausgesprochen geschäftsschädigend sein kann, wenn 
in den Medien etwas wie "$2und2 kümmert sich nicht um Sicherheit". Oder 
"100 Mio. Benutzerdaten wegen Sicherheitslücke bei "$Rachen" geklaut. 
Soetwas findet der handelsübliche Hoster überhaupt nicht lustig...


Okay, und jetzt das angekündigte "siehe unten"...

Im Anhang findest Du eine Grafik mit dem Namen "s.png". Du siehst dort 
drei Wolken, jede davon repräsentiert ein eigenes Netzwerk: einmal das 
Internet mit Deinen Usern, einmal Dein Office, und einmal ein eigenes 
kleines Netz bei Deinem Hoster. Die schwarzen Blitze sind 
Wide-Area-Verbindungen, und wie Du siehst, werden diese WAN-Verbindungen 
jeweils auf diesen kleinen roten Firewalls terminiert.

Und genau diese Firewalls (die auch in einem Gerät zusammengefaßt werden 
können) sind der eigentliche Clou an der Sache, denn: sie trennen Deine 
Netzwerke und lassen ausschließlich die Verbindungen zu, die wirklich 
notwendig sind. Ein User im Internet muß natürlich auf Deine Webseite 
zugreifen können, also läßt "fw_internet" den Zugriff auf HTTPS(!) zu. 
(HTTP ist eine andere Nummer; professionelle Applicationlayer-Firewalls 
können HTTP-Anfragen auf HTTPS umleiten und im Idealfall auch gleich TLS 
(früher: SSL) terminieren -- wie dem auch sei: dieser "fw_internet" läßt 
ausschließlich Zugriffe auf diesen einen Port des Webservers zu. Alle 
anderen Zugriffe werden natürlich nicht blockiert, sondern mit einem 
korrekten TCP Reset (RST) beantwortet. (Just saying.)

Über einen zweiten Kanal (hier als zweiter Firewall "fw_office" gezeigt) 
können Dein Backoffice, die Admins und / oder andere autorisierte Nutzer 
zugreifen, aber nur über ein VPN (oder eine ähnlich stark verschlüsselte 
und authentifizierte) Verbindung. Dabei bietet sich -- und wird etwa von 
gängigen Regularien zur Verarbeitung von Bank- und Kreditkartendaten 
vorgeschrieben -- eine Zwei-Faktor-Authentifizierung an, die in einer 
einfacherern Variante einfach ein OpenSSH mit "AuthenticationMethods 
publickey,password" (kein Leerzeichen hinter dem Komma, ansonsten siehe 
sshd_config(5)) sein könnte. Der Firewall "fw_office" läßt dabei dann 
ausschließlich für solcherart authentifizierte Nutzer auch einen Zugriff 
auf den Datenbank-Host "db" zu -- wahlweise auf die Datenbank, auf ein 
separiertes Admin-Interface, PhpMyAdmin, phpPgAdmin, PgAdmin4, oder SSH, 
whatever you like.

Wer noch mehr Sicherheit wünscht, nutzt auf "fw_internet" etwa einen Web 
Application Firewall wie etwa mod_security von Ivo Bosic vom OWASP ein. 
(Ohnehin ist OWASP.org immer eine gute Quelle, wenn man sich um 
Sicherheit von Webapplikationen sorgt, leider ist die Website gerade im 
Umbau.) Und dann gibt es natürlich noch verschiedene andere Optionen, 
die sich sehr gewinnbringend nutzen lassen; wenn man zum Beispiel keine 
Zugriffe aus Rußland oder China erwartet, kann man seinen "fw_internet" 
so einstellen, daß er Nutzer mit chinesischen oder russischen 
IP-Adressen abweist. Oder man kann mittels Log Monitoring proaktiv tätig 
werden und Benutzer nach drei fehlgeschlagenen Login-Versuchen abweisen. 
Oder, oder, oder.

Im Kern geht es bei diesem Konzept ausschließlich darum, den Traffic zu 
filtern, schon bevor er den Webserver erreicht -- und sicherzustellen, 
daß nur stark authentifizierte Benutzer den Datenbankserver erreichen 
können.

Und, ach so: in meiner simplen Grafik werden die beiden Firewalls als 
zwei verschiedene Systeme visualisiert, aber das muß natürlich nicht 
sein. Man kann die beiden auf demselben System vereinen, aber sie 
sollten jeweils unterschiedliche IP-Adressen und DNS-Namen haben. Dann 
hat man zwar immer noch die freundlichen Anklopfereien aus China, aber 
mit -- idealerweise paßwortgeschützten -- SSH Private Keys und 
zusätzlicher Paßworteingabe erreicht man ein durchaus akzeptables 
Sicherheitsniveau für geschützte Bereiche wir Kredit-, Bank- oder 
Gesundheitsdatenverarbeitung.

Diese Vorgehensweise verbessert die Sicherheit Deiner Webapplikation 
sehr deutlich und wohl stärker als eine symmetrische 
Datenbankverschlüsselung auf Applikationsebene...


Okay, die nächste Eskalationsstufe findest Du in der angehängten Datei 
"shs.png". Dort ist dann auch die Datenbank getrennt, so daß Angreifer, 
welche erfolgreich in Deinen Web- und / oder Datenbankhost eindringen 
konnten, noch einen weiteren Firewall überwinden müßten, um an Deine 
Klartextdaten zu kommen. Und: der Webhost und / oder der gecryptete (bzw 
gehashte, verkürzte, ...) Server können nur auf die entschlüsselte DB 
schreiben, sonst nichts -- nichtmal lesen. Hier ist allerdings ein sehr 
sorgfältiges internet Monitoring notwendig, um sicherzustellen, daß die 
Writes auch dort ankommen, wo sie sollen... Damit ist es auch für einen 
Angreifer, der durch Deinen Firewall hindurch Deinen Webserver bis auf 
Shellebene kompromittieren konnte, noch viel schwieriger, entschlüsselte 
Daten zu stehlen. Da würde ich die Firewalls allerdings tätsächlich auch 
trennen und auf verschiedenen Systemen laufen lassen... aber dann nähern 
wir uns einem Sicherheitsniveau wie bei Geheimdiensten. ;-)


Nebenbei: PGP und GPG bieten die Möglichkeit, Daten so zu verschlüsseln, 
daß sie von mehreren Empfängern gelesen werden können. Bei uns gibt es 
daher eine Datei "zugaenge.gpg", die jeder meiner Admins sie mit seinem 
eigenen GPG-Schlüsselpaar lesen kann... Und dann kann man noch lustige 
Dinge mit einem Trusted Platform Module machen -- und damit verhindern 
daß jemand, der sich Deine Festplatte aus dem Server geklaut oder sie 
aus dem Müll gezogen hat, sie in einem anderen Rechner auslesen kann, 
solange er nicht in den Besitz des TPM gekommen ist.


Ach so: Backups verschlüsseln nicht vergessen! ;-)


Wie dem auch sei: ich finde es sehr löblich, daß Du Dir so viele 
Gedanken darüber machst, wie Du die Daten Deiner Benutzer schützen 
kannst. Aber für Deinen Anwendungsfall gilt: Verschlüsselung erhöht die 
Hürden für einen Angreifer, aber nur dann, wenn die Infrastruktur sicher 
ist. Das ist nicht wie bei TLS / SSL, denn dabei geht es ja nur um die 
Sicherheit flüchtiger Daten während des Datentransfers. Bei Dir ist die 
Sache -- je nachdem, wie ernst Du es meinst -- wesentlich schwieriger, 
denn bei Dir geht es denn vielmehr darum, persistierte Daten zu schützen 
-- und sie trotzdem, auch für Dritte, zugänglich zu machen.

von sid (Gast)


Lesenswert?

Hm...
ehrlich gesagt versteh ich das ganze Problem nicht so richtig...
man kann doch bequem verschlüsselt speichern und lokal entschlüsseln,
wenn man muss (die die müssen).

Der Dienst für dessen db ich verantworklich zeichnete hatte ein 
ähnliches Problem ab der Sekunde wo Nutzer per Kreditkarte Zahlungen 
machen sollten/konnten..

Ich erzähl mal kurz wie ich das gelöst hab
(und bin offen für Verbesserungsvorschläge...)

Die meisten der phps auf dem Server prüfen sich gegenseitig;
(simpler file hash vergleich.. md5 weil schnell)
Sollte man also versuchen die Skripte zu ändern/ergänzen
muss man an dutzenden verschiedenen Orten schreiben um keine 
Fehlermeldung zu verursachen (manche frontend, manche email-alert, 
manche backend...)
das war schon vorher so... egal.

Alle Daten die im 'Bezahl'-php Skript eintrudeln und geprüft wurden,
werden vor dem speichern in der Datenbank per public key (RSA-1024)
verschlüsselt.
der private key befindet sich nicht auf dem Server

Der ist Teil einer lokalen (windoof) Applikation
Das hat mir am meisten Sinn gemacht...

die App selber ist an einen Hardwaretoken gekoppelt und 
Passwortgeschützt
(weil der Kunde das so wollte)

Der Kunde startet also die Applikation, steckt seinen USB Token ein
(in dem Fall ist es irgendein smartcard leser mit keycard... und ja.. 
ich weiss dass man die kopieren kann... aber stand so im Lastenheft ;))
Auf der Smartcard befinden sich (verschlüsselt) zudem 100 byte des 
private key (weil da ja platz satt ist ;)).

dann gibt er das SQL-user Passwort ein lädt die gewünschten Datensätze 
herunter (kann nur nach datum suchen)

Dann wird der noch verschlüsselte private key zusammengesetzt aus dem 
teil in der App un dem auf der Smartcard (nicht linear ;)),
und nach korrekter Passworteingabe entschlüsselt,
damit dieser dann im Gegenzug die heruntergeladenen Daten entschlüsseln 
kann. (was mir echt overkill erscheint ehrlich gesagt... aber so ist das 
nunmal)

Und bei jedem Start werden die md5 hashes der php skripte
mit den lokalen hashes (aus ner ini Datei) verglichen;
um eventuell geänderte Skripte zu erkennen.

Nach bestätigter Zahlung (button in der App)
werden Kreditarten nummern endgültig vom Server gelöscht;
(die letzten vier Ziffern und der Karteninhaber sowie Ablaufdatum 
bleiben dann als einziges verschlüsselt in der online DB)

Sinn: der Angreifer darf ruhig ein komplettes backup der db laden und 
auch die Skripte kopieren und lesen/auswerten...
er kann immernoch nicht an die 'sensiblen' Daten ran.
will er daten umleiten muss er (falls er es nicht VOR dem server tut)
mehr zeit investieren als er zunächst annahm ;)
und das taugt auch nur solange bis die App das nächste mal die 
Prüfsummen ausliest (was angeblich zweimal am Tag passiert) und Radau 
schlägt

Die App ist meines erachtens ein bisschen überladen;
ein passwort und ein lokales -verschlüsselt gespeichertes- zertifikat 
hätte mMn gereicht,
aber man tut ja wie einem geheissen, gell ;)

'sid

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.