rochs: Upload --- Datei benennen

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

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

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. 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.

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

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. 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!

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

            --
            Dieser Satz wurde in mühsamer Kleinstarbeit aus einzelnen Wörtern zusammengesetzt.
              (Hopsel)
  2. 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 Server muss einen Upload überhaupt annehmen
    • die Zeitdauer für den Upload überschreitet nicht die eingestellte
    • die Datenmenge überschreitet nicht die eingestellte

    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.

    Abhilfe:

    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

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau