Teil von SELFHTML aktuell Teil von Artikel Teil von CGI/Perl

Christian Kruse:
Fileupload per Perl/CGI

nach unten Christian Kruse
nach unten Dateien per Perl/CGI hochladen
nach unten Voraussetzungen
nach unten Quelltext eines Beispiel-Scripts
nach unten Installation des Scripts und Aufruf in HTML
nach unten Sicherheits-Hinweise

Christian Kruse

E-Mail: E-Mail CK1@wwwtech.de
Homepage-URL: deutschsprachige Seite http://wwwtech.de/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Fileupload per Perl/CGI

Wer kennt das Problem nicht: eine Datei soll über ein Formular und per HTTP auf einen Server geladen werden, da ein FTP-Zugang nicht zur Verfügung steht oder nicht eingesetzt werden darf/soll.
Dieser Artikel beschäftigt sich mit genau dieser Problematik und mit den damit verbundenen Sicherheitslücken.

nach obennach unten

Voraussetzungen

Für die Inbetriebnahme dieses Scripts benötigen Sie einen lauffähigen Webserver (siehe: Seite Webserver) mit CGI-Unterstützung (siehe: Seite CGI) und englischsprachige Seite Perl 5. Außerdem muss das Perl-Modul englischsprachige Seite CGI.pm installiert sein - dieses Modul gehört allerdings zur Standard-Distribution und sollte schon installiert sein.

nach obennach unten

Quelltext des Beispiel-Scripts (CGI-Script in Perl)

Der folgende Perl-Quellcode enthält ein Beispiel für ein Fileupload-Script.

Beispiel:

#!/usr/bin/perl -w

use strict;
use CGI; # Modul fuer CGI-Programme

my $cgi = new CGI; # neues Objekt erstellen

# Content-type fuer die Ausgabe
print $cgi->header(-type => 'text/html');

# die datei-daten holen
my $file = $cgi->param("myfile");

# dateinamen erstellen und die datei auf dem server speichern
my $fname = 'file_'.$$.'_'.$ENV{REMOTE_ADDR}.'_'.time;
open DAT,'>'.$fname or die 'Error processing file: ',$!;

# Dateien in den Binaer-Modus schalten
binmode $file;
binmode DAT;

my $data;
while(read $file,$data,1024) {
  print DAT $data;
}
close DAT;

print <<"HTML";
<html>
<head>
<title>Fileupload</title>
</head>
<body bgcolor="#FFFFFF">
<h1>Die Datei $file wurde erfolgreich hochgeladen.</h1>

<p>
Die Datei $file wurde erfolgreich auf dem Server
   gespeichert.
  </p>
</body>
</html>
HTML

Erläuterung:

Das Script bindet zunächst das Modul CGI.pm ein, das für die Auswertung der übertragenen Daten sorgt.

Mit dem Befehl my $cgi = new CGI; wird ein neues Objekt $cgi erstellt und die übergebenen Daten werden eingelesen.

Die Methode CGI::param stellt dem Script sowohl ein Filehandle, als auch den Dateinamen der hochgeladenen Datei zur Verfügung.
In der oberen While-Schleife wird die Datei in 1024-Byte-Blöcken eingelesen und in die andere Datei geschrieben. Beide sind im Binär-Modus geöffnet, weil nicht bekannt ist, ob die Daten, die ankommen, Binär- oder Text-Daten sind.
Zuletzt wird noch eine Bestätigung an den User weitergegeben, daß die Datei erfolgreich gesichert wurde.

Beachten Sie:

Dieses Script ist nicht für den praktischen Gebrauch gedacht, es dient lediglich als Beispiel. Bei einem für die Praxis gemachtem Script müssten die Sicherheits-Vorkehrungen viel strenger sein.

nach obennach unten

Installation des Scripts und Aufruf in HTML

Alles nötige, um dieses Script in Betrieb zu nehmen, können sie in SELFHTML unter Seite CGI und im Artikel Seite Die Inbetriebnahme eines CGI-Skripts von Michael Schröpl nachlesen.

Nun können Sie das Skript nutzen. Die Einbindung in Ihre HTML-Datei könnte z. B. so aussehen:

Beispiel:

<form action="http://www.ihreadresse.de/cgi-bin/ihrscript.pl" method="post" enctype="multipart/form-data">
<input type="file" name="myfile" accept="text/*" maxlength="2097152">
<!-- hier beliebige andere Felder -->
<input type="submit"><input type="reset">
</form>

Erläuterung:

Beim action-Attribut des <form>-Tags geben Sie die URL-Adresse Ihres Fileupload-Scripts an. Über das Datei-Feld mit dem Namen "myfile" wird die Datei an das Script übertragen.
Im Folgenden können Sie noch beliebig viele andere Formular-Felder definieren.

Beachten Sie:

Bitte geben Sie bei dem Datei-Feld immer den accept-Parameter und den maxlength-Parameter an!
Diese sorgen dafür, daß nur bestimmte Dateien von bestimmter Größe hochgeladen werden können. Allerdings wird beides bisher von keinem bekannten Browser unterstützt, so daß sie auf jedenfall zusätzlich eine Server-basierte Überprüfung machen sollten.

nach obennach unten

Sicherheits-Hinweise

Ein Datei-Upload auf den Server bedeutet immer ein Sicherheits-Risiko. Ein Hacker könnte Ihr Script ausnutzen und eigene Scripts hochladen, so daß er Zugriff auf den Server und Ihre Dateien bekommt.

Deshalb sollten von Anfang an einige Sicherheits-Vorkehrungen getroffen werden. Dazu zählen unter anderem:

Das könnte z. B. so aussehen:

Beispiel:

my @extensions = qw(txt dat gif jpg);

if($file{"filename"} !~ /^[a-z\.\-_]+?\.([a-z]{3})$/)
 { die("Ungültiger Dateiname"); }
else
 {
 my $extension = $1;
 if(!grep($extension,@extensions))
  { die("Ungültige Dateiendung"); }
 }

Erläuterung:

In dem obigen Code-Schnipsel wird ein Array @extensions mit gültigen Datei-Endungen definiert.
Dann wird der Dateiname auf Integrität überprüft. Wenn Sonderzeichen, shell pipes oder ähnliches darin vorkommen, so wird das Script mit einer Fehlermeldung beendet.

Weitere Hinweise zu Sicherheit in CGI-Scripten lesen sie bitte im Artikel deutschsprachige Seite CGI-Sicherheit von Wolfgang Wiese nach.

Teil von SELFHTML aktuell Teil von Artikel Teil von CGI/Perl

© 2007 bereichsübergreifende Seite Impressum