Crash2001 Geschrieben 10. Januar 2006 Geschrieben 10. Januar 2006 Hi zusammen. Ich habe mir folgendes kleines Script geschrieben: <?php if (!ini_get('register_globals')){ $types_to_register = array('POST','SESSION'); foreach ($types_to_register as $type) { if (@count(${'HTTP_' . $type . '_VARS'}) > 0) { extract(${'HTTP_' . $type . '_VARS'}, EXTR_OVERWRITE); } } } if(!empty($bla)) { if($foo == '1'){ $url="http://www.server/pfad/test.zip"; } else{ header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT"); header ("Cache-Control: no-cache, must-revalidate"); header ("Pragma: no-cache"); echo "Keine gültige ID übergeben."; exit(); } $url=urldecode($url); header("location:$url"); } else { header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT"); header ("Cache-Control: no-cache, must-revalidate"); header ("Pragma: no-cache"); echo "Keine gültige ID übergeben."; } ?>[/PHP] Es wird an die Datei per POST-Methode oder per Session die Variable übergeben, damit der Link zur Datei nicht einfach gebookmarkt werden kann. Ziel des ganzen soll eine Weiterleitung mittels einer php-Datei zu z.B. zip-Dateien sein die auf meinem Webspace liegen, aber deren URL der User nicht einfach sehen soll. (Später läuft das statt mittels [i]if($foo == '1')[/i] über eine Datenbankabfrage, die die entsprechende Ziel-URL liefert). Das ganze funktioniert auch soweit, nur ich würde gerne wissen, wie sicher diese Methode ist und ob es vielleicht noch eine andere einfache und sicherere/sinnvollere Methode dafür gibt. Also her mit eurer Kritik. Zitieren
cane Geschrieben 10. Januar 2006 Geschrieben 10. Januar 2006 Könntest du erläutern warum der User die URLs nicht sehen soll - dann wird es einfacher Alternativen vorzuschlagen. Generell lassen sich alle Sachen umgehen, deine Lösung schützt aber die URLs vor DAUs. Jemand mit Ahnung hängt nen Proxy in die HTTP-Connection und filtert POSTS mit um Muster / Variablen zu erkennen... mfg cane Zitieren
geloescht_JesterDay Geschrieben 10. Januar 2006 Geschrieben 10. Januar 2006 Hi zusammen. Ich habe mir folgendes kleines Script geschrieben: <?php if (!ini_get('register_globals')){ $types_to_register = array('POST','SESSION'); foreach ($types_to_register as $type) { if (@count(${'HTTP_' . $type . '_VARS'}) > 0) { extract(${'HTTP_' . $type . '_VARS'}, EXTR_OVERWRITE); } } } if(!empty($bla)) { if($foo == '1'){ $url="http://www.server/pfad/test.zip"; } [...] [/php] Erstmal dein selbstgebasteltes Register_Globals. Lass es weg und schreib deine Skripte so, dass sie das nicht brauchen. Beispiel (ang. dein Skript oben heißt script.php): Der Aufruf von http://a.b.c/script.php liefert die Meldung: Keine gültige ID übergeben. Wenn ich das ganze aber so aufrufe: http://a.b.c/script.php?bla=x&foo=1 liefert es mir test.zip zurück, und das obwohl ich ja keine Berechtigung oder sonstwas hätte. Du schreibst die übergebenen Variablen, egal woher sie kommen, in eine "normale" Variable und hast somit keine Kontrolle mehr, woher der Inhalt eigentlich stammt. Ich kann also einfach z.B. mit einer manipulierten URL die Daten so ändern, wie ich es gern hätte. Dasselbe Problem war letztens für die Sicherheitslücke in Mambo/Joomla verantwortlich! OK... zu Rest: Wenn du die URLs eh in einer DB stehen hast, dann übergib doch nur eine ID o.ä. und die URL selber gar nicht. Um dies nicht bookmarkbar zu machen "codierst" du die ID noch mit dem Datum z.B.. Also wenn du die Links aufbaust bestimmst du die Zeit (z.B.) und schreibst diese auch in die Session. $zeitcode = getdate()["yday"]; // numerischer Tag des Jahres $_SESSION["zeitcode"] = $zeitcode; Dazu addierst du dann die ID, also z.B. 1001: $id = 1001; $code = $zeitcode + $id; <a href="script.php?id=<?php echo $code; ?>">Hier klicken</a> In deinem Script nimmst du die ID und ziehst den Zeitcode ab, mit der ID greifst du dann auf die DB zu, liest die URL (oder nur den Dateinamen und Pfad, liegt ja eh auf deinem Webspace!), liest die Datei ein und sendest sie mit entspr. Header an den Client. Bsp (mit Name+Pfad): [php] $id = $_GET["id"] - $_SESSION["zeitcode"]; $file = db_get($id); //liefert infos aus der DB $filename = $file[0]; $mimetype = $file[1]; // in der DB ist der Pfad plus der MIME-Typ gespeichert // header senden header("content-disposition: attachement"); header("content-type:".$mimetype); // Datei lesen und ausgeben readfile($filename); So ist ein Link nur einmal im Jahr verwendbar. (Das ist natürlich nur ein Beispiel und müsste noch etwas überarbeitet werden) Also mit Bookmarken ist dann nix. So in der Art würde ich das machen. EDIT: Die richtige URL zur Datei sieht somit keiner. Die Datei muss dann nichtmal im öffentlichen Bereich liegen (also nur du oder php hat Zugriff darauf). Mit der Umleitung von dir, sieht man die URL nämlich dennoch, wenn man will Und das willst du ja aber verhindern. Zitieren
cane Geschrieben 10. Januar 2006 Geschrieben 10. Januar 2006 Interessante Lösung - Danke Jesterday! mfg cane Zitieren
geloescht_JesterDay Geschrieben 10. Januar 2006 Geschrieben 10. Januar 2006 Nachtrag zu meinem obigen Beitrag... das mit den GET-Parametern funktioniert natürlich mit dem angegebenen Code nicht, er wertet ja nur POST und SESSION Vars aus. Dennoch kann damit recht leicht z.B. eine Variable erzeugt oder geändert werden und das ganze ist sehr fehleranfällig/sicherheitskritisch. Anstelle $meineVar musst du eben $_POST["meineVar"] schreiben, das ist ja nun wirklich kein so großer Aufwand Zitieren
Crash2001 Geschrieben 10. Januar 2006 Autor Geschrieben 10. Januar 2006 Könntest du erläutern warum der User die URLs nicht sehen soll - dann wird es einfacher Alternativen vorzuschlagen. Generell lassen sich alle Sachen umgehen, deine Lösung schützt aber die URLs vor DAUs. Jemand mit Ahnung hängt nen Proxy in die HTTP-Connection und filtert POSTS mit um Muster / Variablen zu erkennen... mfg caneDer User soll die URL nicht sehen und bookmarken können, damit nur User von meiner Seite die Sachen runterladen können und diese nicht auf anderen Seiten als Links landen. Dass jemand der Ahnung hat auch das auslesen kann ist mir klar. Mir fiel aber keine andere Möglichkeit ein auf Anhieb. Erstmal dein selbstgebasteltes Register_Globals. Lass es weg und schreib deine Skripte so, dass sie das nicht brauchen. [...]Wenn ich das ganze aber so aufrufe: http://a.b.c/script.php?bla=x&foo=1 liefert es mir test.zip zurück, und das obwohl ich ja keine Berechtigung oder sonstwas hätte. Du schreibst die übergebenen Variablen, egal woher sie kommen, in eine "normale" Variable und hast somit keine Kontrolle mehr, woher der Inhalt eigentlich stammt. Ich kann also einfach z.B. mit einer manipulierten URL die Daten so ändern, wie ich es gern hätte.Das nutze ich auch nur zum testen, wenn ich noch nicht weiss, wie ich die übergebene Variable benennen soll, oder ob noch welche dazu kommen. Nachher ändere ich das schon noch um, dass auch nur die Variablen die ich auch wirklich übergebe ausgelesen werden. Nein, liefert es nicht, da das keine get_Variablen ausliest. Da ich mir noch nicht sicher war, ob ich das per Post oder Session lösen wollte, sind beide noch drin. (hast du ja nachher selber erkannt) [...]Es wird an die Datei per POST-Methode oder per Session die Variable übergeben, damit der Link zur Datei nicht einfach gebookmarkt werden kann. [...]OK... zu Rest: Wenn du die URLs eh in einer DB stehen hast, dann übergib doch nur eine ID o.ä. und die URL selber gar nicht.Ich übergebe doch nur die ID. :confused: Der Rest kommt später aus der DB. [...]In deinem Script nimmst du die ID und ziehst den Zeitcode ab, mit der ID greifst du dann auf die DB zu, liest die URL (oder nur den Dateinamen und Pfad, liegt ja eh auf deinem Webspace!), liest die Datei ein und sendest sie mit entspr. Header an den Client.Bsp (mit Name+Pfad): $id = $_GET["id"] - $_SESSION["zeitcode"]; $file = db_get($id); //liefert infos aus der DB $filename = $file[0]; $mimetype = $file[1]; // in der DB ist der Pfad plus der MIME-Typ gespeichert // header senden header("content-disposition: attachement"); header("content-type:".$mimetype); // Datei lesen und ausgeben readfile($filename); [/php]Klingt soweit okay. Muss ich mir mal überlegen. So ist ein Link nur einmal im Jahr verwendbar. (Das ist natürlich nur ein Beispiel und müsste noch etwas überarbeitet werden) Also mit Bookmarken ist dann nix. So in der Art würde ich das machen.Wenn der User das aber einmal durchschaut hat, bringt das auch nicht mehr viel und er könnte das einfach dann selber mitgeben, wenn er wie Cane oben beschrieb die POSt- und SESSIOn-Variablen sich anschaut. Da würde ich dann doch eher eine Zufallszahl präferieren, wenn die eh übergeben wird. EDIT: Die richtige URL zur Datei sieht somit keiner. Die Datei muss dann nichtmal im öffentlichen Bereich liegen (also nur du oder php hat Zugriff darauf). Mit der Umleitung von dir, sieht man die URL nämlich dennoch, wenn man will Und das willst du ja aber verhindern.Dass die keiner sieht wäre gut. Muss ich mal schauen, ob so ein Bereich per htaccess möglich ist, auf den PHP dennoch zugreifen kann. Nachtrag zu meinem obigen Beitrag... das mit den GET-Parametern funktioniert natürlich mit dem angegebenen Code nicht, er wertet ja nur POST und SESSION Vars aus.Richtig. Dennoch kann damit recht leicht z.B. eine Variable erzeugt oder geändert werden und das ganze ist sehr fehleranfällig/sicherheitskritisch. Anstelle $meineVar musst du eben $_POST["meineVar"] schreiben, das ist ja nun wirklich kein so großer Aufwand Das kommt wie oben schon angemerkt noch, wenn ich festgelegt habe, welche Variablen ich übergebe und das Script ins Endstadium geht. Gibt es per PHP eigentlich eine Möglichkeit auszulesen, über welchen Link bzw. woher der User kommt wie bei JavaScript, oder ist das nur im Browser sichtbar und kann nicht bgefragt werden? [NACHTRAG] [b][size=3]$bla sollte übrigens auch $foo heissen. Hatte mich da vertippt. [/size][/b] [/NACHTRAG] Zitieren
cane Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Gibt es per PHP eigentlich eine Möglichkeit auszulesen, über welchen Link bzw. woher der User kommt wie bei JavaScript, oder ist das nur im Browser sichtbar und kann nicht bgefragt werden? Das nennt sich Referer und läßt sich so auslesen: <? $referer ="$HTTP_REFERER "; echo "Sie kommen von: $referer"; ?> mfg cane Zitieren
geloescht_JesterDay Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Das nennt sich Referer und läßt sich so auslesen: Der Referer ist schön und gut, aber der muss nicht übergeben werden! Eine Seite zu machen, die den Referer vorraussetzt ist viel schlimmer als eine Seite, die Javascript vorraussetzt. Wenn der User das aber einmal durchschaut hat, bringt das auch nicht mehr viel und er könnte das einfach dann selber mitgeben, wenn er wie Cane oben beschrieb die POSt- und SESSIOn-Variablen sich anschaut. Da würde ich dann doch eher eine Zufallszahl präferieren, wenn die eh übergeben wird. Das mit dem numerischen Tag war ja nur eine erste Idee, ich meinte ja, das muss noch überarbeitet werden, vielleicht ja mit etwas weniger "offensichtlichem". Als Fortsetzung der obigen Idee fällt mir auf Anhieb z.B. ein: zusätzlich zum Tag noch 2 Zufallszahlen. Mit der ersten multiplizierst du den Tag und mit der 2ten die ID. Wobei das ja schon irgendwie wieder etwas lächerlich wird, IMHO Lass die Download doch nur zu, wenn eine Session existiert, der User also von deiner Seite kommt. (Dazu muss der User allerdings Cookies akzeptieren, oder du übergibst die SessionID per GET...dann kommt aber wieder das Bookmarken ins Spiel ) Ach ja, neben dem Tag könntest du auch die Unixzeit verwenden (getdate()[0]), das ist schon weniger offensichtlich als der Tag. Ausserdem musst du darauf achten, dass die IDs in der DB dann so gelegt sind, dass nicht durch Zufall mal eine Falsch bei der Berechnung rauskommt (das meinte ich auch mit ÜBerarbeiten von der Idee). Zitieren
cane Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Der Referer ist schön und gut, aber der muss nicht übergeben werden! Eine Seite zu machen, die den Referer vorraussetzt ist viel schlimmer als eine Seite, die Javascript vorraussetzt. Da stimme ich dir zu - ich finde übrigens beides schlimm. Denn bei JS ist keine Barrierefreiheit gegeben. Ich blocke sowohl Referrer als auch .js und Cokkies am Proxy (Squid mit privoxy als Contentfilter) und die vermurksten Seiten die ohne .js gar nicht gehen sind immer wieder ein Ärgernis... mfg cane Zitieren
Crash2001 Geschrieben 11. Januar 2006 Autor Geschrieben 11. Januar 2006 Das nennt sich Referer und läßt sich so auslesen:[...]Aha - alsso geht das mittels PHP auch schon mal. Der Referer ist schön und gut, aber der muss nicht übergeben werden! Eine Seite zu machen, die den Referer vorraussetzt ist viel schlimmer als eine Seite, die Javascript vorraussetzt.Also müsste man den manuell übergeben, oder wird der standardmässig übergeben und man kann ihn unterdrücken? :confused: Das mit dem numerischen Tag war ja nur eine erste Idee, ich meinte ja, das muss noch überarbeitet werden, vielleicht ja mit etwas weniger "offensichtlichem".[...]Was eine Zufallszahl ja wäre. Lass die Download doch nur zu, wenn eine Session existiert, der User also von deiner Seite kommt. (Dazu muss der User allerdings Cookies akzeptieren, oder du übergibst die SessionID per GET...dann kommt aber wieder das Bookmarken ins Spiel )Hmmm... das mit der Session-ID klingt ganz okay, aber wenn dafür Cookies aktiviert sein müssen, scheidet es leider aus. Wieso per GET, wenn ich die genausogut auch per POST übergeben kann? :confused: [...]Ausserdem musst du darauf achten, dass die IDs in der DB dann so gelegt sind, dass nicht durch Zufall mal eine Falsch bei der Berechnung rauskommt (das meinte ich auch mit ÜBerarbeiten von der Idee).Wie, dass nicht durch Zufall mal eine Falsch bei der Berechnung rauskommt? Du meinst, dass quasi eine andere Datei dann benutzt wird oder was? :confused: Also das mit dem htaccess probier ich heute abend mal aus. Hab auf meinem Webspace nur das Verzeichnis direkt (also quasi das document_root für meine Domain). Hab ich ja schon ganz oben angesprochen... aber ich hab letztens etwas ähnliches gemacht, aber nciht mit PHP oder Javascript, sondern mit htaccess und mod_rewrite (falls dir das zur Verfügung steht): #.htaccess RewriteEngine On RewriteCond %{REQUEST_URI} .*\.(gif|jpg|jpeg|png) [NC] RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://(.*)www\.meineDomain\.de/.*$ [NC] RewriteRule (.*) /forbidden.php [L,NS] Bei der Seite geht es um eine Art Gallerie. Was ich damit erreichen wollte war, dass ich feststellen kann, wenn ein Bild aus der Gallerie von einem anderen Webspace verlinkt ist. Dazu die RewriteCond. Erstmal nur bei Bildern (gif, jpg, jpeg, png), dann wenn der Referer nicht leer ist und wenn er nicht meine Domain enthält. Falls alle Regeln zutreffen, wird die Anfrage weitergeleitet (in deinem Fall z.B. zur Seite forbidden.php). Bei mir wird auf eine andere PHP-Seite umgeleitet, der versch. Parameter mitgegeben werden und die dann in einer DB den Zugriff von einem fremden Server logt (mit Referer und welche Datei etc.) Nach dem Eintrag in die DB wird das angeforderte Bild ausgegeben (ähnlich dem Code den ich oben geschrieben hab) und der Besucher merkt von all dem nichts.Klingt soweit okay. Ich schau es mir mal heute abend an bzw. frag mal nach, ob mod_rewrite aktiviert ist. Nur würde ich dann bei deinem Beispiel doch das angeforderte Bild durch ein anderes ersetzen. Zitieren
Crash2001 Geschrieben 11. Januar 2006 Autor Geschrieben 11. Januar 2006 Was ist denn eigentlich so schlimmes daran, wenn man einen Referer voraussetzt? :confused: Zitieren
cane Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Das es niemanden angeht auf welcher Präsenz ich mich vorher bewegt habe. Dient einerseits der Verhinderung von Deeplinks, andererseits werden aber auch Userprofile erstellt. mfg cane Zitieren
Crash2001 Geschrieben 11. Januar 2006 Autor Geschrieben 11. Januar 2006 Nun ja, wenn man von einer externen Seite kommt, verstehe ich das ja. Aber intern ist es doch eigentlich ziemlich egal, ob die mitgeteilt wird, oder nicht. Oder was würde dagegen sprechen? Wird ein Referer denn standardmässig gesetzt, oder muss er explizit mit übergeben werden von einer Seite? Zitieren
geloescht_JesterDay Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Was ist denn eigentlich so schlimmes daran, wenn man einen Referer voraussetzt? :confused: Es hat nix damit zu tun, dass es niemanden angeht, übertragen wird er (u.U.) eh... also das ist es ja nicht. Aber: Der Referer wird eben nicht immer übertragen. Entweder man stellt es im Browser aus oder eine PFW (o.ä.) entfernt den Referer u.U. aus dem Header, ausserdem ist es auch ein leichtes den zu faken (was aber nicht gegen die Vorraussetzung des Referers spricht). Wie gesagt, du kannst den Referer nicht erwarten, da er abgeschalten werden kann (wie Javascript ja auch), aber vorallem deswegen, weil er von manchen "Sicherheitstools" entfertn werden kann ohne dass der Nutzer etwas davon weiß (gut, manche wissen das schon) oder etwas daran ändern kann! (auch hier, nicht alle...) Zitieren
Crash2001 Geschrieben 11. Januar 2006 Autor Geschrieben 11. Januar 2006 Achso. also kann man sich nicht drauf verlassen, dass ein Referer gesetzt ist und daher auch nicht sinnvoll damit arbeiten, da er entfernbar ist. Zitieren
cane Geschrieben 11. Januar 2006 Geschrieben 11. Januar 2006 Ja - so sehe ich das auch. Viele Contentfilter entfernen Referer bereits in der Standardconfig... mfg cane Zitieren
geloescht_JesterDay Geschrieben 12. Januar 2006 Geschrieben 12. Januar 2006 Klingt soweit okay. Ich schau es mir mal heute abend an bzw. frag mal nach, ob mod_rewrite aktiviert ist. Nur würde ich dann bei deinem Beispiel doch das angeforderte Bild durch ein anderes ersetzen. Nein, es geht mir ja nicht darum , die fremden aufrufe zu verhindern. Das wäre ja damit das kleinere Problem gewesen (Das mit dem loggen in der DB und dennoch das richtige bild ausgeben war ja doch was komplizierter ) Es ging mir einfach nur darum zu sehen wann wer welches Bild aufruft und von wo er kommt. Es handelt sich dabei um selbstgemalte bilder einer Bekannten und sie wollte das nicht verhindern (sie freute sich sogar, dass die Bilder bei Google-Images zu finden sind). Nachdem ich aber in der Log-Datei gesehen habe, dass wohl andere Seiten auf Bilder verlinken und in der Log-Datei nur die Top10 o.ä. zu sehen ist (bzw. mit dem Analyse-Tool für das Log), wollte ich das einfach etwas genauer haben *g* (Die Bilder sind mit einem Vermerk versehen und solange es nur ein Link ist (z.B. auf "Bilder die mir am besten gefallen") spricht ja nix dagegen) Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.