Upload --- Datei benennen
rochs
- php
Hallo,
habe bereits einen funktionierenden Upload in PHP.
1.
Wie kann ich den Datei-Namen in die MySQL Datenbank geben?
Es erstellt mir zwar den Eintrag jedoch ist es irgend ein Pfad - ich möchte nur den Datei-Namen eintragen.
Der eben erwähnte Pfad sieht momentan so aus:
/home/www/web349/phptmp/phpQ5tdFc
2.
Welchen Eintrag brauche ich um die Datei nachher im Browser als Link aufzulisten?
Ich lege alle Files im selben Ordner ab.
Danke für Deine Hilfe
rochs
hi,
Wie kann ich den Datei-Namen in die MySQL Datenbank geben?
Es erstellt mir zwar den Eintrag jedoch ist es irgend ein Pfad - ich möchte nur den Datei-Namen eintragen.
Der eben erwähnte Pfad sieht momentan so aus:/home/www/web349/phptmp/phpQ5tdFc
phptmp lässt darauf schliessen, dass dies lediglich dein temporäres Verzeichnis für Dateiupload ist.
Aus diesem heraus musst du die Datei erst mal an einen anderen Ort sichern (move_uploaded_file) - aus dem temp-Verzeichnis wird sie nämlich nach Beendigung des Scriptes wieder gelöscht.
Den Namen vergibst du dabei selber.
Welchen Eintrag brauche ich um die Datei nachher im Browser als Link aufzulisten?
Dass du einen Link brauchst, dürfte uns beiden klar sein.
Was du mit dieser Frage jetzt genau meinst, allerdings allerhöchstens dir. Also beschreibe bitte genauer, was du eigentlich wissen willst.
gruß,
wahsaga
phptmp lässt darauf schliessen, dass dies lediglich dein temporäres Verzeichnis für Dateiupload ist.
Es macht aber gleichzeitig mit INSERT INTO einen Eintrag in die DB.
und der Eintrag 'file' sollte nun der Dateiname und nicht dieser tmp-pfad sein.
Die Variable $Datei beinhaltet diesen tmp-Pfad - welche Variable beinhaltet den original-Datei-namen?
//Eintrag in DB
$query = "INSERT INTO files (file, user)
VALUES('$Datei', '$user')";
// ordner
ftp_chdir($conn_id, "html/pwpw/files");
// Upload der Datei
$upload = ftp_put($conn_id, $_FILES['Datei']['name'], $_FILES['Datei']['tmp_name'], FTP_BINARY);
Was du mit dieser Frage jetzt genau meinst, allerdings
NICHT MAL MIR...
War ne blöde Frage, sorry... Ich muss den Link ja erst auf der Anzeige-Seite selbst machen - kannst also wieder vergessen, danke.
hi,
Es macht aber gleichzeitig mit INSERT INTO einen Eintrag in die DB.
und der Eintrag 'file' sollte nun der Dateiname und nicht dieser tmp-pfad sein.
Die Variable $Datei beinhaltet diesen tmp-Pfad - welche Variable beinhaltet den original-Datei-namen?
Irgendeine "Original-Dateiname" ist uninteressant - dass du den überhaupt bekommst, ist nicht mal unbedingt gegegeben.
Von Interesse ist der Name, unter dem du die hochgeladene Datei permanent sicherst.
Welcher das ist, kann ich dir nicht sagen - schau in dein Script.
// Upload der Datei
$upload = ftp_put($conn_id, $_FILES['Datei']['name'], $_FILES['Datei']['tmp_name'], FTP_BINARY);
Wozu hier überhaupt FTP?
Reden wir etwa _nicht_ von einem HTTP-Datei-Upload über ein HTML-Formular? Falls nein, sag das bitte dazu.
Falls doch - dann ist FTP eigentlich unsinnig, es sei denn, es gibt bestimmte Gründe für die Nutzung im konkreten Fall - dann beschreib auch das bitte.
gruß,
wahsaga
Hi,
Von Interesse ist der Name, unter dem du die hochgeladene Datei permanent sicherst.
Diesen möchte ich ja bestimmen - er sollte der Dateiname sein.
Wozu hier überhaupt FTP?
Weil ich es leider nicht besser weiss...
Mein Projekt:
Ich bin mitten in meiner Lehrabschlussprüfung (leider schon bald am Ende, darum der Zeitdruck).
In meinem Fall ist das eine Neugestaltung eines Internet-Auftritts.
Neu kommt ein PW-Bereich dazu.
In diesem PW-Bereich gibt es einen Upload.
Jeder Benutzer soll nur seine Dateien lesen können (darum gebe ich noch den Benutzernamen in die DB).
Diese Downloads sollen später so aussehen:
Dateien von $user:
Dokument1.doc
Dokument2.doc
Dokument3.doc
Der Name ist gleichzeitig ein Link auf die Datei.
Dieser Name (Dokument1.doc) muss ich doch in die DB eintragen?
Bin ich auf dem falschen Weg?
Danke wahsaga!
Hallo,
Diesen möchte ich ja bestimmen - er sollte der Dateiname sein.
ja, das ist nachvollziehbar. Aber du hast nach dem File-Upload zwei Dinge, die durchaus unterschiedlich sein können:
Zum einen den Original-Dateinamen (üblicherweise ohne Client-Pfad, es wurde aber schon vereinzelt berichtet, dass manche Browser den kompletten Pfad mit übermitteln). Den findest du im superglobalen Array $_FILES[].
Zum anderen den Namen der hochgeladenen Datei im temp-Verzeichnis auf dem Server. Der _kann_ dem Originalnamen entsprechen, muss es aber nicht.
Wozu hier überhaupt FTP?
Weil ich es leider nicht besser weiss...
Aha. Aber wenn dein PHP-Script anläuft, hast du doch die Datei schon auf dem Server (eben im temp-Verzeichnis). Was also willst du mit FTP anstellen? Das einzig wichtige, was du dann noch brauchst, ist move_uploaded_file(). Das hat wahsaga dir aber auch schon verraten.
Bin ich auf dem falschen Weg?
Mit FTP vermutlich schon ...
So long,
Martin
Hello,
habe bereits einen funktionierenden Upload in PHP.
aus dem weiteren Thread habe ich entnommen, dass Du eventuell gar nicht weißt, warum das Upload-Script funktioniert. Dann könnte es auch sein, dass Du gar nicht weißt, welche garviernden Sicherheitslücken es haben könnte oder sogar hat.
Deshalb nochmals ein paar Regeln zum Upload:
--------------------------------------------
Der User kann alles auf den Server hochladen, was ihm gefällt. Die einzigen Einschränkungen dabei sind:
Der Client kann also auch *.EXE-Files, *.PHP-Files, ausführbare Scripte und Programme für Linux usw. hochladen. Gerade, wenn Du diese dann später direkt mit einem Link versiehst, ist die Lücke aufgerissen. man muss oft nur ein PHP-Script hochladen und es mit dem Browser aufrufen. Schon istr es passiert.
Upload überwachen
-----------------
Nach dem Upload als erstes die Variable
$_FILES[$steuerelementname]['error'] === 0
prüfen. Nur wenn die identisch 0 ist, wurde der Upload technisch einwandfrei mit _einem_ File durchgeführt.
Sie kann aber auch ein Array sein, dann muss eben
$_FILES[$steuerelementname]['error'][0] === 0
$_FILES[$steuerelementname]['error'][1] === 0
$_FILES[$steuerelementname]['error'][2] === 0
...
sein, damit alle Files technisch einwandfrei angekommen sind.
Files untersuchen
-----------------
Dann sollte man als nächstes auf dem Server prüfen, welchen Typ die Dateien haben.
Dazu darf man _N_I_C_H_T_ der Angabe in
$_FILES[$steuerelementname]['type'] ## ist nicht vertrauenswürdig !
trauen. Sie ist vom Client eingetragen worden und daher nicht vertrauenswürdig.
Wenn man z.B. nur Bilder zulassen will, hilft
getimagesize()
http://www.php.net/manual/en/function.getimagesize.php
Wenn man nur Textdateien[1] zulassen will, aber ausführbare Programme, Bilder, etc verhindern will,
hilft eine Untersuchung der Datei auf
if(strpos($dateiinhalt,chr(0)) !== false ## Diese Datei ist keine reguläre Textdatei
Meistens reichen schon die ersten 256 Bytes einer Datei, um eine 0 (binär 00000000) zu finden.
Wenn also eine 0 enthalten ist, kann die Datei keine reguläre Textdatei sein!
Das gilt aber keinesfalls sicher anders herum.
Dann gibt es noch die Funktion
mime_content_type() [http://www.php.net/manual/en/function.mime-content-type.php]
die aber nicht in allen PHP-Versionen vorhanden war und auch inzwischen abgekündigt wurde.
Ohne die PECL extension und Fileinfo
http://www.php.net/manual/en/ref.fileinfo.php
wird man also nicht auskommen, wenn man etwas anderes als Bilder zulassen will.
Namen frei vergeben
-------------------
Eine weitere Möglichkeit für "Injections" ist der Name des hochgeladenen Files.
In
$_FILES[$steuerelementname]['name']
steht i.d.R. der vom Client mitgeteilte Name des Files. Er kann aber auch leer sein oder aber,
was viel schlimmer ist, einen ganzen Pfad enthalten. Deshalb darf man ihn
NIE NICHT NIMMER direkt verwenden!
Vertrauenswürdig ist hingegen der Name $_FILES[$steuerelementname]['tmp_name'], da dieser
vom Server generiert wird. Aber auch jeder andere Name, den man sich erzeugt, ist besser
als der vom Client übermittelte.
Wenn man sich aber trotzdem merken will, was der Client als Dateinamen vorgeschlagen hat,
sollte man ihn mittels
$_merkname = basename($_FILES[$steuerelementname]['name']);
auf seinen Namensanteil reduzieren lassen. Was interessiert uns auch der Pfad auf dem Client?
Bei der Erfindung eines Namens für das permanent gespeicherte File muss man natürlich darauf
achten, dass dieser nicht schon vorhanden ist im Ablageverzeichnis.
Auch dies ist ein Grund dafür, dass man den vom Client gemeldeten Namen meistens nicht
verwenden kann, denn wenn mehrere User Files ins selbe Verzeichnis hochladen können, wissen
die i.d.R. ja nicht, welche Namen die anderen schon benutzt haben.
Verzeichnis "kastrieren"
------------------------
Bei üblichen PHP-Einrichtungen bei Hostern werden Script-Dateien (zumindest PHP) in allen
verfügbaren Verzeichnissen unter der DOCUMENT_ROOT auch durch den zugehörigen Parser geschickt;
eine passende Endung ist meistens die einzige Voraussetzung dafür.
In Verzeichnissen, in denen Bilder gespeichert werden sollen oder Textdateien, die vom Client
über HTTP abgefordert werden können (HTML ist auch Text), sollte man daher keine PHP-Dateien
speichern und zulassen. Dem Server sollte man mitteilen, dass Dateien in diesem Verzeichnis
NICHT geparst werden dürfen. Das kann man oft mittels einer ".htaccess-Datei" tun
<FilesMatch ".(php|phtml|html)$">
forceType text/html
</FilesMatch>
Das ist bitte nur als Beipiel zu sehen, wo es langgehen kann.
Wahrscheinlich ist es besser, man baut die Bedingungen und die regulären Ausdrücke so auf,
dass nur "die guten Files" überhaupt entsprechend ihrer Bestimmung ausgeliefert werden und
alle anderen zur Auslieferung einer Fehlerseite führen.
Jedenfalls zeigen diese Anregungen hoffentlich, dass man nicht aufhören darf, wenn es
"so eben funzt"
sondern sich weitaus mehr Gedanken machen muss. AUCH ALS PROVIDER!
http://www.php.net/manual/en/features.file-upload.php
http://httpd.apache.org/docs/2.0/mod/directives.html
Über eine Ergänzung des Threads würde ich mich freuen.
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom