Ankündigung

Einklappen
Keine Ankündigung bisher.

Wie Member-Bereich schützen?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Wie Member-Bereich schützen?

    Hi! Ich hoffe das ist das richtige Forum für diese Diskussion.

    Meine Anwendung soll einen geschützten Member-Bereich haben. Die Benutzer verwalte ich mit einer MySQL-Datenbank. Die Sessions speichere ich in der Datenbank (keine Session-Cookies => kein Session-Hijack möglich). Es stellt sich die Frage, wie ich den Content (Bilder, Videos) im Member-Bereich schützen kann.

    Die folgenden Konzepte habe ich mir überlegt.
    1. Schutz des Member-Bereichs mit htaccess und einer htpasswd-Datei
      Vorteil: Recht einfach. Funktioniert zuverlässig. Es gibt vorgefertigte Tools, die die Benutzer der htpasswd-Datei hinzufügen.
      Nachteil: Keine Benutzer-Datenbank benötigt. Keine Information über Benutzer speicherbar. (Oder es wird eine Synchronisation der Datenbank mit der htpasswd-Datei benötigt.) Scheidet deshalb aus.
    2. htaccess mit Auth MySQL
      Vorteil: Integration der Nutzerdatenbank.
      Nachteile: Setzt mod_auth_mysql Apache Modul voraus. Ausserdem muss sich der Benutzer wohl zweimal anmelden (einmal auf der Seite und einmal, wenn er auf den geschützten Content zugreifen will).
    3. Laden des geschützten Contents mit PHP
      Vorteil: Einfach zu realisieren (richtige Header setzen + readfile()).
      Nachteil: Bei jedem Zugriff muss der Benutzer authentifiziert werden. Es fällt also bei jedem Zugriff auf ein einzelnes Bild eine Datenbankabfrage an (die Sessions speichere ich ja wie gesagt in der Datenbank).
      Ausserdem wird bei jedem Aufruf eines Bildes der PHP-Interpreter gestartet. Generell mag ich Ausgabe von Dateien mit PHP nicht so sehr. Funktionieren da progressive Jpegs? Erscheint mir nicht so.
    4. Den Member-Bereich nicht schützen, aber den Content verschleiern
      Mit einem Cron-Job oder PHP könnte ich periodisch entweder die einzelnen Bilder oder nur deren Verzeichnisse umbenennen.
      Vorteile: Schutz vor Hotlinking. Wenn Nutzer meinen, sie könnten die Bilder verlinken, könnte man dadurch ein wenig zusätzlichen Traffic bekommen.
      Nachteile: Kein echter geschützter Bereich. Cron-job muss installiert werden oder das ganze mit PHP realisiert werden.
    5. Die Sessions doch nicht in der Datenbank speichern und damit die User authentifizieren?
    6. Kombination aus den obigen Möglichkeiten?


    Leider sagen sie mir alle nicht 100% zu. Am ehesten entspricht htaccess mit Auth MySQL dem, was ich machen möchte. Leider kann ich jedoch das Apache Modul nicht voraussetzen. Den Benutzer bei jedem Aufruf eines Bildes mit einer Datenbankabfrage zu authentifizieren halte ich jedoch für nicht sinnvoll. Auch das Laden durch PHP könnte zu viel Server-Last produzieren.

    Ich kenne definitiv Seiten, die nicht einfach eine htaccess-Datei benutzen um den Member-Bereich zu schützen. Genauso wie bei mir kann man sich auf diesen Seiten mit einem html-Formular für Username und Passwort anmelden. Nach Anmeldung wird der Member-Bereich freigeschaltet. Genauso soll es auf meiner Seite auch sein. Leider kann ich den Quellcode nicht einsehen und weiss nicht, wie die das realisiert haben.

    Hat jemand eine Idee?


  • #2
    Zitat von chunky Beitrag anzeigen
    (keine Session-Cookies => kein Session-Hijack möglich)
    Wo die Sessiondaten auf dem Server gespeichert werden ist mehr oder weniger egal. Sessions laufen immer per Cookie ab (außer bei einer SESSIONID in der URL, ist aber unschön) von daher ist es irrelevant wo du die Daten auf dem Server speicherst.

    Zitat von chunky Beitrag anzeigen
    Funktionieren da progressive Jpegs? Erscheint mir nicht so.
    Was sollte da anders daran sein? Binärdaten schleust du einfach durch PHP.

    Zum authentifizieren solltest du ganz normal Sesssions nutzen, somit kannst du deine internen Bereiche schützen (ganz normal wie auf fast jeder Seite).

    Wenn du einzelne Dateien schützen möchtest hast du ja deine Möglichkeiten schon genannt. htaccess -> sehr unschön wenn der User sich für jede Datei nochmal einloggen muss, durch PHP schleusen => wohl die einzigste machbare Alternative. Wurde aber schon zig mal hier im Forum besprochen also bitte Suche benutzen.

    Kommentar


    • #3
      Zitat von chunky Beitrag anzeigen
      Die Sessions speichere ich in der Datenbank (keine Session-Cookies => kein Session-Hijack möglich).
      Vorschlag: Mach' mit dem Vorhaben weiter, wenn du Sessions verstanden hast.

      Kommentar


      • #4
        für mich würde als einzige und venünftige ideen die idee 3 in denn sinn kommen.
        Eine Db Abfrage mehr oder weniger macht auch keinen großen unterschied

        Und zu Session: Eine SessionID wird immer in einem Cookie bzw. in der URL gespeichert. Also eine SessionId kann man ganz leicht verfälschen da nützt auch keine Db etwas ...

        Kommentar


        • #5
          Zu den Sessions wurde ja schon genug gesagt, ich möchte einfach mal 'nen Link weitergeben: Login System.

          Wenn du dir "das System für Profis" anguckst, und das als Vorlage nimmst, kann man damit recht einfach und gut einen Memberbereich absichern. Es reicht aber nicht, einfach alles zu kopieren und zu hoffen, dass es klappt. Du musst es verstehen und wahrscheinlich auch das ein oder andere (an deine Vorstellungen) anpassen.

          Kommentar


          • #6
            Zitat von chunky Beitrag anzeigen
            Laden des geschützten Contents mit PHP
            Vorteil: Einfach zu realisieren (richtige Header setzen + readfile()).
            Nachteil: Bei jedem Zugriff muss der Benutzer authentifiziert werden. Es fällt also bei jedem Zugriff auf ein einzelnes Bild eine Datenbankabfrage an (die Sessions speichere ich ja wie gesagt in der Datenbank).
            Diese Methode kann man auch etwas anders lösen ohne dass Datenbankabfragen nötig werden, indem man die Authentifizierungsinformationen in ein Token packt und anfügt, dann wird nur eine Ver- und eine Entschlüsselung pro Content benötigt, was mittlerweile auch in PHP nicht mehr so viel Zeit kostet! Dieses Token könnte dann einen Verweis auf den angeforderten Content und eine Gültigkeitsdauer enthalten und wird mit einem Serverschlüssel verschlüsselt. Diesen Schlüssel kann man auch regelmäßig wechseln um Bruteforceangriffe auszuschließen. Zudem könnte man aus einem Servergeheimnis und der IP des Benutzers einen Session-Key ableiten und würde den Content dadurch auf einen Benutzer fixieren (je nach Wunsch/Anforderung)!

            Kommentar


            • #7
              Ich würds über folgende, bereits oben beschriebene, Varianten machen:

              htaccess
              Bei jedem erfolgreichen Login wird die htaccess geupdated. Du schreibst also die IPs aller eingeloggten Nutzer (session table in DB) in die passende htaccess-Datei. Somit hat jeder Zugriff auf die Bilder / Videos wer eingeloggt ist.

              Filehandler
              Du hast eine PHP Datei welche die Bilder / Videos nach einem erfolgreichen Sessioncheck via fpassthru durchreicht.

              Hab beides bereits verwendet und klappt gut. Was man auch machen kann ist, Bilder / Videos nicht im klartext speichern. Also statt einen Dateinamen "meinbild.jpg" speichert man "da1d8a84f865d8af309d1c0dc3ea30fe.jpg". In einer Datenbank steht dann wie die Datei wirklich heißt. Will jemand also an eine der Dateien ran, so wirds kompliziert da er die Namen raten darf.

              Kommentar


              • #8
                Das mit den Sessions war mein Fehler. Habe die Cookies dabei nicht bedacht.

                Danke für die vielen interessanten Hinweise.

                Zitat von luks2com Beitrag anzeigen
                für mich würde als einzige und venünftige ideen die idee 3 in denn sinn kommen.
                Eine Db Abfrage mehr oder weniger macht auch keinen großen unterschied
                Hmm, ich weiss nicht so recht. Die Seite wird tausende von Bildern haben. Und bei jedem Zugriff auf ein Bild würde nicht nur eine DB-Abfrage anfallen. Es sollten schon zwei sein (eine für den Vergleich des Passworts und eine andere, die veraltete Sessions löscht). So ist das zumindest zur Zeit bei meinem Login System.

                Interessant wäre natürlich die Möglichkeit, mit einer Datenbank bestimmte Statistiken für jedes Bild zu sammeln. Wie Anzahl der Views, oder eventuell Ratings für jedes Bild.


                Die htaccess-Datei dynamisch zu updaten habe ich mir auch schon überlegt. Das würde mir eigentlich am besten gefallen, weil ich da sicher sein kann, dass man die Bilder nicht hotlinken kann oder sonst auf sie zugreifen kann.
                Beim Login könnte ich auch recht einfach den Nutzer in die htaccess einfügen. Jedoch muss ich auch die Nutzer wieder entfernen. Die sollen schliesslich ja nicht ewig Zugang haben. Das wird dann schon etwas komplizierter. Es müssten bei jedem Login alle aktiven Nutzer überprüft und in die htpasswd-Datei geschrieben werden. Ist nicht unmöglich, klingt aber vergleichsweise langsam.

                Ist es nicht irgendwie möglich einen Benutzer direkt beim Login aus PHP heraus an einem durch htaccess geschützten Bereich anzumelden?

                Kommentar


                • #9
                  @chunky: Dann möchte ich noch einmal meine Idee bewerben, weil du damit alle deine Wünsche abdecken kannst, indem du alle Infos in ein Token packst!

                  Kommentar


                  • #10
                    Zitat von Broady Beitrag anzeigen
                    Also statt einen Dateinamen "meinbild.jpg" speichert man "da1d8a84f865d8af309d1c0dc3ea30fe.jpg". In einer Datenbank steht dann wie die Datei wirklich heißt.
                    Das ist auch ganz interessant. Danke für den Hinweis. Ich habe so etwas auf einer anderen Seite gesehen. Jedoch bin ich davon ausgegangen, dass die Bilder tatsächlich so lange Namen haben, weil ich dachte, der Update-Prozess würde die Bilder so benennen. Kann natürlich sein, dass die so etwas verwenden.

                    @Sirke:
                    Die Token-Lösung hört sich interessant an, ja.
                    Ganz verstehen tue ich das jedoch nicht. Da muss doch immer mindestens ein Teil des Tokens aus der Datenbank kommen, oder? Wenn der Token z.B. aus Usernamen, IP und Zugangszeitraum zusammengesetzt ist, dann muss ich den Zeitraum aus der Datenbank holen. Wenn ich keinen Zeitraum angebe, dann muss ich zumindest den Status (aktiv oder inaktiv) des Nutzers abfragen... Hmm... Es sei denn ich speichere den Token wie die Session ID in einem Cookie beim Login. Aber so kannst du das nicht gemeint haben (weil du von einem Content-spezifischen Token für die einzelnen Bilder sprichst).

                    Der Server-Key muss jedoch trotzdem aus der Datenbank kommen. Wenn ich den nach irgendeinem System generiere, dann kann man ihn leicht ausspähen (der Quellcode wird offengelegt sein).

                    Kommentar


                    • #11
                      Ja, du hast das schon fast richtig verstanden, aber der Server-Schlüssel wird im PHP Quellcode gespeichert und der Quellcode kann dennoch offen sein, weil es ein Konfigurationsparameter ist, welcher jederzeit von jedem angepasst werden kann!
                      Dadurch erlangt jede PHP Datei Zugriff auf den Server-Schlüssel und kann Daten ver- und entschlüsseln. Zugriff auf den Schlüssel hat nur der Admin oder ein Hacker welcher Zugriff auf den FTP hat und dann ist es eh zu spät, weil er den Content auch so auslesen kann.

                      Nun die Beschreibung meiner Idee: Auf der Hauptseite wird normalerweise der Content eingebunden, indem man beispielsweise <img src="bild.jpg"/> ausgibt. Damit dieser Content geschützt wird, kann man diesen verschlüsseln und den verschlüsselten String an eine PHP Datei übergeben, welche den String entschlüsselt und dann das Bild weiterreicht. Anstatt jedoch dann "nur" den Dateinamen zu verschlüsseln kann man weitere Informationen mitverschlüsseln wie IP, Zeitstempel o.ä. welche alle ausgewertet werden und nur für den Fall aller korrekter Überpüfungen wird dann der Content durchgereicht.

                      Die PHP Datei welche das Token auswertet, geht dann IMMER davon aus, dass ein Token nur authentische Infromationen enthält, also von der Hauptseite nur für authentifizierte Benutzer erstellt, dadruch wird eine Datenbanküberprüfung nicht notwendig bzw wird bereits auf der Hauptseite durchgeführt.

                      Notwendig ist also eine Überlegung wie das Token aussieht, also wie man am Besten die benötigten Infos übergibt, mit dem Hintergedanken von Erweiterbarkeit und Spezialisierung, falls man z.B. Content nicht auf eine IP einschränken möchte, aber Zeitlich begrenzen möchte o.ä. Dazu kommt dann ein vernünftiger Verschlüsselungsalgorithmus (z.B. AES) und ein vernünftiger MAC (z.B. HMAC-SHA1) bzw vernünftige Prüfsumme (SHA1). Es ist zudem sinnvoll den Token vor dem Verschlüsseln zu komprimieren, damit man etwas Traffic der sonst langen Token sparen kann...

                      Ich habe das ganze mal sehr abstrakt beschrieben, da keine Implementierung zu Hand, daher bei Fragen ruhig raus damit...
                      ...und alle die Denkfehler entdecken bitte melden!

                      Kommentar


                      • #12
                        Die Frage bleibt aber: Wenn Du dieses Pattern für den User-Auth basierten Zugriff einsetzen willst, musst Du auch den Userstatus mit im Token verwursten. Und beim Aufruf diesen natürlich auch bestimmen.
                        --

                        „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                        Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                        --

                        Kommentar


                        • #13
                          Zitat von nikosch Beitrag anzeigen
                          Die Frage bleibt aber: Wenn Du dieses Pattern für den User-Auth basierten Zugriff einsetzen willst, musst Du auch den Userstatus mit im Token verwursten. Und beim Aufruf diesen natürlich auch bestimmen.
                          Jain, das kommt auf die mit diesem Konzept verbundenen Annahmen an!

                          Ich habe das ganze jetzt einmal auf die Schnelle umgesetzt: Das Token ist ein Objekt mit den Eigenschaften $_content und $_timeout (hier sind selbstverständlich weitere Eigenschaften möglich) und den zugehörigen Settern und Gettern. Außerdem habe ich eine Klasse TokenHandler/TokenFactory erstellt mit den Methoden encrypt() und decrypt(). Die Methode encrypt() bekommt ein Object Token übergeben, serialisiert und komprimiert dieses, verschlüsselt den erstehenden String und codiert den Ciphertext in ein darstellbares Format (z.B. Hex, Base64). Die Methode decrypt() bekommt einen verschlüsselten String übergeben und läuft die Schritte in umgekehrter Reihenfolge ab und gibt am Ende ein Token zurück. Der Schlüssel für Ver- und Entschlüsselung ist ein Hash aus einem Servergeheimnis und der IP Addresse des Requests.
                          Ein Token wird nun in der Hauptseite erstellt und verschlüsselt und per GET an eine andere Seite übergeben, welche den Token entschlüsselt und die Informatione auswertet: Existiert der Content? Ist die Zeit bereits abgelaufen? etc.
                          Unter der Annahme, dass Token nur erstellt und verschlüsselt werden wenn der Content von einem Benutzer gelesen werden darf, dann sind keine weiteren Informationen wie Status und Rechte eines Benutzers von Nöten.
                          Viele Gedanken kann man sich nun zu dem Token an sich, dem "Nachrichtenformat" bzw der Serialisierung, der Verschlüsselung und ähnlichem machen!

                          Ich fand diese Ansatz ganz interessant, weshalb ich ihn einmal umgesetzt habe und muss sagen, dass diese Möglichkeit viel Potential bietet und bereits in dieser kleinen Form einen Content nur einer IP Addresse für einen begrenzten Zeitraum zugänglich macht ohne weitere Datenbankabfragen zu benötigen!

                          Kommentar


                          • #14
                            Das wird dann problematisch, wenn dein Besucher AOLer ist und bei jedem HTTP-Request mit einer neuen IP angerannt kommt.
                            PHP-Code:
                            if ($var != 0) {
                              
                            $var 0;

                            Kommentar

                            Lädt...
                            X