mit PHP die .htaccess öffnen???
Fabienne
- php
Ich habe ein "Mini-Portal", bei dem sich User im php-Formular einloggen können. Die User sind in einem Array gespeichert (also kein SQL o.ä.).
Nun gibt es aber das Problem, dass USer von außen dennoch die Bilder, pdf's usw. abrufen können, da ja nur dir *.php-Dateien geschützt sind. Wenn ich eine .htaccess mit user und Passwort aufschalte wäre natürlich alles geschützt (mehr oder weniger sicher == egal), aber die User müßten sich dann 2x anmelden.
Gibt es also eine Möglichkeit in php die in php für OK bewerteten User+Passworte an die htaccess weiterzureichen und dem aktuellen Client den Zugriff auf die Verzeichnisstruktur zu gewähren?????
Oder gibt es in php die Möglichkeit (ähnlich der htaccess) ganze Verzeichnisse und deren Unterstrukturen zu schützen???
DANKE!!
Hallo,
Oder gibt es in php die Möglichkeit (ähnlich der htaccess) ganze Verzeichnisse und deren Unterstrukturen zu schützen???
Ja. Das Prinzip:
Die gegen aussen "sichtbare URL" stimmt nicht ueberein mit
dem Dateisystem auf dem Server, und die Dateien liegen
in einem Verzeichnis, das nicht via HTTP zugaenglich ist.
Sichtbare URL:
http://www.example.com/privat/bilder/foto1.jpg
Aufgerufen wird aber (unsichtbar):
http://www.example.com/privat.php?pfad=bilder/foto1.jpg
Wenn der Benutzer berechtigt ist (Session/Cookie oder so),
und wenn der Pfad in Ordnung ist (Sicherheits-Pruefungen
unbedingt notwendig!), dann schickt das PHP-Skript
die HTTP-Header (hier: image/jpeg) und danach den Inhalt
der Datei, z.B. mit fpassthru() oder readfile().
Bei nicht berechtigten Usern gibt's eine Fehlermeldung
oder eine Umleitung auf die Login-Seite.
Stichworte:
* search engine friendly URLs
* Apache mod_rewrite
* PHP readfile, fpassthru
* Sessions
Gruesse,
Thomas
Hello,
die Beschränkungen über .htaccess und .htpasswd (oder wie man sie sleber nennt) gelten i.d.R. nur für den direkten Zugriff über HTTP auf das Verzeichnis. Wenn nun aber das PHP-Script zugreift (also das Runtimesystem von PHP) dann gelten nur die "normalen" Beschränkungen des Betriebssystems, also rwx ...
Der Deamon (PHP-Runtime) wird dabei wie ein normaler User behandelt und wickelt mit SEINEN Rechten den Auftrag ab.
Wenn man im Script also nicht dafür sorgt, dass nur autorisierte User zugreifen können, ist das eine schöne Lücke.
Grüße
Tom
Wie funzt das mit dem header()?? Ich habe das so ähnlich schon mal versucht, hat aber nicht geklappt.
Wie wäre es, den User via header("LOCATION: username:passwort@test.php") auf die Seite Test zu schicken, die Seite test.php leitet sofort weiter an header("LOCATION: seite.php"). Dann dürfte der User eigenlich den Username und das Passwort gar nicht zu sehen bekommen... Problem: Es funzt nicht, da der Client in diesem Fall der Server war...
Kann mir jemand die Möglichkeit mit dem Bilder via header senden näher erläutern? Evtl. auch nen Beispiel-Code??
Wäre sehr verbunden. Vielen Dank.
Hallo,
Wie funzt das mit dem header()??
RTFM:
http://www.php.net/manual/de/function.header.php
Ich habe das so ähnlich schon mal versucht, hat aber nicht geklappt.
Vermutlich hattest Du _vor_ dem Header schon etwas an den
Browser geschickt, und sei es nur ein Leerzeichen oder Zeilenumbruch.
http://www.dclp-faq.de/q/q-fehler-header.html
Wie wäre es, den User via header("LOCATION: username:passwort@test.php") auf die Seite Test zu schicken, die Seite test.php leitet sofort weiter an header("LOCATION: seite.php"). Dann dürfte der User eigenlich den Username und das Passwort gar nicht zu sehen bekommen...
Das ist Unfug.
Und es enthaelt einen groben Fehler: Die URL muss absolut und vollstaendig sein,
also mit "http://" beginnen:
header('Location: http://www.example.com/seite.php');
Anders als bei FTP ist es bei HTTP soviel ich weiss nicht vorgesehen,
den Benutzernamen und das Kennwort in die URL reinzupacken.
(Ich weiss, dass es in den meisten Browsern trotzdem funktioniert.)
Es ist auch sehr fahrlaessig, denn die Adresse bleibt an diversen
Orten haengen, z.B. im Cache, in der History, im Adresszeilen-Gedaechtnis
des Browsers, in Proxy-Servern u.s.w.
Wenn die Sicherheit sehr wichtig ist, sollte man sowieso nicht HTTP,
sondern HTTPS (SSL) verwenden.
Auch bei GET- und POST-Anfragen wird das Passwort unverschluesselt
uebermittelt.
Bei GET ist es genauso unsicher, wie mit der obigen "@" Methode, weil
das Passwort sichtbar ist.
Befasse Dich intensiver mit Sicherheit im allgemeinen und Passwortschutz-
Loesungen in PHP sowie Sessions im speziellen.
_Einigermassen_ sicher waere es z.B., wenn sich der Benutzer
ueber ein POST-Formular einlogt, dann eine Session-ID kriegt,
und fuer alle folgenden Anfragen die Session-ID uebergeben wird.
Die Session-ID wird ueblicherweise in einem Cookie gespeichert,
wenn das nicht moeglich ist, wird sie an alle URLs drangehaengt.
Sobald der Benutzer sich "abmeldet", oder nach einer vorbestimmten
Zeit der Inaktivitaet, wird die Session geloescht, und auch jemand,
der zufaellig an die Session-ID kommt, kann nichts mehr damit anfangen,
weil sie nicht mehr gueltig ist.
Problem: Es funzt nicht, da der Client in diesem Fall der Server war...
Das sollte keine Rolle spielen.
Kann mir jemand die Möglichkeit mit dem Bilder via header senden näher erläutern? Evtl. auch nen Beispiel-Code??
<?php
$verlangt=intval($_GET['nr']);
unset($bild); // Zur Sicherheit, falls register_globals on ist...
unset($pfadzumbild); // dito
$bild[0]="pfad/zum/null.gif"; // Transparentes 1x1 Pixel GIF
$bild[1]="pfad/zu/bild1.jpg";
$bild[2]="pfad/zu/bild2.gif";
if (isset($bild[$verlangt])) // d.h. wenn ein zulaessiges Bild verlangt wird
{ $pfadzumbild=$bild[$verlangt]; }
else
{ $pfadzumbild=$bild[0]; } // Transparentes GIF ausgeben
$bildinfos=getimagesize($pfadzumbild);
$bildtypnr=$bildinfos[2];
$contenttype[1]='image/gif';
$contenttype[2]='image/jpeg';
$contenttype[3]='image/png';
header("Content-Type: $contenttype[$bildtypnr]");
readfile($pfadzumbild);
?>
Kannst Du hier ausprobieren:
http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=1
http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=2
http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=99
PHP-Manual-Kapitel zu den verwendeten Funktionen getimagesize() und readfile():
http://www.php.net/manual/en/function.getimagesize.php englisch, aktuell
http://www.php.net/manual/de/function.getimagesize.php deutsch, unvollstaendig
http://ch.php.net/manual/en/function.readfile.php englisch, aktuell
http://ch.php.net/manual/de/function.readfile.php deutsch
Testen, welchen HTTP-Header der Server schickt, kannst Du z.B. mit:
http://cgi.w3.org/cgi-bin/headers
Gruesse,
Thomas
Hab den Code so übernommen, allerdings meine Bilder in einen nicht öffentlichen webordner gestellt. Rauskommen tut nur ein riesen Buchstaben-Zahlensalat...
Was mach ich falsch?? Muss ich zuerst noch ne html-Seite generieren, in dem ein img-Tag steht??
Hallo,
Hab den Code so übernommen,
Wirklich so, 1:1?
Ohne etwas vorher oder nachher auszugeben?
Er muss ganz genau mit der spitzen Klammer von
<?php
oder
<script language="php">
anfangen und mit der spitzen Klammer von
?>
oder
</script>
aufhoeren.
Ausser den beiden Zeilen:
header("Content-Type: $contenttype[$bildtypnr]");
readfile($pfadzumbild);
(und ggf. weiteren Headern) darf _nichts_ an den Browser
geschickt werden.
allerdings meine Bilder in einen nicht öffentlichen webordner gestellt.
Sollte keine Rolle spielen, weil PHP ja ueber's Dateisystem
auf die Datei zugreift und nicht via HTTP.
Rauskommen tut nur ein riesen Buchstaben-Zahlensalat...
Also gibt PHP offenbar etwas aus ;-)
Das ist schonmal gut.
Welcher Browser? Welches Betriebssystem?
Wie faengt der Buchstabensalat an?
Was siehst Du bei meinen Beispielen?
http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=1
http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=2
Was sagt der HTTP Head Service bei Dir?
http://cgi.w3.org/cgi-bin/headers
Wie hast Du die Pfade zu den Bildern angegeben?
Muss ich zuerst noch ne html-Seite generieren, in dem ein img-Tag steht??
Nein. Siehe meine Beispiele.
Die funktionieren bei mir problemlos in Mozilla 1.2.1 und Konqueror 3.1.1 (SuSE Linux).
Gruesse,
Thomas
Dieses Problem habe ich ja schon gelöst... Hatte HTML-Code vor dem header ausgegeben... Anfänger-Fehler...
Aber wie kann ich jetzt in einem html-Dokument diese Bilder verwenden??
Die Bilder auf deinen Versuchsseiten sehe ich, allerdings nur Bilder, kein HTML.
Oh ja, ich habe meinen Fehler entdeckt:
Habe vor dem header schon html ausgegeben.
Wie kann ich dann diese Bilder via Bildschleuse in bestehenden html-Code implementieren??
Hallo,
Oh ja, ich habe meinen Fehler entdeckt:
Habe vor dem header schon html ausgegeben.
Aber, aber!
In weiser Voraussicht hatte ich Dir doch bereits den Link zu
http://www.dclp-faq.de/q/q-fehler-header.html
gepostet.
Das Bild-Durchschleuser-Skript darf _gar_kein_ HTML ausgeben.
Auch nicht im Fehlerfall.
Weil seine Ausgabe ja ein Bild sein soll.
Wie kann ich dann diese Bilder via Bildschleuse in bestehenden html-Code implementieren??
Wie ein normales Bild.
<img src="http://www.tiptom.ch/tests/phpssi/bildschleuse.php?nr=1" alt="Foto einer Uhr" width="207" height="300">
Das ganze Gebastel dient ja dem Passwortschutz.
Wie gesagt, wuerde ich das mit Sessions loesen.
Im Fall, dass der Browser kein Cookie akzeptiert, wird die Session-ID
einfach an die URL des Bild-Durchschleuser-Skripts angehaengt.
<img src="bildschleuse.php?nr=1&PHPSESSID=xyz123abc978" alt="...">
Beachte:
Noch etwas Lektuere fuer den Feieraben:
http://www.dclp-faq.de/ch/ch-security.html
http://www.dclp-faq.de/ch/ch-version4_session.html
http://www.php.net/manual/en/ref.session.php
Gruesse,
Thomas
VIELEN DANK!!!!!!!
P.S. Ich arbeite bereits mit session, da ich ne Benutzerabfrage drin habe, dann in einer globalen Variable $globale_variable den Nutzer usw. abspeicher und den dann (ohne Cookie) via URL von Seite zu Seite weiterreiche. Kann ich da eigentlich auch ne Verfallszeit wie bei einem Cookie einstellen, dass der USer maximal z.B. eine Stunde lang online sein kann und alle späteren Versuche abgewehrt werden, oder ist das größerer Programmieraufwand?
Nochmals Danke für die "Bildschleuse".
Noch was: Die Seite muss nicht 1000% sicher sein, sondern nur 100%ig.
Also ist die session-Geschichte als Sicherheitslücke OK, aber ne Verfallszeit wäre ganz gut.
Hallo,
VIELEN DANK!!!!!!!
Gerngeschehen.
Ich habe dieses "Durchschleusen" als Prinzip schon ein paarmal
empfohlen, aber um ehrlich zu sein, habe ich es heute zum ersten
Mal selbst ganz konkret ausprobiert...
War erfreut, zu sehen, dass es funktioniert. ;-)
Ich arbeite bereits mit session, da ich ne Benutzerabfrage drin habe, dann in einer globalen Variable $globale_variable den Nutzer usw. abspeicher und den dann (ohne Cookie) via URL von Seite zu Seite weiterreiche.
Dann hast Du dass Prinzip der Sessions noch nicht restlos begriffen.
Der Witz an den Sessions ist gerade, dass Du _nur_ die Session-ID
von Seite zu Seite weitergibst (mit Cookies ist nichtmal das notwendig).
Alle anderen Variablen (Benutzername, Passwort, weitere persoenliche
Daten, Voreinstellungen, was auch immer) bleiben auf der "sicheren Seite",
naemlich auf dem Server, gespeichert, wo nur _Du_ (d.h. Dein Skript)
darauf Schreib- und Lesezugriff haben.
Lies mal:
http://www.dclp-faq.de/q/q-sicherheit-parameter.html
Also ist die session-Geschichte als Sicherheitslücke OK, aber ne Verfallszeit wäre ganz gut.
So, wie Du es machst, ist es eine Sicherheitsluecke.
Das "Restrisiko" besteht in der Uebernahme einer Session
durch eine unberechtigte Drittperson.
Bei Cookies ist das _relativ_ unwahrscheinlich
(d.h. jemand muesste den Datenverkehr abhoeren),
bei GET (Anhaengen an die URL) schon wahrscheinlicher
(beides kann zum Problem werden bei Computern in Web-Cafes,
Universitaeten und anderen gemeinsam genutzten Computern).
Wenn die Benutzer sich diszipliniert ausloggen, und man
anschliessend die Session loescht, vermindert das
dieses Risiko.
Die Verfallszeit ist in der PHP-Konfiguration geregelt:
http://www.php.net/manual/en/ref.session.php
und zwar mit den Einstellungen session.gc_maxlifetime
und session.cookie_lifetime.
Diese sind in der php.ini vordefiniert, aber Du kannst
sie auch zur Laufzeit aendern mit ini_set():
http://www.php.net/manual/en/function.ini-set.php
Gruesse,
Thomas
P.S. habe nun mal endlich das Subject etwas angepasst...