Images und URL-Auflösung= *.php Datei
Mark
- php
0 Thomas Luethi0 Tom
Hallo,
war heute in einem Forum, der seinen Usern u.a. eine eigene Fotogalerie anbietet.
Habe mir natürlich auch einige Bilder angesehen, und nach Auflösung der URL zu den Bildern steht da nun z.B. folgendes:
album_pic.php?pic_id=1000000
Wieso ein Image als PHP-Datei, dachte immer, dass es nur dann möglich wäre, wenn die Dateien in den DatenBanken selbst abgelegt wären?
Habe als Antwort vom ForumBetreiber folgendes erhalten:
In der Datenbank sind nur die Verweise zu den Images hinterlegt die in einem Ordner Hot-Link geschützt und mit codierten Dateinamen gespeichert werden...
Gibt es da irgendwo Anwendungsbeispiele? Würde mich interessieren, wie das umgesetzt wurde.
Danke
Hallo,
album_pic.php?pic_id=1000000
Wieso ein Image als PHP-Datei, dachte immer, dass es nur dann möglich wäre, wenn die Dateien in den DatenBanken selbst abgelegt wären?
Nein, man kann PHP auch einfach brauchen, um Bilder "durchzuschleusen".
Bilder in der DB zu speichern, ist im allgemeinen nicht sinnvoll.
http://www.dclp-faq.de/q/q-db-blob.html
In der Datenbank sind nur die Verweise zu den Images hinterlegt die in einem Ordner Hot-Link geschützt und mit codierten Dateinamen gespeichert werden...
Das ist ein brauchbarer Ansatz.
Der Ordner mit den Bildern sollte via Web (HTTP) gar nicht zugaenglich sein,
sondern nur via Filesystem.
Dann braucht man auch keine "codierten" Dateinamen.
Gibt es da irgendwo Anwendungsbeispiele? Würde mich interessieren, wie das umgesetzt wurde.
Etwas sehr aehnliches habe ich Fabienne vor zwei Wochen im Posting
http://forum.de.selfhtml.org/archiv/2003/11/62399/#m353128
vorgeschlagen. Lies den Thread mal durch, vielleicht hilft er Dir weiter.
Sonst melde Dich wieder.
Gruesse,
Thomas
Hello,
Der Ordner mit den Bildern sollte via Web (HTTP) gar nicht zugaenglich sein,
sondern nur via Filesystem.
Dann braucht man auch keine "codierten" Dateinamen.
Wie bildest Du das ab, wenn keine Session und kein Login besteht? Mach mal bitte vor.
Grüße
Tom
Hallo,
Wie bildest Du das ab, wenn keine Session und kein Login besteht? Mach mal bitte vor.
Hae?
Man kann ein PHP-Skript zum "Durchschleusen" von Dateien brauchen,
die irgendwo im Filesystem liegen.
Ob man das ganze noch mit Passwortschutz/Login und Sessions kombinieren
will oder nicht, ist eine ganz andere Geschichte.
Und _die_ ist _mir_ momentan ziemlich egal.
Was soll ich "vormachen"?
Wie man ein Verzeichnis mit .htaccess vor jeglichem Abruf via Web sperrt?
Oder was?
Mark hat ueberhaupt nicht gesagt, wozu er das ganze - wenn ueberhaupt - anwenden will.
Er hat nur gefragt, wie man mit PHP aufgrund einer Zahl/ID oder so
ein Bild ausgeben kann, das nicht in einer Datenbank steht.
Das ist alles.
_Du_ kommst jetzt mit Login und Sessions daher.
Ich denke, es ist muessig, sich darueber den Kopf zu zerbrechen,
solange Mark nicht eine Frage in der Richtung stellt.
;-)
Freundliche Gruesse,
Thomas
Hello Thomas,
warum wirst Du denn so pampig?
Wie bildest Du das ab, wenn keine Session und kein Login besteht? Mach mal bitte vor.
Was soll ich "vormachen"?
Wie man ein Verzeichnis mit .htaccess vor jeglichem Abruf via Web sperrt?
Oder was?
psssst, kühl Dich ab...
<cite>
Der Ordner mit den Bildern sollte via Web (HTTP) gar nicht zugaenglich sein,
sondern nur via Filesystem.
Dann braucht man auch keine "codierten" Dateinamen.
</cite>
Und ich möchte jetzt wissen, was das bringen soll, die Bilder woanders abzulegen, wenn man keine codierten "Dateinamen" benutzt. Sind natürlich zwei Denkschritte. Hoffe, Du kannst mir so schnell folgen ;-)
Der Aufruf erfolgt ja nach wie vor durch <img src="xyz" ..>
Nur dass jetzt xyz nicht mehr das Bild selbst ist, sondern das Script mit Parameter. Das ergibt nun den "Dateinamen". Ich kann also nun an dieser Stelle durch Eingabe von beliebigen Parametern beliebige Bilder anfordern. Dadurch, dass die Parameter meistens sogar einfach nur durchgezählt werden, ist es sogar NOCH einfacher, das gesamte Bildverzeichnis auszulesen, als es wäre, wenn man DIREKT auf das Bildverzeichnis mit seinen natürlichen Bildnamen verlinkt (mit src=).
Hast Du meine Frage nun verstanden?
Dann wäre es nett, wenn Du mir Deine Gedanken erläutern könntest.
Grüße
Tom
Hallo,
psssst, kühl Dich ab...
OK, OK. Sorry fuer's erhitzen;-)
Der Ordner mit den Bildern sollte via Web (HTTP) gar nicht zugaenglich sein,
sondern nur via Filesystem.
Dann braucht man auch keine "codierten" Dateinamen.
Zugegeben, bei diesem Absatz bin auch ich davon ausgegangen,
dass es um einen "Schutz" geht.
Und ich möchte jetzt wissen, was das bringen soll, die Bilder woanders abzulegen, wenn man keine codierten "Dateinamen" benutzt.
Es kann bringen, dass man z.B. in einem CMS nur die Bild-ID(s)
mit einem Artikel verknuepfen muss, und nicht die physischen
Dateinamen.
Zudem kann man verschiedene Varianten (gross/klein, gute/schlechte Qualitaet)
desselben Bildes mit einer ID und zusaetzlichen Parametern codieren.
Das Skript, das den Artikel anzeigt, muss also nur die Bild-ID wissen
und erzeugt daraus folgende Links:
bild.php?bildid=15 => es wird eine vorher definierte "Standard-Version" ausgeliefert
bild.php?bildid=15&version=thumb => Thumbnail
bild.php?bildid=15&version=hoch => Hochaufloesende Version u.s.w.
_Das_ waere ein Einsatzszenario, das nicht dem "Schutz" dient, sondern anderen Zielen.
Ein anderer Grund koennte z.B. sein, dass man den Traffic limitieren will/muss,
und dass man gegen Monatsende, wenn die Quota ueberschritten ist, nur noch
kleine Dateien ausliefern will.
u.s.w.
Dadurch, dass die Parameter meistens sogar einfach nur durchgezählt werden, ist es sogar NOCH einfacher, das gesamte Bildverzeichnis auszulesen, als es wäre, wenn man DIREKT auf das Bildverzeichnis mit seinen natürlichen Bildnamen verlinkt (mit src=).
Voellig einverstanden.
Man koennte das natuerlich auch wieder zum Selbstschutz verwenden:
Gewisse IDs als "Falle" ohne zugehoeriges Bild, und wer diese ID
verlangt, wird fuer 30 Minuten gesperrt, kriegt also gar kein Bild
mehr zu sehen.
(Und ja, ich kenne http://www.dclp-faq.de/q/q-scripte-abstimmung.html
und weiss, dass das nicht richtig moeglich ist. War ja auch nur so eine Idee.)
Oder man koennte fuer jede ID noch gleich einen kurzen String
definieren, den nur der Server kennt.
Bei allen server-generierten Links laesst man den Code automatisch
ausgeben, aber das automatische Durchzaehlen fuer "Bildersammler"
wird so unmoeglich gemacht.
Bildersammler sieht
bild.php?bildid=15&code=abc
und versucht es mit
bild.php?bildid=16&code=abc
bild.php?bildid=17&code=abc
Die Bilder werden aber nur ausgeliefert, wenn auch der code stimmt:
bild.php?bildid=16&code=mno
bild.php?bildid=17&code=xyz
u.s.w.
Ach, ich zerbreche mir schon wieder den Kopf ueber Probleme,
die gar niemand geloest haben will!
Freundliche Gruesse + Gute Nacht,
Thomas
Hello,
Ach, ich zerbreche mir schon wieder den Kopf ueber Probleme,
die gar niemand geloest haben will!
Nee, nee...
Das steht noch auf meinem Plan der Sicherheitslücken.
Ich habe da immer noch ein CMS am Wickel, das auch mal solche Aufgaben lösen soll. Die Funktionen sollen z.B. mal für ein medizinisches Institut eingesetzt werden, dass an Allergien arbeitet. Die hätten nicht so gerne, wenn die Patientenaufnahmen allzuleicht für Jedermann lesbar würden (obwohl sie da meistens schwarze Balken und sowas eingeblendet haben, aber immer geht es eben nicht).
So ähnlich, wie Du vorschlägst, habe ich das bisher auch gelöst. Wenn einer daneben tippt, dann schläft das Script 3 Sekunden und liefert dann ein DuDu-Bild aus. Aber das schadet nur der eigenen Server-Performance, da schlaue Grabber mit fork arbeiten und einfach parallele Requests senden.
Grüße
Tom
Moin!
Das steht noch auf meinem Plan der Sicherheitslücken.
Wieso "Sicherheitslücken"? Wenn, dann wäre das eher eine Konzeptlücke.
So ähnlich, wie Du vorschlägst, habe ich das bisher auch gelöst. Wenn einer daneben tippt, dann schläft das Script 3 Sekunden und liefert dann ein DuDu-Bild aus. Aber das schadet nur der eigenen Server-Performance, da schlaue Grabber mit fork arbeiten und einfach parallele Requests senden.
Punkt 1: sleep() ist recht performanceneutral, da wird der Prozess einfach schlafengelegt. Natürlich zählt er weiterhin zu den existierenden Prozessen und belegt auch Speicher, aber die CPU werkelt nicht an ihm.
Punkt 2: Wenn, unter welchen Bedingungen auch immer, vom Projekt definiert ist, dass irgendein beliebiger Client per HTTP eine definierte URL vom Server anfragen darf, ohne sich authentifizieren zu müssen, dann kann man das nicht verhindern.
Webgrabber werden effektiv vom Grabben von Bildern abgehalten, indem die URLs sich nicht simpel durch hochzählen bilden lassen.
/pfad/bild001.gif
/pfad/bild002.gif ... ist schlecht.
/pfad/skript.php?id=1
/pfad/skript.php?id=2 ... ist ebenso schlecht.
/pfad/17687689.gif
/pfad/10908769.gif ... ist besser
/pfad/skript.php?id=19087987
/pfad/skript.php?id=87568761 ... ist ebenso gut.
Und jetzt kommen wir wieder zum Raten und den Wahrscheinlichkeiten. Wenn man allein durch die Auswahl einer passend großen Wertemenge entweder des Dateinamens oder der ID die Ratemöglichkeiten so groß macht und gleichzeitig durch im Vergleich zur tatsächlichen Ratemenge geringen Anzahl von vorhandenen Bildern die Erfolgsmenge, die beim Abgrasen einer gewissen Anzahl von Werten entsteht, dann ist Grabbing effektiv verhindert.
Die direkte Grafikausgabe hat den Vorteil, dass sie performanceschonend einen 404 produziert, die Skriptvariante hat den Vorteil, dass man die Bildauslieferung mit serverseitiger Dynamik gestalten kann (wobei sich die Dynamik keinesfalls auf den auszugebenden Inhalt beziehen muß).
Aber beide Mechanismen versagen, wenn die auf die eine oder andere Weise verfügbaren Bilder in einer frei zugänglichen HTML-Seite verlinkt sind.
Einmal wget über die ganze Site drüberlaufen lassen, und gut ist. Dagegen _kann_ es kein Mittel geben, der nicht in irgendeiner Art und Weise berechtigte Besucher ausschließt. Denn woran will man den unberechtigten Grabber erkennen?
- Sven Rautenberg
Hello,
Wieso "Sicherheitslücken"? Wenn, dann wäre das eher eine Konzeptlücke.
Na, gut, einverstanden.
Punkt 1: sleep() ist recht performanceneutral, da wird der Prozess einfach schlafengelegt. Natürlich zählt er weiterhin zu den existierenden Prozessen und belegt auch Speicher, aber die CPU werkelt nicht an ihm.
Es sperrt aber leider einen Prozess. Der Apache bedient nur eine gewisse Anzahl Requests "gleichzeitig". Standard sind wohl 150.
Punkt 2: Wenn, unter welchen Bedingungen auch immer, vom Projekt definiert ist, dass irgendein beliebiger Client per HTTP eine definierte URL vom Server anfragen darf, ohne sich authentifizieren zu müssen, dann kann man das nicht verhindern.
Nun mal dumm gefragt. Wenn ich eine src anfordere, werden da die Cookies auch mitgesendet? Ist Request = Request oder machen die Browser da irgendwo Unterschiede?
Du bringst mich immer auf gute Ideen.
Man gebe JEDEM eine Session. Jede Seite bekommt zur Not eine neue. In die Session werden dann die Bilder-Pfade eingestellt und mit einem Trivialnamen verknüpft (oder ID-Parameter). Solange die Images für die passende Seite requestet werden, wird dann ja immer der passende Cookie mitgesendet. Wenn nun jemand versucht, Bilder ohne Cookie oder mit dem aus einer anderen Seite zu holen, blitzt er ab.
Ist noch recht unausgegoren. Muss ich noch mehr drüber nachdenken.
Wahrscheinlich schläft das Dateisystem dann irgendwann ein.
Ich habe ja auch schon mal die selbstlöschende Datei "erfunden". Wenn eine Seite mit Bildern angefordert weird, werden diese im Dateisystem physisch kopiert unter einem pseudonym. Wenn der Browser dann den Bildrequest ausführt (Script), dann löscht sich dieses Script nach Auslieferung seiner Daten selbst. Funktioniert.
Ich habe noch mehr dämliche Ideen in der Schublade...
Grüße
Tom
Moin!
Nun mal dumm gefragt. Wenn ich eine src anfordere, werden da die Cookies auch mitgesendet? Ist Request = Request oder machen die Browser da irgendwo Unterschiede?
Ja, Request ist Request. Immer gleich.
Du bringst mich immer auf gute Ideen.
Das glaube ich nicht.
Man gebe JEDEM eine Session. Jede Seite bekommt zur Not eine neue. In die Session werden dann die Bilder-Pfade eingestellt und mit einem Trivialnamen verknüpft (oder ID-Parameter). Solange die Images für die passende Seite requestet werden, wird dann ja immer der passende Cookie mitgesendet. Wenn nun jemand versucht, Bilder ohne Cookie oder mit dem aus einer anderen Seite zu holen, blitzt er ab.
Ja, und? Der Grabber braucht also nur die Seite zu laden, wird mit einem Cookie beworfen, was er recht freundlich bei jedem nachfolgenden Request wieder an dich zurückschickt, und kriegt dennoch alle Bilder, wenn er sich als Spider von Seite zu Seite hangelt und enthaltene Ressourcen abgreift.
Ein Browser eines Besuchers macht übrigens nichts anderes. Und weil das so ist, kannst du die beiden niemals unterscheiden.
Ist noch recht unausgegoren. Muss ich noch mehr drüber nachdenken.
Ja, weil es viel Aufwand für keinen Effekt hat.
Wahrscheinlich schläft das Dateisystem dann irgendwann ein.
Um Gottes Willen. Sowas macht man doch nicht per realer Dateikopie!
Ich habe ja auch schon mal die selbstlöschende Datei "erfunden". Wenn eine Seite mit Bildern angefordert weird, werden diese im Dateisystem physisch kopiert unter einem pseudonym. Wenn der Browser dann den Bildrequest ausführt (Script), dann löscht sich dieses Script nach Auslieferung seiner Daten selbst. Funktioniert.
Ja. Man kann sich auch einen Stacheldraht durch den Bauchnabel ziehen und "Hallelujah" singen, funktioniert auch.
:)
- Sven Rautenberg
Hello,
Ja, und? Der Grabber braucht also nur die Seite zu laden, wird mit einem Cookie beworfen, was er recht freundlich bei jedem nachfolgenden Request wieder an dich zurückschickt, und kriegt dennoch alle Bilder, wenn er sich als Spider von Seite zu Seite hangelt und enthaltene Ressourcen abgreift.
Ein Browser eines Besuchers macht übrigens nichts anderes. Und weil das so ist, kannst du die beiden niemals unterscheiden.
Er bekommt aber nur die Bilder der freigegebene Seiten. Und die bekommt er ja sowieso. Er kann nicht einfach das gesamte Bildverzeichnis lesen.
Gute Nacht
Tom
Moin!
Er bekommt aber nur die Bilder der freigegebene Seiten. Und die bekommt er ja sowieso. Er kann nicht einfach das gesamte Bildverzeichnis lesen.
Das kann er ja sowieso nicht - das Bildverzeichnis lesen, meine ich.
Aber er kann eine neue Seite anfordern. Und kriegt dann wieder freigeschaltete Bilder.
Mal ernsthaft: Kein intelligenter Bildergrabber wird so blöde sein und nur aufgrund einer Datei, die _scheinbar_ durchnumeriert ist, diese Nummern durchprobieren. Er kann sich mit einiger Sicherheit drauf verlassen, dass die Bilder existieren und zugriffsfähig sind, welche auf den zugehörigen Webseiten verlinkt sind. Bilder, die nicht verlinkt sind, sieht man ja nicht. Also können die existieren (ob nun als simpler oder komplizierter Dateiname - egal), oder auch nicht.
Die Suche danach bedeutet jedenfalls viele 404 und wenig Erfolg - was beim Spidern und Grabben der HTML-Site genau umgekehrt ist.
Und wenn du einen derartig komplexen Mechanismus einbaust, dass man mit einer Automatik nicht mehr rankommt - dann bastelt sich der Grabber einen Cache-Explorer und holt die Bilder alle aus dem Browsercache. Ganz einfach. Mit dem Proxy WWWOFFLE sogar ganz einfach machbar, der kümmert sich nämlich nicht um Proxy-orientierte HTTP-Header - und im Zweifel fischt man die vorher raus.
- Sven Rautenberg
Uiui..., was hab ich angerichtet?
Nee, im ernst: Meine Frage wurde doch bereits beantwortet. Spart euch doch die Energie für Nachfolgende ;)
Gruss, Mark
P.S. Besser als jedes Buch, hehe...
Hallo Thomas,
Bilder in der DB zu speichern, ist im allgemeinen nicht sinnvoll.
Das wusste ich schon, deshalb war ich dort auch ein wenig vorlaut, da ich dachte sein Forum würde es machen.
Etwas sehr aehnliches habe ich Fabienne vor zwei Wochen im Posting
http://forum.de.selfhtml.org/archiv/2003/11/62399/#m353128
vorgeschlagen. Lies den Thread mal durch, vielleicht hilft er Dir weiter.
Jup, hilft Danke
Hello,
das Spannende dabei sind zwei Dinge:
1. Wie sorgt man dafür, dass nur berechtigte User ein Bild bekommen?
Das geht mit Sessions ganz toll, was aber, wenn auch User
ohne Sessions Bilder ausgeliefert bekommen sollen?
2. Wie sorgt man dafür, dass das Bild nicht bei jedem Request
über die Leitung saust, auch wenn es sich nicht geändert hat?
// prüfen, ob das Bild im Server neuer ist als im Cache des Browsers
$last_modified = gmdate('D, d M Y H:i:s',filemtime(PICPATH.$filename)).' GMT';
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
// parse header
$if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($if_modified_since == $last_modified)
{
// the browser's cache is still up to date
header("HTTP/1.0 304 Not Modified");
header("Cache-Control: max-age=86400, must-revalidate");
return true;
}
}
Ist ein Ausschnitt aus meiner Funktion.
Wüsste gerne, ob max-age=86400 nicht zu wenig ist. Sind wohl Sekunden und dann wäre das ein Tag...
Was muss man schreiben, wenn man nur bei einem neueren Bilddatum ein Revalidate will?
Grüße
Tom