Headdy: Eigene Mitgliederverwaltung und Sicherheit

Hallo Zusammen

Eigentlich würde ich nur gerne wissen, welche Bedenken es bezüglich Sicherheit in meinem Projekt gibt. Ein Problem für die Umsetzung sehe ich nicht, aber würde halt gerne wissen ob ich es sicherheitstechnisch so umsetzen sollte.

Ich habe vor, einen Webauftritt zu gestalten, in dem sich Benutzer registrieren können, um in einen Mitgliederbereich gelangen zu können (mit eigenem Profil), Forum, etc. Beim Registrieren werden die Daten (erstmal Nickname und PW) mit md5 verschlüsselt und in einer MySQL-Tabelle gesichert.
Die Funktionen zum Verbinden mit der Datenbank und die benötigten Tabellen-Funktionen stehen in php-Dateien, die wiederrum in htacces-geschützen Ordnern liegen und includet werden. So sollten die Funktionen auf den MySQL-Tabellen ja halbwegs unsichtbar sein, das ganze also relativ sicher.

Die ganze Seite soll mit SSL-Verschlüsselung laufen.
Will der Benutzer sich später anmelden (mit Login-Formular), werden die Eingabedaten in md5 verschlüsselt und mit dem Nickname/Passwort in der Datenbank verglichen. Wurde ein passender Eintrag gefunden, ist der Benutzer eingeloggt. Ich möchte das ganze ohne Sessions machen (da ich davon nicht viel Ahnung habe und in anderen Foren auf Beiträge mit Problemen bei Sessions gestoßen bin). Damit der Benutzer jedoch beim wechseln der Seiten trotzdem eingeloggt bleibt, müssen ja gewisse Daten (nur die nötigsten) per POST oder GET zur nächsten Seite übermittelt werden (nach dem Motto userpage.php?logged_in=1) :-). Ich denke da z.B. an einen zu übergebenden String, nach dem Prinzip md5(Timestamp+Nickname+Token) (sozusagen "Möchtegern-Session-ID"). Diese wird auch in der MySQL Benutzer-Tabelle temporär gespeichert,solange der Benutzer eingeloggt ist. Bei jedem Seitenwechsel wird dann dieser String per POST übergeben und mit dem in der Datenbank abgeglichen. Loggt sich der Benutzer wieder aus, so wird die "Pseudo-Session-ID" auf 0 gesetzt und eine Row namens "logged_in" auf false oder so ähnlich. So sollte es doch schwer möglich sein, von außen (als fremder Nutzer) in den  geschützen Bereich zu kommen, da dieser String ja nur temporär in der Benutzertabelle steht und schwer zu duplizieren ist. Die Pseudo-Session-ID müsste zum übertragen per POST dann jedoch auf jeder Seite in einem versteckten Formular schlummern. Da liegt mein Bedenken zur Sicherheit.

Damit es für den Benutzer möglich ist zu jeder beliebeigen Seite zu wechseln, müsste folgendes gegeben sein: Der Seitenlink auf den der Benutzer klickt, müsste eine Javascript-Fkt aufrufen, die im Pseudo-Session-ID-Formular, den action-Attribut ändert (auf die gewünschte Seite).

Ist dieses Script dann eine zusätzliche Sicherheitslücke?
Das Prinzip klingt für mich eigentlich relativ konsequent und unbedenklich bis auf die Session-String-Übergabe per Formular und POST.

Habe meinen Webspace bei Strato mit SSL und würde wegen der ständigen Übermittlung von POST-Daten die ganze Seite über SSL laufen lassen.
Danke fürs geduldige durchlesen des Romans.

  1. hallo,

    ich stand mal vor der gleichen frage und habe es, richtig oder falsch?, wie folgt vorerst gelöst

    Die ganze Seite soll mit SSL-Verschlüsselung laufen.
    Will der Benutzer sich später anmelden (mit Login-Formular), werden die Eingabedaten in md5 verschlüsselt ...

    md5 erstellt nur checksummen...somit kann jeder md5 wieder in deine ursprünglichen daten wandeln, probier mal lieber crypt(); denn damit ist auch aus der datenbank das passwort (z.b. bei blowfish verschlüsselung) nicht auslesbar und "sicherer" abgelegt

    sessions nutze ich auch nicht. ich nutze diverse angaben (Browserid, ip,...) die mir übermittelt werden und schreibe zusätzlich mehrere cookies (wiederrum mit crypt verschlüsselt) um den benutzer eindeutig zuzuordnen.

    bedenke bei der variante auch, dass sich nicht alle benutzer ausloggen und du da wiederrum eine sicherheitslücke hast. da wäre ein autologout (z.b. mit timestamp und einem zeitvergleich) hilfreich.

    viel erfolg

    cr

    1. Hallo

      Will der Benutzer sich später anmelden (mit Login-Formular), werden die Eingabedaten in md5 verschlüsselt ...

      md5 erstellt nur checksummen...somit kann jeder md5 wieder in deine ursprünglichen daten wandeln, probier mal lieber crypt(); ...

      ... welches, mit einer anderen Verschlüsselungsmethode genau das Gleiche macht.

      ... denn damit ist auch aus der datenbank das passwort (z.b. bei blowfish verschlüsselung) nicht auslesbar und "sicherer" abgelegt

      Aha.

      sessions nutze ich auch nicht. ich nutze diverse angaben (Browserid, ip,...) die mir übermittelt werden und schreibe zusätzlich mehrere cookies (wiederrum mit crypt verschlüsselt) um den benutzer eindeutig zuzuordnen.

      Die Browser-ID kommt vom Benutzer und kann gefälscht sein, bei mehreren Browsern übereinstimmen ...

      Die IP kann bei Verwendung eines Proxys andauern wechseln. Das ist z.B. bei AOL Standard.

      Tschö, Auge

      --
      Die deutschen Interessen werden am Liechtenstein verteidigt.
      Veranstaltungsdatenbank Vdb 0.2
      1. hallo!

        md5 erstellt nur checksummen...somit kann jeder md5 wieder in deine ursprünglichen daten wandeln, probier mal lieber crypt(); ...

        ... welches, mit einer anderen Verschlüsselungsmethode genau das Gleiche macht.

        deswegen ja blowfish ;-)

        ... denn damit ist auch aus der datenbank das passwort (z.b. bei blowfish verschlüsselung) nicht auslesbar und "sicherer" abgelegt
        Aha.

        ähm nicht nicht auslesbar sondern wenn auslesbar dann zumindest nicht ins klarschrift wandelbar ;-) sorry für die inkorekkte ausdrucksweise

        sessions nutze ich auch nicht. ich nutze diverse angaben (Browserid, ip,...) die mir übermittelt werden und schreibe zusätzlich mehrere cookies (wiederrum mit crypt verschlüsselt) um den benutzer eindeutig zuzuordnen.

        Die Browser-ID kommt vom Benutzer und kann gefälscht sein, bei mehreren Browsern übereinstimmen ...

        sicher gibt es überall probleme mit diesem system, wie auch in der ganzen it-welt...man sagte mir mal "ein pc ist wie eine frau, nur mit dem unterschied, dass er zumindest manchmal das tut, was er soll!"

        schönen abend!

        1. Hallo

          ... denn damit ist auch aus der datenbank das passwort (z.b. bei blowfish verschlüsselung) nicht auslesbar und "sicherer" abgelegt
          Aha.

          ähm nicht nicht auslesbar sondern wenn auslesbar dann zumindest nicht ins klarschrift wandelbar ;-) sorry für die inkorekkte ausdrucksweise

          Das gilt für md5 aber auch. Beide Systeme, crypt und md5, sind "Einwegverschlüsselungen", die, solange die Methoden nicht geknackt sind, nicht zurückwandelbare Strings ausgeben (von blowfish weiß ich nicht mehr, als dass es eine Verschlüsselungsmethode ist, kann dazu also auch nix sagen).

          sessions nutze ich auch nicht. ich nutze diverse angaben (Browserid, ip,...) die mir übermittelt werden und schreibe zusätzlich mehrere cookies (wiederrum mit crypt verschlüsselt) um den benutzer eindeutig zuzuordnen.

          Die Browser-ID kommt vom Benutzer und kann gefälscht sein, bei mehreren Browsern übereinstimmen ...

          sicher gibt es überall probleme mit diesem system, wie auch in der ganzen it-welt

          Naja, man muss sich die Lücke ja nicht wissentlich einbauen.

          Tschö, Auge

          --
          Die deutschen Interessen werden am Liechtenstein verteidigt.
          Veranstaltungsdatenbank Vdb 0.2
    2. Moin!

      Will der Benutzer sich später anmelden (mit Login-Formular), werden die Eingabedaten in md5 verschlüsselt ...

      md5 erstellt nur checksummen...somit kann jeder md5 wieder in deine ursprünglichen daten wandeln

      Das ist schlicht falsch. Aus dem Ergebnis von MD5 läßt sich der ursprüngliche Text nicht einfach wiederherstellen. Alle Methoden, MD5 irgendwie "zurückzurechnen", sind extrem zeit- und rechenaufwendig.

      probier mal lieber crypt();

      crypt() funktioniert im Prinzip identisch, wie MD5. Allerdings nutzt es nur die ersten 8 Zeichen des Passwortes, und ist daher viel leichter angreifbar, weil die Menge an nutzbaren Passworten endlich klein ist. Wenn man genügend schnelle Rechner hat, oder auch nur einen einzelnen und etwas mehr Zeit, kann man bei crypt-Hashwerten drauf warten, bis man das Ergebnis hat.

      Bei MD5 klappt das nicht!

      denn damit ist auch aus der datenbank das passwort (z.b. bei blowfish verschlüsselung) nicht auslesbar und "sicherer" abgelegt

      "Blowfish" ist eine reversible Verschlüsselung, d.h. damit kann man, wenn man das Passwort kennt, den Originaltext exakt wiederherstellen. Und das Passwort kennt man vermutlich, denn das muß die Applikation ja selbst benutzen, um neue Passworte in die Datenbank zu schreiben und auf Identität zu prüfen.

      Es ist eine ganz schlechte Idee, für Passworte einen Verschlüsselungsmechanismus zu verwenden, der zum Ver- und Entschlüsseln das gleiche Passwort benutzt.

      Und wenn man ein asymmetrisches Verfahren benutzt, gehört das Entschlüsselungspasswort selbstverständlich nicht auf den Server.

      sessions nutze ich auch nicht.

      Doch, tust du.

      ich nutze diverse angaben (Browserid, ip,...) die mir übermittelt werden und schreibe zusätzlich mehrere cookies (wiederrum mit crypt verschlüsselt) um den benutzer eindeutig zuzuordnen.

      Also doch wieder Sessions. Du generierst einen für den Benutzer eindeutigen Identifikator, und veranlaßt dessen Browser, diesen Identifikator bei jedem folgenden Request wieder zum Server zurückzuschicken, damit du die Session identifizieren kannst.

      Dass du dir was selbstgestricktes ausgedacht hast, macht die Sache nicht sicherer. Eher unsicherer.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
  2. Hallo

    Eigentlich würde ich nur gerne wissen, welche Bedenken es bezüglich Sicherheit in meinem Projekt gibt.

    Die Funktionen zum Verbinden mit der Datenbank und die benötigten Tabellen-Funktionen stehen in php-Dateien, die wiederrum in htacces-geschützen Ordnern liegen und includet werden. So sollten die Funktionen auf den MySQL-Tabellen ja halbwegs unsichtbar sein, das ganze also relativ sicher.

    Noch besser ist die Ablage der PHP-Skripte, mit denen man auf den Mechanismus schließen kann, außerhalb der DOCUMENT_ROOT. So kann zwar weiterhin über das Dateisystem aber nicht über HTTP(S) darauf zugegriffen werden.

    Ich möchte das ganze ohne Sessions machen (da ich davon nicht viel Ahnung habe und in anderen Foren auf Beiträge mit Problemen bei Sessions gestoßen bin).

    Der Sessionmechanismus von PHP funktioniert, sonst würde der, auch auf großen Seiten, nicht eingesetzt.

    Damit der Benutzer jedoch beim wechseln der Seiten trotzdem eingeloggt bleibt, müssen ja gewisse Daten (nur die nötigsten) per POST oder GET zur nächsten Seite übermittelt werden (nach dem Motto userpage.php?logged_in=1) :-).

    Grundsätzlich ist allen Daten, die vom Benutzer kommen, zu misstrauen. Das gilt insbesondere für POST- oder GET-Daten.

    Die Pseudo-Session-ID müsste zum übertragen per POST dann jedoch auf jeder Seite in einem versteckten Formular schlummern. Da liegt mein Bedenken zur Sicherheit.

    Da liegt es zurecht.

    Damit es für den Benutzer möglich ist zu jeder beliebeigen Seite zu wechseln, müsste folgendes gegeben sein: Der Seitenlink auf den der Benutzer klickt, müsste eine Javascript-Fkt aufrufen, die im Pseudo-Session-ID-Formular, den action-Attribut ändert (auf die gewünschte Seite).

    Ist dieses Script dann eine zusätzliche Sicherheitslücke?

    Es ist sowohl eine Sicherheitslücke, da jeder Besucher der Seite auf den Quelltext der JavaScript-Funktion zugreifen kann, als auch eine Barriere, denn es schließt, durch die zwingende Verwendung von JavaScript, Besucher aus, denen dies, aus welchen Gründen auch immer, nicht zur Verfügung steht.

    Beschäftige dich mit Sessions (so schwer ist das nicht), übermittle _nur_ die Session-ID (das .htaccess-Passwort ansich wird ja eigenständig übermittelt) und speichere alle Nutzdaten, die über mehrere Seiten hinweg notwendig sind aber noch nicht in der DB gespeichert werden sollen, im Session-Array auf dem Server.

    Tschö, Auge

    --
    Die deutschen Interessen werden am Liechtenstein verteidigt.
    Veranstaltungsdatenbank Vdb 0.2
  3. Hi Headdy,

    Beim Registrieren werden die Daten (erstmal Nickname und PW) mit md5 verschlüsselt und in einer MySQL-Tabelle gesichert.

    Es gibt keinen Grund, den Nicknamen zu verschlüsseln. Der Zweck des Verschlüsselns in der Datenbank ist, dass ein Blick in die Datenbank nicht die "Login-Informationen" freigibt. Dafür reicht es, das Passwort zu verschlüsseln. Den Nicknamen eines Benutzers wirst Du aber eventuell brauchen können, um Ihn anzureden. Nicknamen ist keine geheimen Daten (Nach dem Login hättest Du ihn ggf. auch so zur Verfügung, aber für eventuelle automatische Emails o.ä. bräuchtest Du ihn aus der Datenbank).

    Ich möchte das ganze ohne Sessions machen (da ich davon nicht viel Ahnung habe und in anderen Foren auf Beiträge mit Problemen bei Sessions gestoßen bin).

    Wenn Du Sicherheitsprobleme meinst - die wirst Du alle auch mindestens gleichermaßen mit Deiner Konstruktion haben. Ich sehe nicht den geringsten Vorteil Deines Planes, eine Sassion "von Hand zu bauen", gegenüber einer PHP-Session. Im Gegenteil, wenn Du da nicht genau weißt, was Du tust, kannst Du Dir damit große Probleme schaffen. Und weniger komfortabel ist es so oder so. Zwei Apskte, die mir spontan einfallen:

    • Du würdest, wenn ich Dich richtig verstehe, alle sessionbezogenen Daten in der Datenbank speichern. Da brauchst Du ein gutes Datenbankdesign oder Du wirst sehr unflexibel, was eventuelle Weiterentwicklungen der Website angeht.

    • Du musst gut aufpassen, dass Deine generierten Session-IDs eindeutig sind. Mit Deinen md5-Ansätzen zur Erzeugung verlässt Du Dich dabei auf die Stochastik (oder willst Du bei jedem Erzeugen alle existierenden IDs vergleichen?). Das wird wahrscheinlich gutgehen in der Praxis, aber sauber ist es nicht.

    Die Pseudo-Session-ID müsste zum übertragen per POST dann jedoch auf jeder Seite in einem versteckten Formular schlummern. Da liegt mein Bedenken zur Sicherheit.

    Ein grundsätzliches potentielles Sicherheitsproblem jeder Session (ob PHP- oder "von Hand gebaut" oder was auch immer) ist: Der Benutzer muss sich bei seinem HTTP-Request identifizieren, d.h. eine Information (die Session-ID) schicken, die (im besten Fall) nur er kennt. D.h. man kommt nicht drumrum, dass die ID, während ein Benutzer eingeloggt ist, irgendwo im Client-Rechner zu finden ist - sei es in einem Cookie oder im beim letzten Request gesendeten Quellcode. Wenn nun andere Leute Zugang zu dem Rechner haben, dann können sie gegebenenfalls die ID herausfinden. Das ist nicht schön, aber nicht zu vermeiden.

    Damit es für den Benutzer möglich ist zu jeder beliebeigen Seite zu wechseln, müsste folgendes gegeben sein: Der Seitenlink auf den der Benutzer klickt, müsste eine Javascript-Fkt aufrufen, die im Pseudo-Session-ID-Formular, den action-Attribut ändert (auf die gewünschte Seite).

    Ist dieses Script dann eine zusätzliche Sicherheitslücke?

    Nicht wirklich. User könnten das Skript zwar manipulieren, aber da hätten sie nicht viel von. Wenn sie das Ziel eines "Links" oder die Session-ID für den nächsten Request manipulieren wollten, können sie gleich das Formular direkt manipulieren und abschicken. Aber es ist extrem umständlich (denke z.B. daran, dass auch alle eventuellen echten Formulare, die Du irgendwo verwendest, mit der Session-ID gefüttert werden müssten), und bringt den generellen Der-User-braucht-JavaScipt-Nachteil mit sich.

    Ich rate Dir also energisch von diesem Eigenbau der Sessions ab.

    viele Grüße
    der Bademeister

  4. echo $begrüßung;

    Die Pseudo-Session-ID müsste zum übertragen per POST dann jedoch auf jeder Seite in einem versteckten Formular schlummern.

    Neben dem bisherigen Abraten ist das hier ein Punkt der zu Folgeproblemen führt. Nehmen wir an, dass du generell POST-Requests durch die Gegend sendest, damit die Session-ID nicht in der URL landet. Wenn nun ein Besucher in der History zurückblättern möchte, bekommt er immer die Frage, ob er die POST-Daten noch einmal senden möchte. Diese Abfrage wirst du nicht wegbekommen. Der Cookie-basierte Ansatz hingegen, der zur Not auf die URL ausweicht, mit "normalen" GET-Requests arbeitend, hat dieses Problem nicht.

    Da liegt mein Bedenken zur Sicherheit.

    Bedenken zu irgendeinem Thema lassen sich dadurch ausräumen, indem man sich über das Thema informiert und es letzlich verstanden hat, sowie weiterhin am Ball bleibt, um beim aktuellen Stand - hier des Sicherheitswettrüstens - mitzuhalten. Ein eigenes bedenkenbeladenes Konzept, das in der Praxis nicht getestet ist, ist sicher kein gutes.

    echo "$verabschiedung $name";

    1. Ich bedanke mich für euer Engagement und die guten Infos. Werde mich dann wohl ab jetzt mit Sessions beschäftigen. Ein paar Fragen hätte ich noch (auch hier schonmal danke für eventuelle Antworten):

      1.Was haltet ihr von dieser Beschreibung (Profi-Skript):
      http://www.traum-projekt.com/forum/73-workshops-und-tutorials/112212-tutorial-login-systeme-einfach-profi.html

      2.Stimmt es, dass das Erreichen versteckter Benutzerseiten mit Sessions nur auf dem Prinzip basiert, dass auf jeder sensiblen Seite mit session_start(); etc. der Benutzer validiert wird? Heißt dass, der Schutz basiert nur auf einer Folge von php-Funktionen und ohne htacces o.ä? Dann würden die Dateien (z.B. edituserprofile.php) ja in nicht-passwortgeschützten Ordnern liegen. Falls die Mitgliederbereichs-Seiten in htacces-geschützten Ordnern liegen würden, müssten die Benutzer doch neben ihren Logindaten zusätzlich noch die htacces-Abfrage ausfüllen oder? (Hoffe ihr wisst was ich meine). Habe anscheinend Probleme, das Grundprinzip von Sessions zu verstehen.

      Danke und Gruß
      Headdy

      1. Hallo,

        2.Stimmt es, dass das Erreichen versteckter Benutzerseiten mit Sessions nur auf dem Prinzip basiert, dass auf jeder sensiblen Seite mit session_start(); etc. der Benutzer validiert wird? [...] Habe anscheinend Probleme, das Grundprinzip von Sessions zu verstehen.

        vielleicht hilft Dir dieser Artikel in SELFHTML aktuell weiter:
        http://aktuell.de.selfhtml.org/artikel/php/loginsystem/

        Freundliche Grüße

        Vinzenz

      2. echo $begrüßung;

        1.Was haltet ihr von dieser Beschreibung (Profi-Skript):
        http://www.traum-projekt.com/forum/73-workshops-und-tutorials/112212-tutorial-login-systeme-einfach-profi.html

        Ich habe es nur überflogen, sah jedoch recht passabel aus.

        2.Stimmt es, dass das Erreichen versteckter Benutzerseiten mit Sessions nur auf dem Prinzip basiert, dass auf jeder sensiblen Seite mit session_start(); etc. der Benutzer validiert wird? Heißt dass, der Schutz basiert nur auf einer Folge von php-Funktionen und ohne htacces o.ä? Dann würden die Dateien (z.B. edituserprofile.php) ja in nicht-passwortgeschützten Ordnern liegen. Falls die Mitgliederbereichs-Seiten in htacces-geschützten Ordnern liegen würden, müssten die Benutzer doch neben ihren Logindaten zusätzlich noch die htacces-Abfrage ausfüllen oder? (Hoffe ihr wisst was ich meine). Habe anscheinend Probleme, das Grundprinzip von Sessions zu verstehen.

        Ob die Seiten nun versteckt sind oder nicht, mit HTTP-Authentication versehen oder nicht, wann immer du auf einer Seite auf die Session-Daten zugreifen willst, ist ein session_start() erforderlich. Einige denken, ihre Anwender mögen die HTTP-Authentication nicht und müssen statt dessen ein eigenes Login-System nachbauen, dass sich auch besser in die Seite integriere. Http-Auth liefert ja bei jedem Request die Anmeldedaten mit. Sessionbasiert wird nur die Session-ID übertragen, zu der sich dann der Server interessierende Daten merkt, unter anderem auch den Anmeldestatus, wenn man die Session dafür verwendet.

        echo "$verabschiedung $name";

  5. Moin!

    Ich habe vor, einen Webauftritt zu gestalten, in dem sich Benutzer registrieren können, um in einen Mitgliederbereich gelangen zu können (mit eigenem Profil), Forum, etc. Beim Registrieren werden die Daten (erstmal Nickname und PW) mit md5 verschlüsselt und in einer MySQL-Tabelle gesichert.

    Die Frage wäre, ob es schlau ist, auch den Nickname durch MD5 zu jagen. Das Resultat wäre, dass du keinerlei Zuordnung mehr hast, welcher User bzw. Username mit welchem Eintrag der Usertabelle in Zusammenhang steht.

    Will der Benutzer sich später anmelden (mit Login-Formular), werden die Eingabedaten in md5 verschlüsselt und mit dem Nickname/Passwort in der Datenbank verglichen. Wurde ein passender Eintrag gefunden, ist der Benutzer eingeloggt. Ich möchte das ganze ohne Sessions machen (da ich davon nicht viel Ahnung habe und in anderen Foren auf Beiträge mit Problemen bei Sessions gestoßen bin).

    Es geht aber nunmal nicht ohne Session. Das, was du da beschreibst, ist ein selbstgebauter Sessionmechanismus, dem ich pauschal erstmal attestiere, dass er viel mehr Probleme macht, als der in PHP standardmäßig eingebaute Mechanismus, denn der ist millionenfach getestet und funktioniert in 99% aller Fälle problemlos.

    Dass du ihn noch nicht magst, weil du ihn noch nicht kennst, kann man ja ändern.

    Am allerekligsten finde ich dabei, dass du deshalb alle Seitenaufrufe per POST-Request machen willst. Das bringt einen dermaßenen Zusatzaufwand mit sich, dass man keine Sekunde darüber nachdenken muß, was besser zu verwenden ist: Natürlich der PHP-Mechanismus, nicht deine Idee.

    Abgesehen davon: Benutzer können durch nicht beeinflussbare Umstände daran gehindert sein, sich ordnungsgemäß auszuloggen. Ein Mechanismus, der fix "User ist drin" oder "User ist draußen" in einen Permanentspeicher schreibt, birgt Risiken, weil diese Information einfach auch falsch sein kann.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."