Nico R.: Bild nur anzeigen mit Berechtigung

Hallo liebes Forum,

ich speichere in einem Ordner QR-Codes von Benutzern. Die Benutzer generieren sich den Code über ein Formular, ein Script speichert den Code im Ordner qr_img auf dem Server und verschickt ihn dann per E-Mail-Anhang an den Benutzer.

Ich möchte den Nutzern nun eine bequeme Möglichkeit anbieten, auf ihrem Smartphone vom Startbildschirm aus per App-Symbol den Code anzuzeigen. Das geht auf jeden Fall mit einem Link. Dass man ein Bild oder PDF-Dokument so ablegen kann, ist mir nicht bekannt. (Oder kennt jemand eine Möglichkeit?). Eventuell geht das beim iphone über "Kurzbefehle". Aber wenn ich schon keine Lust habe, mich damit zu beschäftigen, wirds wohl ein Nutzer erst recht nicht tun. Einen Website-Link auf den Startbildschirm zu packen ist dagegen eine Sache von zwei oder drei Klicks.

Also eine Website… Wenn ich als Link www.example.com/qr_img/13.png anbiete (13 ist die ID des Nutzers), kann der sich natürlich munter alle möglichen anderen Codes anzeigen lassen. Gibt es die Möglichkeit 1, den img-Ordner so zu "konfigurieren", dass sich Bilder dort nur per PHP-Script aufrufen lassen? Dann könnte ich ja z.B. das Erstellungsdatum des Codes als Parameter mitgeben: www.example.com/qr_img/13.png?filemtime=1680787822

Möglichkeit 2 wäre vielleicht, jeden Code in einem einzelnen Ordner abzulegen: www.example.com/qr_img/1680787822/13.png. Die Variante fand ich nicht so schön, weil ich so keinen Überblick habe, in welchem Ordner sich welcher Code befindet. Aber wo ich das jetzt so schreibe, fällt mir ein, dass ich den Ordner ja auch 13_1680787822 nennen könnte. Hmmm, dann mach ich das doch vermutlich so...

Oder hat jemand eine bessere Idee? Bis jetzt war das immer der Fall :-)

Beste Grüße

Nico

  1. Oder hat jemand eine bessere Idee? Bis jetzt war das immer der Fall :-)

    Darf ich die Frage stellen, ob es in irgendeiner Form notwendig ist, dass der NUR die berechtigte Person NUR den ihr zugeordneten QR-Code sehen kann?

    Wenn es so ist, dann

    1. ist jede der von Dir gezeigte Möglichkeiten mit dem „Geheimnis“ in der URL untauglich. Denn die taucht trotz HTTPS z.B. in der Browserhistorie und seltener sogar in Proxys (Ups. Ja! Ausgerechnet in transparenten Zwangsproxies stark sicherheitsbewusster Organisationen) auf und kann in jedem Fall bei der Eingabe von unberechtigten Dritten mit Augen oder Kameras gesehen werden.
    2. kommt die Frage auf, wie sicher soll es sein? Wie viel Aufwand willst Du den Benutzern zumuten? Da hängt wieder davon ab,um was es denn geht. Also dem „use case“ des QR-Dingens, über den Du nichts schreibst.
    1. Hallo Rakete,

      Darf ich die Frage stellen, ob es in irgendeiner Form notwendig ist, dass der NUR die berechtigte Person NUR den ihr zugeordneten QR-Code sehen kann?

      Dabei geht es mir vor in erster Linie um den Datenschutz. Ich möchte nicht, dass jemand durch Eingabe aller möglichen id.png-Varianten herausfinden kann, welche Nutzer noch alles in der DB gespeichert sind.

      Die Daten, die in dem QR-Code stecken, sind dabei aber nicht besonders sensibel. Im Grunde sind das nur der Name und die ID. Ohne den Namen hätte ich dabei keine besonderen Bedenken. Aber dass man theoretisch die Namen aller registrierten Nutzer herausfinden kann, ist doch irgendwie beunruhigend, oder nicht?

      Gruß Nico

      1. Die persönlichen Daten reichen, um Sorgfalt walten lassen zu müssen.

        Wie wäre es damit:

        • HTML-Formular.
        • Benutzername und Passwort eingeben.
        • Ein PHP-Skript vergleicht das Passwort mit dem in der Datenbank gespeicherten Hash und liefert das PNG oder erzeugt es live aus Daten in Datenbank und sendet es zurück. Wenn das Passwort nicht stimmt sendet das Skript die Webseite mit dem Formular.
        • Anzeige im Browser.

        Man muss sich noch Gedanken machen, wie man brute-force-Attacken unterbindet.

  2. Hallo Nico R.,

    den Ordnerinhalt nur per PHP lesen zu können kannst du mit einer .htaccess Datei erreichen, oder du verlegst den Ordner an eine Stelle außerhalb des Document Root.

    Statt einen Link mit dem Geheimnis in der URL könnte man auch ein kleines form machen, das an ein PHP Script postet und das Geheimnis als hidden input mitgibt. Damit wird es mal zumindest nicht im Zugriffslog des Servers erscheinen. Das Script liefert dann das Bild als Response. Ob diese Idee wirklich taugt sollen andere bewerten.

    Die Steigerung wäre ein echter Login mit Benutzerverwaltung.

    Aber wie schon von Raketenwilli gesagt, es hängt am usecase, was für dich richtig und wichtig ist.

    Rolf

    --
    sumpsi - posui - obstruxi
  3. Lieber Nico,

    ich speichere in einem Ordner QR-Codes von Benutzern.

    welchen Sinn haben diese QR-Codes? Welchem Zweck dienen sie?

    Die Benutzer generieren sich den Code über ein Formular,

    Benötigen sie dafür ein Passwort? Oder kann man sich beliebig viele von diesen Dingern erstellen lassen?

    Ich möchte den Nutzern nun eine bequeme Möglichkeit anbieten, auf ihrem Smartphone vom Startbildschirm aus per App-Symbol den Code anzuzeigen.

    Ah! Es geht um eine Art Bildergalerie für ein einziges Bild. Oder soll das Anzeigen des QR-Codes auf dem Smartphone einem anderen ZWeck dienen, wie z.B. das Smartphone an einen Scanner zu halten?

    Wenn Du eine Verknüpfung (vulgo Link) auf dem Startbildschirm einrichten willst, dann ist das in erster Linie Sache des jeweiligen Smartphone-Benutzers. Und wenn der sich dazu nicht genügend schlau machen will, sondern die Bilddatei mühsam aus seinem Bilderordner herausfummeln will, dann soll der das doch dürfen! Wenn Du aber eine bequeme Möglichkeit suchst, dem Benutzer ein solches Bookmark anzubieten, dann solltest Du die Ergebnisseite nach dem Formular so gestalten, dass sie sich wie eine progressive web app verhält und eine „Installation“ anbietet - was eben das App-Symbol auf den Home-Schirm bringt.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      Wenn Du eine Verknüpfung (vulgo Link) auf dem Startbildschirm einrichten willst... dann solltest Du die Ergebnisseite nach dem Formular so gestalten, dass sie sich wie eine progressive web app verhält und eine „Installation“ anbietet - was eben das App-Symbol auf den Home-Schirm bringt.

      zu Progressive Web Apps hatte ich vor geraumer Zeit auch schon mal was gelesen, das klang zunächst sehr interessant. Bei genauerer Beschäftigung damit, kam mir das Ganze aber ehrlich gesagt wie eine nicht ganz ausgereifte und eher theroretische Technologie aus. Mir wars mit meinen beschränkten Kenntnissen auch ehrlich gesagt zu kompliziert, mit API, Manifest usw.

      Ich habe leider auch nie irgendwo eine funktionierend Anwendung gesehen. Alles, was mir als angebliche Beispiele angezeigt wurde, waren normale Webseiten, da war nix mit Installation. Kennst du, oder irgendjemand sonst hier, ein funktionierendes Beispiel?

      Schöne Grüße

      Nico

  4. Hi,

    Also eine Website… Wenn ich als Link www.example.com/qr_img/13.png anbiete (13 ist die ID des Nutzers), kann der sich natürlich munter alle möglichen anderen Codes anzeigen lassen.

    statt einer einfachen numerischen ID wie 13 könntest Du eine UUID für jeden User generieren und in der User-Tabelle speichern. Und diese UUID hängst Du dann in die URL.

    Es ist dann zwar immer noch möglich, alle möglichen UUID-Werte durchzugehen, aber der Aufwand ist doch etwas höher als wenn Du nur 1, 2, 3, ... durchprobieren müßtest.

    cu,
    Andreas a/k/a MudGuard

    1. Also eine Website… Wenn ich als Link www.example.com/qr_img/13.png anbiete (13 ist die ID des Nutzers), kann der sich natürlich munter alle möglichen anderen Codes anzeigen lassen.

      statt einer einfachen numerischen ID wie 13 könntest Du eine UUID für jeden User generieren und in der User-Tabelle speichern. Und diese UUID hängst Du dann in die URL.

      Es ist dann zwar immer noch möglich, alle möglichen UUID-Werte durchzugehen, aber der Aufwand ist doch etwas höher als wenn Du nur 1, 2, 3, ... durchprobieren müßtest.

      Soweit ich die Nummer verstanden habe: beste Antwort bislang. Speicher die Bilder direkt als UUID.jpg/png, versende/zeige den Link dazu an und fertig.

      Kein PHP, kein Auth, kein weiteres Gedöns nötig. Der Webserver liefert die Teile auf Abruf aus und gut.

      Bei iFrame-Basteleien hätte ich beispielsweise mittelschwere Verständnisprobleme, wie das Teil dann "bequem" auf dem Startschirm des Smartphones landen soll…

      Schneller und sauberer, als der Webserver standalone kannst Du kaum ein Bild ausliefern.

      1. Hello,

        habe schon auf deinen Kommentar gewartet!

        Also eine Website… Wenn ich als Link www.example.com/qr_img/13.png anbiete (13 ist die ID des Nutzers), kann der sich natürlich munter alle möglichen anderen Codes anzeigen lassen.

        statt einer einfachen numerischen ID wie 13 könntest Du eine UUID für jeden User generieren und in der User-Tabelle speichern. Und diese UUID hängst Du dann in die URL.

        Es ist dann zwar immer noch möglich, alle möglichen UUID-Werte durchzugehen, aber der Aufwand ist doch etwas höher als wenn Du nur 1, 2, 3, ... durchprobieren müßtest.

        Soweit ich die Nummer verstanden habe: beste Antwort bislang. Speicher die Bilder direkt als UUID.jpg/png, versende/zeige den Link dazu an und fertig.

        Schlechte Idee!

        Wer generiert die UUID und wie gelangt sie in den Dateinamen und die Response? Wie soll sich der User das merken?

        Kein PHP,

        siehe hierzu UCN zu uniqid()

        kein Auth,

        damit jeder dumme Proxy oder Hop oder Mitleser im offenen WLAN auf dem Weg die URL mitlesen kann. <i>SUPER Idee</i> ;-P

        Glück Auf
        Tom vom Berg

        --
        Es gibt soviel Sonne, nutzen wir sie.
        www.Solar-Harz.de
        S☼nnige Grüße aus dem Oberharz
        1. Hallo Tom,

          Wer generiert die UUID und wie gelangt sie in den Dateinamen und die Response? Wie soll sich der User das merken?

          Die UUID würde ich beim Generieren des QR-Codes mit generieren und per Link an den Benutzer senden, also www.example.com/qr_img/13_1680787822.png

          Diesen Link soll er sich dann auf seinem Startbildschirm speichern. Merken muss er sich gar nichts. Er muss auch seine eigene ID gar nicht kennen. Er muss nur wissen, wie er seinen QR-Code findet.

          damit jeder dumme Proxy oder Hop oder Mitleser im offenen WLAN auf dem Weg die URL mitlesen kann. <i>SUPER Idee</i> ;-P

          Hm. Mal ganz blöd gefragt. Muss ich mich darum kümmern? Gibts in einem offenen WLAN nicht interessantere Daten, die es abzugreifen lohnte? Oder übersehe ich etwas?

          Schöne Grüße Nico

          1. Hello Nico,

            Wer generiert die UUID und wie gelangt sie in den Dateinamen und die Response? Wie soll sich der User das merken?

            Die UUID würde ich beim Generieren des QR-Codes mit generieren und per Link an den Benutzer senden, also www.example.com/qr_img/13_1680787822.png

            Wie denn? DU persönlich kannst keine UUID generieren, sondern Du kannst nur eine Funktion eine UUID generieren lassen. Und das genau war meine Frage: zu welchem Modul oder Programm gehört diese Funktion?

            Machst Du das mittels PHP?

            Diesen Link soll er sich dann auf seinem Startbildschirm speichern. Merken muss er sich gar nichts. Er muss auch seine eigene ID gar nicht kennen. Er muss nur wissen, wie er seinen QR-Code findet.

            Ja, nee. Ist schon klar. Alles ganz easy. Besonders für Mitleser im WLAN und Lauscher auf Proxies und Hops.

            damit jeder dumme Proxy oder Hop oder Mitleser im offenen WLAN auf dem Weg die URL mitlesen kann. <i>SUPER Idee</i> ;-P

            Hm. Mal ganz blöd gefragt. Muss ich mich darum kümmern? Gibts in einem offenen WLAN nicht interessantere Daten, die es abzugreifen lohnte? Oder übersehe ich etwas?

            Das kann ich Dir nicht beantworten.

            Ich bin Mitglied bei Freifunk Harz, Sektion Oberharz und kenne daher etliche Klagen von Leuten, die den WLAN dafür verantwortlich machen, dass ihr Transfer nicht verschlüsselt war. Dabei sind sie selber für die Nutzung von verschlüsselten Verbindungen zuständig!

            Warum Mitleser in größeren offenen WLANS nun lauschen und (unverschlüsselte) Datenpakete abgreifen, kann viele Gründe haben.

            Du selbst bleibst deines Glückes Schmied.

            Und soweit ich das beurteilen kann, bist Du als Anbieter (wenn auch klein) verpflichtet, private Daten nur noch verschlüsselt zu übertragen, und die Übertragung in GET-Parametern entspricht eben nicht dieser Regel. Aber das hat Dir Raketenwilli schon geschrieben.

            Glück Auf
            Tom vom Berg

            --
            Es gibt soviel Sonne, nutzen wir sie.
            www.Solar-Harz.de
            S☼nnige Grüße aus dem Oberharz
            1. Hallo Tom,

              Machst Du das mittels PHP?

              Ja, mittels PHP.

              Und soweit ich das beurteilen kann, bist Du als Anbieter (wenn auch klein) verpflichtet, private Daten nur noch verschlüsselt zu übertragen.

              Das ist natürlich ein interessanter Hinweis. Könnte das wirklich problematisch sein? Bin ich dieser Pflicht nicht dadurch nachgekommen, dass meine Seite per https:// ausgeliefert wird?

              Schöne Grüße

              Nico

              1. Hello,

                Und soweit ich das beurteilen kann, bist Du als Anbieter (wenn auch klein) verpflichtet, private Daten nur noch verschlüsselt zu übertragen.

                Das ist natürlich ein interessanter Hinweis. Könnte das wirklich problematisch sein? Bin ich dieser Pflicht nicht dadurch nachgekommen, dass meine Seite per https:// ausgeliefert wird?

                Bitte nochmal lesen. Ich war noch nicht fertig mit dem Posting und habe noch etwas nachgetragen. Bitte entschuldige meine Bummelei ;-P

                Glück Auf
                Tom vom Berg

                --
                Es gibt soviel Sonne, nutzen wir sie.
                www.Solar-Harz.de
                S☼nnige Grüße aus dem Oberharz
            2. Machst Du das mittels PHP?

              Soweit man "php" als Schlagwert des OP für relevant betrachtet: vermutlich ja!

              1. Hallo,

                Machst Du das mittels PHP?

                Soweit man "php" als Schlagwert des OP für relevant betrachtet: vermutlich ja!

                Ick bewundre dir, dass du noch niemals nicht auch nur ein kleinstes Informationshäppchen übersehen hast! Restepk!

                Gruß
                Kalk

                1. Hi,

                  Soweit man "php" als Schlagwert des OP für relevant betrachtet: vermutlich ja!

                  Ick bewundre dir, dass du noch niemals nicht auch nur ein kleinstes Informationshäppchen übersehen hast! Restepk!

                  naja, so klar war das auch wieder nicht, denn zwischendurch war ja auch die Rede von Java und einer Handy-App.

                  Einen schönen Tag noch
                   Martin

                  --
                  Im Englischen hat eine Katze neun Leben. Im Deutschen vielleicht auch, aber nach Abzug der Steuern bleiben nur noch sieben übrig.
      2. Hello,

        Soweit ich die Nummer verstanden habe: beste Antwort bislang. Speicher die Bilder direkt als UUID.jpg/png, versende/zeige den Link dazu an und fertig.

        Ich habe selbstverstäbdlich nochmal darüber nachgedacht.
        Bis zu dem Punkt, an dem eine UUID oder sonst ein Token per Link im Response-Body per HTTPS-Response gesendet wird, mag ich Dir zustimmen. Solange sollte das sicher sein.

        Aber schon der Versand per eMail ist fragwürdig. da hier schon wieder zuviele "kostenlose" eMail-Anbieter im Spiel sein können, die in ihren Geschäftsbedingungen ausdrücklich darauf hinweisen, dass sie mitlesen dürfen.

        Und beim per HTTPS-Response verschickten Link (im verschlüsselten Body) wird es in dem Moment interessant, wenn er benutzt wird, man darauf klickt, also der Link inklusive Token wieder im GET-Request auftaucht. Dann ist er i.d.R. wieder lesbar für Mitleser, Sniffer, usw.

        Glück Auf
        Tom vom Berg

        --
        Es gibt soviel Sonne, nutzen wir sie.
        www.Solar-Harz.de
        S☼nnige Grüße aus dem Oberharz
    2. Guten Morgen an euch alle,

      statt einer einfachen numerischen ID wie 13 könntest Du eine UUID für jeden User generieren und in der User-Tabelle speichern. Und diese UUID hängst Du dann in die URL.

      vielen Dank für eure Antworten. Ich finds wirklich toll, wie kompetent und schnell hier geholfen wird und wie viel Aufwand teilweise darin steckt. Wollte ich einfach mal los werden.

      Ich antworte jetzt mal hier, weil mir das den entscheidenen Anstoß gegeben hat, wie ichs machen würde. Statt einen Ordner mit 13_1680787822 zu erstellen, könnte ich das Bild ja einfach 13_1680787822.png nennen. Meine Suche nach UUID hat ergeben, dass selbige natürlich viel komplexer aufgebaut ist. Aber es dürfte doch eher unwahrscheinlich sein, dass jemand die Kobination aus einer ID und einem UNIX-Timestamp errät. Alternativ könnte ich ja zusätzlich noch einen random-Wert mit anhängen.

      Gegen einen professionellen bösartigen Angriff mag das nicht helfen, aber an dieser Stelle würden die Angreifer wirklich bloß IDs und Namen erhalten. Wirklich interessant sind diese Sachen nicht. Und so interssant ist dann ehrlich gesagt auch das ganze Projekt nicht. Es geht mir dabei eher um einen "einfachen" Datenschutz. Nutzer sollen nicht durch Austausch der ID die Namen anderer Nutzer herausfinden können. Das zu verhindern, sollte man von einem Anbieter erwarten. Für wirkliche Angriffe ist das Projekt kein lohnendes Ziel und der Schaden wäre überschaubar bis null.

      Schöne Grüße Nico

      1. Hallo Nico,

        Für wirkliche Angriffe ist das Projekt kein lohnendes Ziel und der Schaden wäre überschaubar bis null.

        Das ist eine Bewertung, die nur Du allein treffen kannst, da Du uns den fachlichen Inhalt deines Projekts nicht mitteilst (keine Kritik, nur Feststellung).

        dass jemand die Kombination aus einer ID und einem UNIX-Timestamp errät

        Das sehe ich anders. Gerade weil es ein Timestamp ist, kann man relativ gut abschätzen, in welchem Intervall sich der Timestamp aufhalten muss. Wenn ein Haufen Dateien schnell hintereinander generiert werden, haben sie ähnliche Timestamps und das Rate-Intervall ist noch kleiner.

        Alternativ könnte ich ja zusätzlich noch einen random-Wert mit anhängen.

        Das solltest Du definitiv tun. Und zwar an Stelle des Timestamps. Meine Empfehlung wäre, mit bin2hex(random_bytes(16)) einen 32-stelligen Hexwert zu erzeugen, den Du als Anti-Rate-Salz an den Dateinamen anfügst.

        Das schützt Dich nicht gegen das Abgreifen der URL durch Log-Schnüffler oder so - aber dafür hatte ich ja schon den Vorschlag mit dem Form gemacht.

        Rolf

        --
        sumpsi - posui - obstruxi
  5. Hello,

    ich speichere in einem Ordner QR-Codes von Benutzern. Die Benutzer generieren sich den Code über ein Formular, ein Script speichert den Code im Ordner qr_img auf dem Server und verschickt ihn dann per E-Mail-Anhang an den Benutzer.

    Die erste Idee wäre, in einer .htaccess

    options -indexes
    

    zu setzen und die Nutzer in Unterverzeichnissen mit Usernamen unterzubringen. Die Bilder dann nicht grabbable numerieren, sondern mit einem mindestens 4stelligen Zufalls-HEX-Code oder sogar mit 64 Zeichen pro Digit (a-z, A-Z, 0-9, _, -) o. ä.

    (Und fail2ban für HTML-Zugriffe Satus 404 auf vielleicht 10 Fehlzugriffe einzustellen.)

    Oder hat jemand eine bessere Idee? Bis jetzt war das immer der Fall :-)

    Weiß ich nicht, aber ich würde es so machen:

    • QR-Code generieren und Bild außerhalb der DocRoot ablegen
    • Als Response eine Seite senden, die einen Cookie setzt und ein iFrame enthält, das das Bild referenziert.
    • der iFrame-Request kommt dann mit dem Cookie auf dem Server an
    • die Auslieferung des Bildes erfolgt dann nur mit dem gültigen Cookie (oder alternativ mit Credntials User:Passwort).

    Dafür benötigst Du ein Script, das die Auslieferung vornimmt.
    Ein Beispiel dafür findest Du im Wiki unter Fileupload.

    Ich hoffe, dass Du da noch heran kommst, da der Artikel in meinen privaten Bereich zurückgeschoben wurde.

    Wenn man für jeden User ein eigenes Verzeichnis außerhalb der DocRoot anlegt, kann darin alle seine QR-Bilder und (in einem Unterverzeichnis davon) auch das Passwort-Hash und die Cookie-Hashes ablegen.

    Man benötigt dann keine Datenbank.

    Wenn es total viele User werden könnten, müsste man vielleicht noch eine Router-Ebene (mit dem Anfangsbuchstaben des Usernamen) vorschalten.

    
    --+--a--+--Albert--+--qr--
      |     |          |    
      |     |          +--pass--
      |     |          |
      |     |          +--cookies--
      |     |
      |     +--andrea--+--qr--
      |     |          | 
      |     |          +--pass--
      |     |          |
      |     |          +--cookies--
      |     |
      |     +--    
      |
      +--b--+--balu----+--qr---
      |     |          |
      |     |          +--pass--
      |     |          |
      |     |          +--cookies-- 
      |     |
    
    usw.
    

    Glück Auf
    Tom vom Berg

    --
    Es gibt soviel Sonne, nutzen wir sie.
    www.Solar-Harz.de
    S☼nnige Grüße aus dem Oberharz