Zum Inhalt springen

URL einer zu downloadenden Datei unkenntlich machen


Empfohlene Beiträge

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Der 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. :rolleyes: [/size][/b]

[/NACHTRAG]

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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).

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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. :rolleyes:

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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...)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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. :rolleyes:

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)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...