.htaccess Sicherung - User: No Access, Server: Access
lima-city → Forum → Die eigene Homepage → Sicherheit im Internet
ausgeben
bild
bildformat
code
datei
ende
erstellen
fehlermeldung
foto
gefunden bild
header
http
index
mime
ordner
show
type
url
verzeichnis
zugriff
-
ho ;)
Ich habe eine Frage an die Webspace-Server und .htaccess Spezialisten :D
Ich habe eine Seite, auf der ein paar Fotos gespeichert sind. Die Seite ist via PHP Passwortgeschützt, und alles funktioniert soweit ganz gut. Das einzige, was ich nicht direkt schützen kann (oder nicht weiß, wie es geht...) sind die Fotos selbst.
Sprich:
1. Die Seite anzeigen lassen, auf der die Fotogalerie ist - Ohne PW nicht möglich.
2. Das Foto direkt ansehen (vorausgesetzt, man hat den direkten Link dazu... "meineseite.at/pics/foto1.jpg") geht natürlich schon.
2tes will ich nun auch verhindern. Ich habe mir gedacht, dass ich einfach eine .htaccess Datei in den Pics Ordner gebe, und damit keiner mehr direkten Zugriff auf die Fotos hat.
Das Ergebnis war, dass zwar kein User mehr einen Zugriff auf die Fotos hat, allerdings der Server selbst auch nicht. Sprich statt einer Fotogalerie hatte ich eine leere Seite...
Nun meine Frage: Wie kann ich das machen? User:Nein (nur über Fotogalerie!) Server:Ja (Um die Fotos auf der Fotogalerie anzuzeigen.)
Irgend eine Idee? Oder geht es gar nicht? Oder geht es nicht via .htaccess?
lg
Sincer -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Meine Kenntnisse bezüglich .htaccess sind nicht so groß, aber soweit ich es überblicke: Eine Mischung aus PHP und .htaccess ist nicht möglich. Allerdings wäre .htaccess die einzige sicher Möglichkeit die Bilder zu schützen. Das heißt letztlich, dass es nicht möglich ist.
Idee1: Bilder bekommen einen kryptischen Dateinamen, damit sie nicht ohne weiteres erratbar sind. Allerdings ist das nicht die effektivste Lösung, wenn jemand den Link zum Bild weiterschickt, kann die andere Person das Bild ja trotzdem öffnen.
Idee2: Soweit ich weiß kann man mit .htacces den MIME-Typ abändern. Falls es nun möglich wäre, einem Bild den Typ .php zu geben. Könnte man ja überprüfen, ob der User eingeloggt ist. Wobei ich da gerade etwas überfragt bin, ob diese auch wirklich geht. -
Also eigentlich sollte es genügen eine .htaccess Datei mit folgendem Inhalt in das Verzeichnis zu kopieren:
Deny from all
Achte darauf, dass sich kein Zeichen mehr nach dem letzten Zeichen in dieser Datei befindet und auch keine Leerzeile danach. Das Skript sollte dennoch auf die Bilder zugreifen können. Allerdings hast du nur eine einzige Chance Bilder im Internet vor Zugriffen zu schützen und das ist sie nicht hochzuladen. Alles andere ist sinnlos, denn der Browser lädt die Bilder auf alle Fälle mal in den Cache bzw. den Temp Ordner. Das muss er sonst kann man die Bilder nicht anzeigen und ein Screenshot ist auch schnell gemacht.
Grüße Christian -
ho ;)
Danke für die schnelle Antwort :D
Das habe ich schon fast befürchtet, dass es nur mit einer .htaccess Datei nicht möglich ist :/
Zur Idee1:
Man kann den Link zum Bild nicht wirklich erraten. Es geht wie du vermutet hast nur darum, dass ein User den Link nach außen Transportieren könnte. Und das will ich verhindern.
Zur Idee2:
Uff... von so etwas habe ich noch nie gehört, aber wenn es funktioniert... Das Problem wäre dann wohl eher, dass mein Foto-Album Script vil. Probleme hätte, oder?
Dazu bräuchte ich auf jeden Fall ein gutes Tutorial... Hab damit noch überhaupt keine Erfahrung.
Für weitere Ideen und Vorschläge bin ich noch immer offen :D
@kompettweb:
Das Probiere ich gleich mal aus...
//EDIT:
Nein, wenn ich die .htaccess Datei einfüge, dann kann mein Script auch nicht mehr auf die Fotos zugreifen.
---
Also in den Ordner, wo die ganzen Unterordner (in denen die Fotos sind) einfach eine .htaccess Datei rein stellen, in der eine Zeile steht:
Deny from all
Stimmt das so?
thx
Sincer
Beitrag zuletzt geändert: 27.9.2009 23:21:18 von sincer -
Ich hab grade mal Google bemüht:
http://www.guweb.com/postcards/help/antileech.shtml
Vielleicht hilft dir das ja.
MfG
karlsve
Edit: lass aber den guweb teil weg.
Beitrag zuletzt geändert: 27.9.2009 23:37:38 von karlsve -
Auch ein thx an dich karlsve, aber das ist nicht ganz das, wonach ich gesucht habe...
Es geht eher darum:
MSN User A: hey, schau dir das bild an - link ...
MSN User B: *klick* Hm... Ich seh kein Bild.
Also es muss kein Link sein, der auf einer anderen Seite gepostet wurde, sondern einfach nur ein direkter Link.
Allerdings stand in dem Forum (Google Link) noch etwas anderes, dass recht interessant klang:
Wenn man das Foto direkt aufrufen will, wird man zur Startseite weitergeleitet.
Das müsste doch beuten, dass ich mit dem PHP Script die Fotos aufrufen kann, aber man die Fotos nicht sehen kann, wenn man den Link direkt anvisiert.
Ist das so möglich? (Und wie geht das? XD )
lg
Sincer -
Ich hatte bei der angabe des links zwar eher an die Möglichkeit A mit htaccess gedacht aber das habe ich nicht geschreiben und du ja vllt auf der verlinkten seite übersehen.
RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://your.domain.com/ <-- Deine domain natürlich RewriteRule .*\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG)$ http://another.domain.com/for/picture/forbidden.png <--startseite deiner domain eingeben
MfG
karlsve -
Wie wärs wenn du gar nicht direkt auf die Bilder verlinkst, sondern auf eine PHP-Datei, welche dann Prüft ob der Benutzer die entsprechenden Rechte hat und dann das Bild ausgibt.
Du verlinkst also anstatt auf http://example.com/pics/bild1.png auf http://example.com/show.php?bild=bild1
=> Niemand weiß wo das Bild wirklich liegt, und wenn der Link weiter geschickt wird und Benutzer2 auf den Link klickt, wird die PHP-Datei nochmal ausgefürt, und du kannst erneut überprüfen ob der Nutzer die benötigten Rechte hat.
Für das Ausgeben des Bildes mittels PHP sind folgende Funktionen wahrscheinlich ganz nützlich:
imagecreatefromjpeg()
imagejpg()
Wenn es keine JPEG-Bilder sind, musst du natürlich die entsprechenden Funktionen nehmen.
€dit:
Du brauchst auch noch die Funktion header() um den Content-Type mitzuschicken. Das sähe dann z.B. so aus:
header('Content-Type: image/jpeg');
Beitrag zuletzt geändert: 28.9.2009 0:26:25 von ketchupfleck -
Ich würde eine Mischung aus PHP und .htaccess verwenden ^^
Du kannst mittels mime_content_type den Dateityp bestimmen, diesen über header an den Browser senden und dann mit readfile das Bild ausgeben, davor können dann noch die Sicherheitsabfragen kommen.
Mit .htaccess kannst du dann den Ornder schützen, in welchem die Bilder liegen, denn darauf muss keiner direkt zugreifen, denn der zugriff erfolgt über die PHP-Datei.
[edit]
@ketchupfleck:
warum denn imagecreatefromjpeg() usw. verwenden, wenn man das Bild nicht bearbeiten will, sondern nur auslesen und an den Browser senden?
Beitrag zuletzt geändert: 28.9.2009 0:33:23 von thomasba -
ho ;)
karlsve schrieb:
Ich hatte bei der angabe des links zwar eher an die Möglichkeit A mit htaccess gedacht aber das habe ich nicht geschreiben und du ja vllt auf der verlinkten seite übersehen.
Nein, das habe ich nicht übersehen. Allerdings schützt dieser Code nur vor verlinkten Bildern.
Sprich:
Link liegt auf Server A
Bild liegt auf Server B
-> Kein Zugriff möglich.
Soweit so gut, aber Link wird per Mail an anderen User gesendet.
Zugang müsste meinem Verständnis nach gegeben sein, obwohl ich das nicht will.
Aber vil. habe ich das auch missverstanden!?
ketchupfleck schrieb:
Wie wärs wenn du gar nicht direkt auf die Bilder verlinkst, sondern auf eine PHP-Datei, welche dann Prüft ob der Benutzer die entsprechenden Rechte hat und dann das Bild ausgibt.
Du verlinkst also anstatt auf http://example.com/pics/bild1.png auf http://example.com/show.php?bild=bild1
Die Lösung klingt kompliziert (Bin noch nicht so ganz Sattelfest, was PHP angeht.) und außerdem bin ich mir nicht sicher, ob das wirklich funktioniert.
Die Bilder kann man als Thumbnails sehen. Ein Klick auf das Thumbnail -> Lightbox geht auf - Großes Bild zu sehen.
(Ich glaube man kann die Lightbox nicht an so etwas verlinken wie "show.php?bild=bild1")
Abgesehen davon: Würde es durch diesen Code nicht mehr möglich sein, einfach einen Rechtsklick auf das Bild zu machen, und "Grafik in neuem Tab anzeigen" zu drücken? (Bzw. das schon, aber steht dann in der URL Leiste eben das "show.php?bild=bild1" und nicht "bild1.jpg"? )
thomasba schrieb:
Mit .htaccess kannst du dann den Ornder schützen, in welchem die Bilder liegen, denn darauf muss keiner direkt zugreifen, denn der zugriff erfolgt über die PHP-Datei.
Genau das ist ja das Problem...
Die PHP Datei hat dann auch keinen Zugriff mehr auf das Bild, wenn es mit .htaccess geschützt ist :/
Danke für die vielen Antworten
Sincer -
thomasba schrieb:
Mit .htaccess kannst du dann den Ornder schützen, in welchem die Bilder liegen, denn darauf muss keiner direkt zugreifen, denn der zugriff erfolgt über die PHP-Datei.
Genau das ist ja das Problem...
Die PHP Datei hat dann auch keinen Zugriff mehr auf das Bild, wenn es mit .htaccess geschützt ist :/
Nein, denn PHP greift auf die Datei nicht über den Webserver zu!
Für PHP ist das Bild eine ganz normale Lokale Datei, für dich, der dir am Ende die Passwortabfrage sieht, ist es eine Datei irgendwo im Internet ;)
=> htaccess passwortschutz beeinflusst PHP nicht -
Ich glaube ich habe es zu kompliziert erklärt. Ich führe es mal vor:
Wenn du zuerst auf http://ketchupfleck.lima-city.de/sincer/show.php?bild=bild1 gehst, wirst du die Meldung bekommen, dass du nicht die nötigen Rechte hast dieses Bild zu sehen. Wenn du allerdings auf http://ketchupfleck.lima-city.de/sincer/auth.php klickst und dann dem Link folgst hast du die benötigten Rechte.
Wie Funktioniert das? Zuerst einmal der Code von der auth.php:
Wie du siehst nichts aufregendes: Ich setzte nur die Session-Variable 'rechte' sobald du die Seite aufrufst.<?php session_start(); $_SESSION['rechte']=True; ?>
Nun der Code der show.php
Der Code ist ein bisschen mehr, aber auch nicht kompliziert. Ich teste ob die Session-Variable 'rechte' True ist. Wenn sie das nicht ist, war der Benutzer vorher nicht auf der auth.php und er bekommt eine Fehlermeldung. Wenn sie True ist, dann hole ich mir den Bildnamen aus dem Get-Wert und zeige das Bild an. Ob du die Session dann am Schluss mit session_destroy() beendest oder nicht liegt an dir. Ich habe es gemacht, und somit muss der Benutzer immer zuerst über die auth.php gehen um das Bild zu sehen. Wenn du die Session nicht beendest bzw. die Variable nicht löscht, dann muss der User nur einmal (so lange die Session gültig ist) über die auth.php gehen um das Bild zu sehen. Übrigends ist das angezeigte Bild dann auch vom Mime-type ein Bild (und keine PHP-Datei) von daher solltest du das vermutlich auch in die LightBox einbauen können. Es wird dir vielleicht auch aufgefallen sein, dass man das Bild unter http://ketchupfleck.lima-city.de/sincer/bild1.png immernoch direkt aufrufen kann, du musst es also in deiner Ordnerstruktur irgendwo verstecken.<?php session_start(); if($_SESSION['rechte']){ $bild=$_GET["bild"]; $im = imagecreatefrompng($bild.".png"); header('Content-type: image/png'); imagepng($im); imagedestroy($im); session_destroy(); } else{ echo "Sie haben nicht die benoetigten Rechte um das Bild zu sehen"; } ?>
Würde es durch diesen Code nicht mehr möglich sein, einfach einen Rechtsklick auf das Bild zu machen, und "Grafik in neuem Tab anzeigen" zu drücken? (Bzw. das schon, aber steht dann in der URL Leiste eben das "show.php?bild=bild1" und nicht "bild1.jpg"? )
Wie schon gesagt :Wenn du die Session Variable nicht löscht, darf dieser Benutzer (und nur er) das Bild solange sehen wie die Session gültig ist. Also "Grafik in neuem Tab anzeigen" würde funktionieren. In der URL steht dann ...show.php?bild=bild1.
@thomasba: Ich habe readfile bisher nur verwendet, wenn ich Usern das Bild zum Download anbieten wollte, deshalb weiß ich nicht ob das funktioniert. -
ketchupfleck schrieb:
@thomasba: Ich habe readfile bisher nur verwendet, wenn ich Usern das Bild zum Download anbieten wollte, deshalb weiß ich nicht ob das funktioniert.
Es funktioniert, der Browser entscheidet ja anhand des Content-Type, ob die Datei angezeigt wird, oder eben der Download Dialog angezeigt wird.
Die Version mit readfile ist halt nicht so Speicherintensiv, bei großen Bilder kann es mit deiner Version vorkommen, das PHP zu viel speicher benötigt und mit einem Fehler beendet. -
@sincer:
.htaccess:
RewriteEngine On RewriteCond %{REMOTE_HOST} !^karlsve\.lima-city\.de RewriteRule .*\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG)$ http://karlsve.lima-city.de/testbox/
Versuch es mit diesem Code der leitet den Zugriff auf deine Startseite um wenn du sie einsetzt für meine Seite.
Ich habe es bei mir eingefügt auf einer Seite.
http://karlsve.lima-city.de/testbox/
Und bei mir funktioniert es soweit ganz gut.
Wenn es bei dir nicht funktionieren sollte dann weiß ich auch nicht weiter mit htaccess
MfG
karlsve
Edit:
Wie werden die Bilder abgerufen?
Beitrag zuletzt geändert: 28.9.2009 4:51:26 von karlsve -
karlsve schrieb:
@sincer:
.htaccess:
RewriteEngine On RewriteCond %{REMOTE_HOST} !^karlsve\.lima-city\.de RewriteRule .*\.(gif|GIF|jpg|JPG|jpeg|JPEG|png|PNG)$ http://karlsve.lima-city.de/testbox/
Versuch es mit diesem Code der leitet den Zugriff auf deine Startseite um wenn du sie einsetzt für meine Seite.
Ich habe es bei mir eingefügt auf einer Seite.
http://karlsve.lima-city.de/testbox/
Und bei mir funktioniert es soweit ganz gut.
Wenn es bei dir nicht funktionieren sollte dann weiß ich auch nicht weiter mit htaccess
Dadruch kann er aber immer noch nicht abrufen, ob die Person auch auf das Bild zugreifen darf ;)
Hier mal meine Lösung komplett:
Im Ordner bilder liegen im Beispiel die BIlder!
.htaccess (wenn der Pfad umgeschrieben werden soll)
RewriteEngine on Options FollowSymLinks RewriteBase / RewriteRule ^bild/(.*) bild.php?bild=$1
dadruch kann man das Bild dann so aufrufen: bild/wasweisich.jpg anstelle von bild.php?bild=wasweisich.jpg
bilder/.htaccess
deny from all
bild.php
<?php // kan ganz einfach durch eine eigene Abfrage ersetzt werden if($_SESSION["darf_zugreifen"] !== true) { die("Keine Berechtigung"); } // ../ rausfiltern! $file = "bilder/".str_replace("../","",$_GET["bild"]); // prüfen ob datei existiert: if(!file_exists($file)) { die("Bild nicht gefunden!"); } // Richtigen Content-Type mitliefern: $mime = mime_content_type($file); header("Content-Type: $mime"); // Fileread: weniger speicherintensiv als imagepng usw. readfile($file); exit(); ?>
Beitrag zuletzt geändert: 28.9.2009 11:44:08 von thomasba -
ho ;)
thomasba schrieb:
Nein, denn PHP greift auf die Datei nicht über den Webserver zu!
Für PHP ist das Bild eine ganz normale Lokale Datei, für dich, der dir am Ende die Passwortabfrage sieht, ist es eine Datei irgendwo im Internet ;)
=> htaccess passwortschutz beeinflusst PHP nicht
Wenn das so ist wie du sagst, frage ich mich aber, warum auf meiner Seite dann steht "Auf das Bild kann nicht zugegriffen werden!", sobald ich eine .htaccess Datei hoch lade.
Ich verwende ein Thumbnail Script, dass mir zuerst die Fotos verkleinert, um sie schön anzeigen zu lassen (Ich glaube, es ist das gleiche oder zumindest ein sehr ähnliches, das karlsve auch benützt.) und dann die Lightbox, um die original Bilder anzeigen zu lassen.
Auf jeden Fall gibt dieses Script diese Meldung aus, wenn es keinen Zugriff auf die Fotos hat. (Das beutet entweder, dass der Angegebene Pfad nicht stimmt, oder das Script keine Berechtigung hat... In dem Fall das 2.)
-> Die .htaccess Datei beeinflusst das PHP Thumbnail Script sehr wohl.
(Oder ich habe irgend etwas übersehen...)
ketchupfleck schrieb:
Es wird dir vielleicht auch aufgefallen sein, dass man das Bild unter http://ketchupfleck.lima-city.de/sincer/bild1.png immernoch direkt aufrufen kann, du musst es also in deiner Ordnerstruktur irgendwo verstecken.
Also, das habe ich nicht dazu gesagt. Sry... Ich habe schon ein Loginsystem. Es funktioniert eig. wie du es gesagt hast. (Sessions). Die Fotoshow (Tumbnails -> Lightbox) sieht man also nur, wenn man eingeloggt ist.
Allerdings kann jeder das Foto direkt aufrufen, wenn er den Link hat. (zB meineseite.at/pics/foto1.jpg) und genau das möchte ich verhindern...
Jetzt hast du natürlich eine nette Methode genannt, um den Link zum Bild zu verschleiern... (Gibt es eig. eine Möglichkeit, von dem Link (show.php?bild=bild1) auf den richtigen Link zu schließen?)
D.h., wenn ich das richtig verstanden habe. Ich verlinke jedes Bild nur auf diese weise. Jeder, der eingeloggt ist, kann das Foto sehen, ... Natürlich auch in einem neuen Tab anzeigen lassen, den Link verschicken, der aber keinem etwas nützt, der die passenden Sessions nicht hat. (Soweit habe ich das ja richtig verstanden, oder?)
Zwei Fragen dazu:
1) Gibt es eine andere Weise (also nicht durch Link-Weitergabe - diese Möglichkeit wurde durch das Script ausgeschlossen) den richtigen Pfad des Bildes herauszufinden? ("Hey, da ist ein Webspace, scannen wir den mal auf alle Bilderformate durch...") Klingt vil. jetzt blöd, aber wie du selbst gesagt hast... Wenn man den direkten Link zum Foto kennt, ist das Script logischerweise auch machtlos.
2) Wie funktioniert das genau? (Wie gesagt... Ich lerne immer wieder dazu, aber bei PHP sind mir viele Dinge noch unbekannt.)
$bild=$_GET["bild"]; $im = imagecreatefrompng($bild.".jpg"); header('Content-type: image/jpg'); imagejpg($im); imagedestroy($im);
(Die Frage bezieht sich sowohl auf den Code, als auch auf die Anwendung XD )
Anwendung:
Ohne deinem Script: (Habe jetzt mal das Unwichtige weg gelassen.)
<a href="pics/foto1.jpg" rel="lightbox"><img src="thumbnail.php?src=pics/foto1.jpg&p=150 /></a>
(Erklärung: Ein A-Tag ruft die Lightbox hervor... wobei pics/foto1.jpg ein direkter Link ist... thumbnail.php?src=xy.jpg ruft das originale Bild auf, und verkleinert es (in dem Fall auf höhe oder breite 150px). Aber auch das kann man in der URL aufrufen. (Ist dann halt ein kleines Foto, allerdings nicht PW geschützt...)
Mit deinem Script: (Ich nenne dein Script mal bildverschleirung.php ^^ und speichere es in das Hauptverzeichnis, in dem auch die index.php liegt)
<a href="bildverschleierung.php?bild=bild1" rel="Lightbox"><img bildverschleierung.php?bild=thumbnail.php?src=pics/foto1.jpg&p=150 /></a>
Ginge das überhaupt?
Funktionsweise: (ACHTUNG - Habe das Script auf meine Bedürfnisse (hoffentlich richtig) angepasst!)
$bild=$_GET["bild"]; // ist mir klar -> Aus der URL wird der Parameter geholt... in dem Fall bild1
$im = imagecreatefrompng("pics/".$bild.".jpg"); // -> Das würde bedeuten, dass es in dem ordner pics ein Bild namens bild1.jpg gibt.
header('Content-type: image/jpg'); // -> Habe noch nicht damit gearbeitet, aber meines Wissens sagt diese Zeile dem Browser einfach nur "Hey, die folgende Information ist ein Bild."
imagejpg($im); // -> Uff... ich hoffe, dass es den Befehl überhaupt gibt "imageJPG();" KA, was der Macht :/
imagedestroy($im); // -> Ich schätze mal, das ist wie session_destroy(); - Muss ich das überhaupt verwenden? Wenn ja, warum? Was macht es genau...?
Das ganze wäre für mich eig. eine akzeptable Lösung.
(Schützen kann ich die Bilder eh nicht. Wie ihr auch schon gesagt habt. Screen-Shot oder ähnliches... Aber es geht darum, dass die meisten User sowieso nicht wollen, dass außer ihnen jem. an die Pics ran kommt. Mir geht es nur darum, mir die Weste sauber zu halten. Falls ein Bild nach außen dringt kann ich ruhigen Gewissens sagen, dass ich es nicht verhindern kann, dass jeder User, der die Bilder sehen kann, sie genauso gut speichern und weiter senden kann. Mir geht es nur darum zu verhindern, dass ein "Fremder" die Fotos auf meinem Server sehen kann...)
karlsve schrieb:
Versuch es mit diesem Code der leitet den Zugriff auf deine Startseite um wenn du sie einsetzt für meine Seite.
Vil. habe ich etwas missverstanden, aber ich habe folgendes versucht:
Eine .htaccess Datei mit deinem Code in das Hauptverzeichnis (Dort, wo auch die index.php liegt) mit dem verbot, auf meineseite.at/pics zuzugreifen, bzw. auf die index.php umzuleiten.
Das hat zwar schön funktioniert, allerdings habe ich das gleiche Problem, das ich ganz oben angesprochen habe. Mein Thumbnail Script gab mir die Meldung aus, dass es keinen Zugriff auf die Bilder hat...
Kurz gesagt: Ob Access Deny, oder Umleitung... Die Bilder werden nicht mehr angezeigt :/
@all:
Ich kann euch gar nicht genug für eure Mühe danken :)
lg
Sincer -
Also, das habe ich nicht dazu gesagt. Sry... Ich habe schon ein Loginsystem. Es funktioniert eig. wie du es gesagt hast. (Sessions). Die Fotoshow (Tumbnails -> Lightbox) sieht man also nur, wenn man eingeloggt ist.
Allerdings kann jeder das Foto direkt aufrufen, wenn er den Link hat. (zB meineseite.at/pics/foto1.jpg) und genau das möchte ich verhindern...
Das ist mir bewusst, deshalb habe ich ja vorgeschlagen, dass du den Link nicht rausrückst, sondern nur den Link zu einer PHP-Datei welche dann prüft ob der Benutzer eingeloggt ist und dann das Bild ausgibt. Damit man den Pfad zum Bild aber nicht raten kann musst du das Bild in deiner Ordnerstruktur verstecken. D.h. du speicherst die Bilder nicht unter http://example.com/pics/bild1.png sondern z.B. unter http://example.com/asdfzufhf/bild1.png
Jetzt hast du natürlich eine nette Methode genannt, um den Link zum Bild zu verschleiern... (Gibt es eig. eine Möglichkeit, von dem Link (show.php?bild=bild1) auf den richtigen Link zu schließen?)
Genau deswegen musst du das Bild in der Ordnerstruktur verstecken. Wenn du die bilder mit show.php?bild=bild1 verlinkst und das Bild findet man dann in /pics/bild1.png, dann ist das leicht zu erraten und unsicher. Wenn sich das Bild aber in /ffzfgzuassd/bild1.png befindet, findet das niemand raus.
Ich verlinke jedes Bild nur auf diese weise. Jeder, der eingeloggt ist, kann das Foto sehen, ... Natürlich auch in einem neuen Tab anzeigen lassen, den Link verschicken, der aber keinem etwas nützt, der die passenden Sessions nicht hat. (Soweit habe ich das ja richtig verstanden, oder?)
Richtig, genau so funktionierts.
Zwei Fragen dazu:
1) Gibt es eine andere Weise (also nicht durch Link-Weitergabe - diese Möglichkeit wurde durch das Script ausgeschlossen) den richtigen Pfad des Bildes herauszufinden? ("Hey, da ist ein Webspace, scannen wir den mal auf alle Bilderformate durch...") Klingt vil. jetzt blöd, aber wie du selbst gesagt hast... Wenn man den direkten Link zum Foto kennt, ist das Script logischerweise auch machtlos.
Wenn du in jedem Unterverzeichniss eine (leere) index.html oder index.php hast, dann gibt es diese Möglichkeit nicht, ausser durch Brute-Force (d.h. reines Ausprobieren). Das jemand das Bild findet ist wirklich sehr sehr unwahrscheinlich wenn du sie in einem Ordner versteckt hast dessen Name keinen sinn ergibt (also z.B. " ffzfgzua3321ssd/). Die index.html bzw index.php solltest du sowieso in jedes Verzeichniss packen, unabhängig von meinem Script.
2) Wie funktioniert das genau? (Wie gesagt... Ich lerne immer wieder dazu, aber bei PHP sind mir viele Dinge noch unbekannt.)
Erklär ich weiter unten.
Mit deinem Script: (Ich nenne dein Script mal bildverschleirung.php ^^ und speichere es in das Hauptverzeichnis, in dem auch die index.php liegt)
<a href="bildverschleierung.php?bild=bild1" rel="Lightbox"><img bildverschleierung.php?bild=thumbnail.php?src=pics/foto1.jpg&p=150 /></a>
Ginge das überhaupt?
Der erste Teil geht ziemlich sicher, aber "bildverschleierung.php?bild=thumbnail.php?src=pics/foto1.jpg&p=150" funktioniert nicht. Da musst du beide Scripte zu einem zusammenfügen und dann praktisch den Bildpfad zu <img src="bildverschleierung.php?bild=djhf&p=150"> machen. Da muss man ein bisschen aufpassen. Ich könnte dir auch die Scripte zusammenfügen, allerdings bräuchte ich dann den Code von der thumbnail.php. Wenn du es selber machen willst, musst du den Code aus der thumnail.php nach dem imagecreatefromjpeg() einfügen und so abändern, dass er mit der Imageressource $im arbeitet, und sie verkleinert wenn $_GET["p"] gesetzt ist. Genaueres kann ich nicht sagen, da müsstest du den Code der thumbnail.php posten.
Funktionsweise:
$bild=$_GET["bild"]; // ist mir klar -> Aus der URL wird der Parameter geholt... in dem Fall bild1
Richtig
$im = imagecreatefrompng("pics/".$bild.".jpg"); // ->; Das würde bedeuten, dass es in dem ordner pics ein Bild namens bild1.jpg gibt.
Naja, einfach gesagt läd er das Bild in die Variable $im
header('Content-type: image/jpg'); // -> Habe noch nicht damit gearbeitet, aber meines Wissens sagt diese Zeile dem Browser einfach nur "Hey, die folgende Information ist ein Bild."
Genau.
imagejpg($im); // -> Uff... ich hoffe, dass es den Befehl überhaupt gibt "imageJPG();" KA, was der Macht :/
Dieser Befehl gibt das Bild wieder aus. Den Befehl imagejpg() gibt es.
imagedestroy($im); // -> Ich schätze mal, das ist wie session_destroy(); - Muss ich das überhaupt verwenden? Wenn ja, warum? Was macht es genau...?
Diese Funktion musst du am Ende verwenden um den benötigten Ram wieder freizugeben. Klingt komisch, ist aber so.
@thomasba: ich befürchte aber eine rießige Sicherheitslücke wenn du readfile() benutzt. Stell dir mal vor jemand ruft diese Seite auf [url]http://example.com/show.php?bild=/etc/passwd\0[/url]. Dein readfile-Script gibt dann einfach so die Datei aus, wenn du nicht die GET-Werte aufwändig absicherst. Mein Script gibt eine Fehlermeldung aus, dass die Datei kein gültiges Format hat. Klar, dafür frisst es ein Bisschen mehr Memory, aber das ist nicht Weltbewegend. -
Alles klar :)
Also was ich schon von Anfang an getan habe, ist eine index.php datei in jeden Ordner zu legen. (Egal ob nun Bilder, oder andere Dateien drinnen sind. Ich habe keine Server Config rechte - kA, ob das mit .htaccess geht, aber ich wollte einfach verhindern, dass man eine "index of" Tree-Liste sehen kann.) Diese index.php leitet einfach auf die eigene 404 Errorseite um (als hätte man eine URL angegeben, die es nicht gibt.) Man kann meiner Erfahrung nach also nicht erkennen, ob es sich nun um eine Weiterleitung, oder wirklich um einen unbekannten Pfad handelte.
Den Ordner, in dem sich die Bilder befinden, muss ich noch umbenennen...
Hier einmal das Thumbnail Script. (Hab es einfach 1:1 übernommen, da ich mich nicht weiter damit auseinandersetzen wollte...)
<?php # Nachfolgende Funktion ist für die Ausgabe eventueller Fehler als Bild zuständig function error_message($text = ''){ $img = imagecreatetruecolor(strlen($text) * 7, 20); // Erstellt ein neues Bild imagefill($img, 0, 0, imagecolorallocate($img, 255, 255, 255)); // Malt das bild weiß aus imagestring($img, 2, 0, 0, $text, imagecolorallocate($img, 0, 0, 0)); // Schreibt den Text der der Funktion übergeben wurde auf das Bild imagepng($img); // Gibt das Bild aus imagedestroy($img); // Löscht das Bild aus dem Arbeitsspeicher des Servers } $img_src = $_GET['src']; // Pfad zum Bild aus welchem das Thumbnail erstellt werden soll $cache_dir = './cache'; // Pfad zum Cache Verzeichnis wo später die Bilder gespeichert werden $cache = true; // Gibt an ob die Bilder aus dem Cache geladen werden sollen # Überprüft ob ein Bildpfad übergeben wurde if (!isset($_GET['src'])){ error_message('Es wurde kein Bildpfad übergeben aus dem ein Thumbnail ezeugt werden könnte'); // Gibt eine Fehlermeldung aus } # Auslesen der Bildgröße und des Bildtyps $image_infos = @getimagesize($img_src) or error_message('Auf das Bild kann nicht zugegriffen werden'); $width = $image_infos[0]; $height = $image_infos[1]; $type = $image_infos[2]; $mime = $image_infos['mime']; # Berechnung der Maße des Thumbnails if (isset($_GET['p']) && !isset($_GET['w']) && !isset($_GET['h'])){ // Überprüfen ob die Bildgröße proportional berechnet werden soll if($width < $height) { // Überprüfen ob das Bild Hoch- oder Querformat ist $new_width = ceil(($_GET['p'] / $height) * $width); $new_height = intval($_GET['p']); // Zuweisen der neuen Höhe } else { $new_height = ceil(($_GET['p'] / $width) * $height); $new_width = intval($_GET['p']); // Zuweisen der neuen Breite } } else if (isset($_GET['w']) && !isset($_GET['h']) && !isset($_GET['p'])){ // Überprüfen ob die Breite oder die Höhe berechnent werden soll $new_width = intval($_GET['w']); // Zuweisen der neuen Breite $new_height = ceil($height * $new_width / $width); // Berechnen der neuen Höhe } else if (isset($_GET['h']) && !isset($_GET['w']) && !isset($_GET['p'])){ // Überprüfen ob die Breite oder die Höhe berechnent werden soll $new_height = intval($_GET['h']); // Zuweisen der neuen Höhe $new_width = ceil($width * $new_height / $height); // Berechnen der neuen Breite } else if (isset($_GET['h']) && isset($_GET['w']) && isset($_GET['p'])){ $new_height = intval($_GET['h']); // Zuweisen der neuen Höhe $new_width = intval($_GET['w']); // Zuweisen der neuen Breite } else { error_message('Es muss entweder die neu Höhe oder die neu Breite angegeben werden.'); // Fehlermeldung ausgeben } # Prüft ob das Chache Verzeichnis existiert bzw. benötigt wird und legt dieses eventuell an if ($cache === true && !file_exists($cache_dir)){ mkdir($cache_dir) or error_message('Das Cache Verzeichnis konnte nicht angelegt werden'); // Legt das Cache Verzeichnis an. Sollte dies nicht möglich sein, so wird ein Fehler ausgegeben chmod($cache_dir, 0777); // Gibt dem Cache Verzeichniss die nötigen Schreib- und Lese Rechte } # Ermitteln des Bildtypes und Erstellung des Thumbnails switch ($type){ case 1: header('Content-type: '.$mime); // Header ausgeben if (imagetypes() & IMG_GIF){ // Überprüfen ob das Bildformat untestützt wird if (!file_exists($cache_dir.'/'.md5($img_src).'.gif')){ // Wenn das Thumbnail nicht existiert wird es erstellt $orginal = imagecreatefromgif($img_src) or error_message('Das Bild wurde nicht gefunden'); // Bild aus dem Orginalbild erstellen $thumb = imagecreatetruecolor($new_width, $new_height); // Das Thumbnailbild erstellen imagecopyresampled($thumb, $orginal, 0, 0, 0, 0, $new_width, $new_height, $width, $height); if ($cache === true){ // Prüft ob das Bild gespeichert werden soll imagegif($thumb, $cache_dir.'/'.md5($img_src).'.gif') or error_message('Das Bild konnte nicht gespeichert werden'); // Bild speichern } imagegif($thumb); // Bild ausgeben } else { readfile($cache_dir.'/'.md5($img_src).'.gif') or error_message('Das Bild wurde nicht gefunden'); // Bild ausgeben } } else { error_message('GIF Bilder werden nicht unterstützt'); // Fehlermeldung ausgeben, wenn das Bildformat nicht unterstützt wird } break; case 2: header('Content-type: '.$mime); // Header ausgeben if (imagetypes() & IMG_JPG){ // Überprüfen ob das Bildformat untestützt wird if (!file_exists($cache_dir.'/'.md5($img_src).'.jpg')){ // Wenn das Thumbnail nicht existiert wird es erstellt $orginal = imagecreatefromjpeg($img_src) or error_message('Das Bild wurde nicht gefunden'); // Bild aus dem Orginabild erstellen $thumb = imagecreatetruecolor($new_width, $new_height); // Das Thumbnailbild erstellen imagecopyresampled($thumb, $orginal, 0, 0, 0, 0, $new_width, $new_height, $width, $height); if ($cache === true){ // Prüft ob das Bild gespeichert werden soll imagejpeg($thumb, $cache_dir.'/'.md5($img_src).'.jpg') or error_message('Das Bild konnte nicht gespeichert werden'); // Bild speichern } imagejpeg($thumb); // Bild ausgeben } else { readfile($cache_dir.'/'.md5($img_src).'.jpg') or error_message('Das Bild wurde nicht gefunden'); // Bild ausgeben } } else { error_message('JPEG Bilder werden nicht unterstützt'); // Fehlermeldung ausgeben, wenn das Bildformat nicht unterstützt wird } break; case 3: header('Content-type: '.$mime); // Header ausgeben if (imagetypes() & IMG_PNG){ // Überprüfen ob das Bildformat untestützt wird if (!file_exists($cache_dir.'/'.md5($img_src).'.png')){ // Wenn das Thumbnail nicht existiert wird es erstellt $orginal = imageCreateFromPNG($img_src) or error_message('Das Bild wurde nicht gefunden'); // Bild aus dem Orginalbild erstellen $thumb = imagecreatetruecolor($new_width, $new_height); // Das Thumbnailbild erstellen imagecopyresampled($thumb, $orginal, 0, 0, 0, 0, $new_width, $new_height, $width, $height); if ($cache === true){ // Prüft ob das Bild gespeichert werden soll imagepng($thumb, $cache_dir.'/'.md5($img_src).'.png') or error_message('Das Bild konnte nicht gespeichert werden'); // Bild speichern } imagepng($thumb); // Bild ausgeben } else { readfile($cache_dir.'/'.md5($img_src).'.png') or error_message('Das Bild konnte nicht gespeichert werden'); // Bild ausgeben } } else { error_message('PNG Bilder werden nicht unterstützt'); // Fehlermeldung ausgeben, wenn das Bildformat nicht unterstützt wird } break; default: error_message('Das Bildformat wird nicht unterstützt'); // Fehlermeldung ausgeben, wenn das Bildformat nicht unterstützt wird } # Löscht das Bild aus dem Speicher des Servers falls es existiert if (isset($thumb)){ imagedestroy($thumb); } ?>
Aufgerufen wird es wie schon gezeigt mit <img src="thumbnail.php?src=pfad/bild.jpg&p=150" /> (Wobei 150 für die Anzahl an px der höchsten oder breitesten Stelle des Bildes steht.)
Wenn du die Zeit dafür hast, dir das durchzusehen, und für den Bilder-Schutz abzuändern, wäre es auch klasse, wenn du mir dazu sagst, was genau du geändert hast...
Wie gesagt, obwohl an erster Stelle steht, dass alles Funktioniert, will ich es ja auch lernen. (Dieses Script ist mir zwar noch ein paar Stufen zu hoch für mich, aber ich taste mich immer wieder ran und lerne Schritt für Schritt dazu :) )
Auf jeden Fall vielen lieben Dank für deine Hilfsbereitschaft ;)
thx
Sincer -
ketchupfleck schrieb:
@thomasba: ich befürchte aber eine rießige Sicherheitslücke wenn du readfile() benutzt. Stell dir mal vor jemand ruft diese Seite auf [url]http://example.com/show.php?bild=/etc/passwd\0[/url]. Dein readfile-Script gibt dann einfach so die Datei aus, wenn du nicht die GET-Werte aufwändig absicherst. Mein Script gibt eine Fehlermeldung aus, dass die Datei kein gültiges Format hat. Klar, dafür frisst es ein Bisschen mehr Memory, aber das ist nicht Weltbewegend.
Und du meinst das Funktioniert hier?
$file = "bilder/".str_replace("../","",$_GET["bild"]);
erstens wird hier immer das Verzeichniss bilder verwendet und zweitens wird ein betreten der Übergeordneten Verzeichnisse verhindert.
Ich sehe da keine Möglichkeit, andere dateien als die im Ordner Bilder auszulesen
Btw.: bei der Lösung mit imagejpeg geht etwas an Bildqualität verloren. Außerdem kann bei größeren Bildern dieser Fehler erscheinen:
Fatal error: Allowed memory size of 41943040 bytes exhausted (tried to allocate 17152 bytes) in /home/webpages/lima-city/thomasba/html/lima/img/imagejpeg.php on line 7
Beitrag zuletzt geändert: 29.9.2009 0:28:17 von thomasba -
Also ich habe es mal noch ein bisschen weiter versucht und bin schließlich zu der Einsicht gekommen, dass das beste eine Mischung aus .htaccess und php ist.
Also du sicherst die bilder indem du den Zugriff von außen verhinderst.
(was auch bei einem in <img> tag eingebundenen bild geschieht)
Dies geschieht mit .htaccess.
und dann leitest du die ganzen sachen über eine php Datei um ... wie sincer schon die ganze Zeit schreibt.
somit ist sowohl die möglichkeit, dass jemand durch zufall die bildnamen errät ausgeschlossen und damit auf sie zugreifen kann und du kannst mit der php datei noch abfragen ob derjenige der das bild aufruft auch angemeldet ist.
So hab ich das jetzt gemacht nur dass ich im moment noch daran arbeite das ganze so einzurichten dass ich cookies benutze und nen hash wert so das man nur über meine seite die bilder ansehen kann und nicht über das bild.php script.
MfG
karlsve
PS:
Ist alles nicht so schwer, du musst nur in etwa das ausführen was sincer geschrieben hat.
(Da du ja schon sessions benutzt dürfte das nicht sooo schwer für dich sein :D ich hab da so meine probleme mit mit sessions und cookies bei mir will das nie so wie ich will) -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage