serverseitig Excel-Datei nach Upload erkennen
Andreas Korthaus
- php
Hallo!
Ich habe einen Upload über ein html-Formular geschrieben, und überlege jetzt, wie ich Mißbrauch berhindern kann. Ich konntrolliere die Datei folgendermaßen:
if (isset($_FILES['userfile']) &&
(!$_FILES['userfile']['error']) &&
($_FILES['userfile']['type'] == "application/octet-stream") &&
(substr($_FILES['userfile']['name'],-4) == ".xls")) {
move_uploaded_file($_FILES['userfile']['tmp_name'], $dateiname);
}
else {
echo "FEHLER";
exit;
}
Erste Fragen, "application/octet-stream", beaue ich mir damit keine Stolperfalle, vielleicht senden das nicht alle Browser?
Außerdem bringt das nicht so viel, wenn ich eine jpg-Datei hochlade und als .xls umbenenne, ist das dann auch "application/octet-stream".
OK, Dateiendung prüfen sollte ich auf alle Fälle, oder?
Wie wärs noch mit einer mindest und Maximalgröße über $_FILES['probe']['size']? Welche Werte würdet ihr empfehlen?
Was könnte man noch machen um zu verhindern das jemand irgendwelche "bösen" Scripte oder so hochläd?
Bin für jeden Tipp dankbar!
Grüße
Andreas
Hi,
Bin für jeden Tipp dankbar!
Nun, einen "fertigen" Tipp habe ich nicht für Dich, lediglich eine Idee: Man kann mit Perl Excel-Dateien parsen (http://www.heise.de/ix/artikel/2001/06/175/. Wenn soetwas mit den passenden Modulen möglich ist, muß man doch mit diesen Modulen auch Dateien überprüfen können. Will heißen: Probier doch diese Dateien zu editieren und z.B. eine Zelle mit (fiktiven) Inhalt zu füllen. Wenn dies klappt, mach die Änderung rückgängig und Du weist, es ist ein gültiges Excel-File. Wenn es nicht klappt, kommt es zu einem Fehler, den Du abfangen kannst. Dann weist Du, dass es kein gültiges Excel-File ist.
Ich weiss aber nicht, ob es sowas auch für PHP gibt.
Wie gesagt, ist nur so eine spontane Idee.
Viel erfolg...
Alex :)
Hi!
Nun, einen "fertigen" Tipp habe ich nicht für Dich, lediglich eine Idee: Man kann mit Perl Excel-Dateien parsen (http://www.heise.de/ix/artikel/2001/06/175/. Wenn soetwas mit den passenden Modulen möglich ist, muß man doch mit diesen Modulen auch Dateien überprüfen können. Will heißen: Probier doch diese Dateien zu editieren und z.B. eine Zelle mit (fiktiven) Inhalt zu füllen. Wenn dies klappt, mach die Änderung rückgängig und Du weist, es ist ein gültiges Excel-File. Wenn es nicht klappt, kommt es zu einem Fehler, den Du abfangen kannst. Dann weist Du, dass es kein gültiges Excel-File ist.
Ja, genau zu dem Zweck will ich ja Excel hochladen ;-) Ich brauch auch gar nicht schreiben, wenn die Datei nicht geparst werden kann müßte ich ja eine Fehlermeldung erhalten, das wollte ich dann sowieso einbauen, Problem ist nur das meine Scripte in PHP programiert sind, und das Excel-Parse Script in PERL, welches ich über einen system() Aufruf aus PHP starte.
Daheher weiß ich nich nicht wie ich die Fehlermeldung übermittlen soll, aber ich könnnte für den Zweck ja ein eigens PERL-Script schreiben, welches ggfs. eine Fehlermeldung ausgibt.
Wie wäre es einfach mit
use strict;
use Spreadsheet::ParseExcel;
my $oExcel = new Spreadsheet::ParseExcel;
my $oBook = $oExcel->Parse('Excel/Test97.xls');
if ($oBook==undef){
print "FEHLER";
}
else {
print "OK";
}
Dabei verlasse ich mich darauf das $oBook undef gesetzt wird, wenn das Parsen nicht funktioniert hat, wie in
http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm
angegeben, wenn ich das richtig verstehe. Kann ich das wohl so machen?
Ich weiss aber nicht, ob es sowas auch für PHP gibt.
Nein, da gibts leider nur die COM- Schnittstelle, aber dazu muß Excel installiert sein, und das ist unter Unix nicht ganz so trivial ;-)
Wie gesagt, ist nur so eine spontane Idee.
und eine sehr gute! Vierlen Dank, vor allem auch für den Heise-Artikel, den kannte ich noch gar nicht! Ich werde es auf jeden fall einbauen, nur weiß ich nicht ob ich mich alleine darauf verlassen sollte, denn was weiß ich wie die Date geparst wird und ob da nicht irgendwelche bösen Scripte die das Modul kennen irgendwelchen Code einschleusen können... Daher wäre auch eine mindest-Dateilänge nicht schlecht(da muß man erstmal drauf kommen, denn Scripte sind meist recht kurz), nur welche Länge nehme ich da ohne jetzt aus Versehen die Hälfte der kleineren echten Excel-Sheets abzublocken? Weiß jemand wie groß eine Excel Datei(97/2000) mindestens ist? Ich hatte noch keine unter 5KB, aber kann man das so annehmen? Was gäbe es noch für Kontrollmechanismen?
Viele Grüße
Andreas
Hallo,
Ja, genau zu dem Zweck will ich ja Excel hochladen ;-) Ich brauch auch gar nicht schreiben, wenn die Datei nicht geparst werden kann müßte ich ja eine Fehlermeldung erhalten, das wollte ich dann sowieso einbauen, Problem ist nur das meine Scripte in PHP programiert sind, und das Excel-Parse Script in PERL, welches ich über einen system() Aufruf aus PHP starte.
Ich habe mal kurz gegooglet und folgendes gefunden: http://sourceforge.net/projects/psxlsgen/
Vielleicht kannst Du das ja benutzen. Ich muß zugeben, das ich mich dort nicht eingelesen habe und einfach mal rate, ob was passendes für Dich dabei ist ;)
use strict;
use Spreadsheet::ParseExcel;
my $oExcel = new Spreadsheet::ParseExcel;
my $oBook = $oExcel->Parse('Excel/Test97.xls');
if ($oBook==undef){
print "FEHLER";
}
else {
print "OK";
}
Dabei verlasse ich mich darauf das $oBook undef gesetzt wird, wenn das Parsen nicht funktioniert hat, wie in
http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm
angegeben, wenn ich das richtig verstehe. Kann ich das wohl so machen?
Ich würde sagen ja, hast Du es denn mal ausprobiert?
Daher wäre auch eine mindest-Dateilänge nicht schlecht(da muß man erstmal drauf kommen, denn Scripte sind meist recht kurz) nur welche Länge nehme ich da ohne jetzt aus Versehen die Hälfte der kleineren echten Excel-Sheets abzublocken?
Eine leere, frisch gespeicherte Excel 2000 Datei ist 13,5 KB groß. Ob dies für Excel 97 auch gilt, weiss ich nicht.
Wenn Du Dein System fertig gestellt hast, wäre es interessant zu hören, wie Du es abschließend gemacht hast.
Viel Erfolg...
Alex :)