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?
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ß.
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
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
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.
Sheeva P. schrieb: > Nur dann, wenn die Ver- und Entschlüsselung clientseitig passiert. ... NICHT clientseitig ... Entschuldigt bitte.
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.
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?
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
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.
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.
Der Poster scheint nicht wirklich eine grosse Ahnung zu haben. Einfach mal etwas verschluesseln, egal wie und wozu ..
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.
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.
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?
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.
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!
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.
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!
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
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.
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.
Ich verstehe immer noch nicht, wie du "durchsuchbar" und "jedes Passwort entschlüsselt nur ein Feld" erreichen willst.
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
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.
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.
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.
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.
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?
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.
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?
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.
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, ...).
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.
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.
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?
@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
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.
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. ;-)
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. ;-)
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
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.
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.
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.
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.
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. ;)
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
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 ...
Weil mir beim Geburtsdatum eine einzige Fehlermeldung reicht nachdem ich alle drei Bestandteile davon geprüft habe.
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.
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.
> 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.
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...
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.
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.
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
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.
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. ;-)
> 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.
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?
> 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.