java: verhindern das excel-files upgeloadet werden

hallo,

ich habe folgendes problem, in einem projekt sollen .csv dateien in eine mysql datenbank geschrieben werden. jedoch kommt es immerwieder vor das user excel dateien uploaden (sind halt nur anwender). jetzt möchte ich erkennen lassen ob es sich nicht um eine excel datei handelt. bis jetzt habe ich das volgendermaßen versucht zu lösen.

if(!empty($csvdatei_name)){ //wenn keine excel datei ansonsten ...
$oder1 = $csvdatei_type;  // erstes problem x-msexcel oder msexcel
$oder2 = $csvdatei_type;  // ...

if($oder1=="application/x-msexcel" || $oder2=="application/msexcel")
{
die("Diese Datei ist ein MS-Excel Dokument! Informationen zum dateiupload von .csv Dateien finden sie $infos ".$csvdatei_type);
}

else{
echo ($csvdatei_type);
if(@copy($csvdatei,"$csvdatei_name"))
{
echo "<br><b>Upload beendet!</b><br>";
echo "Dateiname: $csvdatei_name";
}
}
}
else{....

ABER

es kommen immernoch excel files an. die dateien werden in einem weiteren script umbenannt (datum, user ...), also kann ich nicht sagen ob sie endung .xls hatten und das angegebene script nicht funktioniert, oder ob der user einfach die dateiendung geaendert hat.

KANN mir jemand einen tip geben wie excel dateien auf anderem wege auschliessen kann?

java

  1. Hallo,

    ich [erkenne Dateien nach MIME-Typ].
    KANN mir jemand einen tip geben wie excel dateien auf anderem wege auschliessen kann?

    Analysiere den Inhalt. Das wird schwierig, weil .xls ein geschlossenes Format ist und sich sowieso alle Naselang geändert hat - Details kannst du evtl. vom Koffice-Team abgrasen, wenn du nicht selber Reverseengineering machen kannst/willst.

    Wenn eine grobe unpräzise Erkennung auch reicht, mache den Unterschied fest, indem du Dateien mit hohem Anteil an Nicht-Textzeichen zurückweist. Kommaseparierte Listen sind fast vollständig Text, .xls ist fast vollständig binäres Kauderwelsch.

  2. Hi,

    warum prüfst du nicht direkt im browser die endung des files ab, mit javascript. Natürlich kann man die Datei vorher umbenennen, aber falls das nur aus unwissenheit den benutzern passiert reicht doch so eine abfrage aus. z.B. so oder so ähnlich:

    -head--
    function checkFileName(){
      if( document.sendung.file.value.indexOf(".csv")==-1){
         alert("Bitte senden Sie nur Dateien mit der Endung CSV");
         return false;
      }
      return true;
    }

    -form--
    <form name="sendung" action.... onsubmit="return checkFileName()">

  3. Moin!

    KANN mir jemand einen tip geben wie excel dateien auf anderem wege auschliessen kann?

    Du mußt einfach in der hochgeladenen Datei nachsehen, ob sie als Format den Anforderungen der Datenbank genügt. Das bedeutet: Lies die Datei in PHP ein, und schau, ob nur ordentliche Buchstaben, Zahlen und Sonderzeichen vorkommen, und vor allem: Kommas (oder was auch sonst als Trennzeichen verwendet wird).

    Die Prüfung, ob der Browser den richtigen Mime-Typ mitgeschickt hat, ist zum Scheitern verurteilt: Diese Angabe kommt vom Browser, der aber Excel- oder CSV-Dateien genauso gut unterscheiden kann wie ein Blinder - und PHP übernimmt einfach nur diese Angabe. Wenn also der Browser sich irrt, und du auf den Browser vertraust, irrst du auch.

    Generell würde ich das Hochladen und Einfügen von CSV-Dateien in eine Datenbank als äußerst kritisch sehen. Es mag funktionieren, aber es bietet reichlich Angriffsfläche. Wenn du nicht, wie oben vorgeschlagen, die CSV-Datei probeweise einliest und auf Kompatibilität mit der Datenbank prüfst, indem du z.B. die Anzahl der Felder pro Zeile nachzählst, und möglicherweise auch die Datentypen testest, dann handelst du dir über kurz oder lang Ärger ein. Das Beispiel mit den falschen Excel-Dateien ist nur der Anfang.

    - Sven Rautenberg

    1. hallo,

      danke fuer deine infos. den ansatz habe ich schon versucht, als ich annahm der dateiheader koennte ja gleich sein, aber war er nicht.

      also mit fgetcsv('zeiger','max_laenge','trennzeichen # , ; ?tabstop?')!

      kann mir einer auf die schnelle sagen wie ich den delimiter (tabstop) ausdruecke?

      1. Moin!

        kann mir einer auf die schnelle sagen wie ich den delimiter (tabstop) ausdruecke?

        Auf verschiedene Weisen: In C-Syntaxartigen Zeichenketten steht \t für Tabulator, und \n für Newline (neue Zeile).

        Du kannst aber natürlich auch in die ASCII-Tabelle gucken und dort herausfinden, daß ein horizontaler Tabulator den ASCII-Wert 9 (dezimal) hat: http://cips02.physik.uni-bonn.de/pool/infos/ascii/table.htm (bei Google der erste Treffer bei "ASCII Tabelle").

        Vermutlich wird es aber auf dasselbe herauskommen.

        - Sven Rautenberg