Thread Mailmodul: Alternative zu Mime::Lite? (24 answers)
Opened by jemand at 2004-06-11 00:26

Dubu
 2004-06-13 20:37
#2855 #2855
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Perl beklagt sich darueber, dass du ungeprueft Benutzerdaten fuer das open(DATS, ">>$_[0]") in writed() benutzt. Mit dieser Zeile kann ich an jede Datei auf dem Server Daten anhaengen, fuer die der User, unter dem das Skript laeuft, Schreibrechte hat! Und die Funktion writes() reicht mir schon, um mir jede Datei anzeigen zu lassen. (Was Perl zwar per se nicht als unsicher ansieht, aber darueber kann man geteilter Meinung sein.)

Beispiel:
Code: (dl )
http://dein.server.tld/pfad/zum/skript?func=writes&datei=/etc/passwd

Was macht diese URL wohl, wenn der Server unter Linux/Unix laeuft?

Offensichtlich laeuft dein Skript unter Taint-Mode (gut!) und hat deshalb zumindest etwas gehobenere Sicherheitsansprueche.
Abhilfe: Entferne mit einer Regex alles aus den Benutzerparametern, was dort nicht hingehoert, z.B. Pfadangaben.

Noch ein paar Anmerkungen:
- Woher hast du diese Syntax mit "local"? Ersetze bitte alle "local variablenname" durch "my variablenname", falls du nicht ein uraltes Perl (< 5.0) benutzt.
- CGI-Parameter von Hand auszuwerten ist fehlertraechtig. Es gibt CGI.pm, und das ist bei Perl dabei.

Hier mal ein Vorschlag, wie man das mit CGI.pm schreiben koennte:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/perl -T

use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser);

my $FilePath = '/home/username/public_html/files/';
my $Cgi = CGI->new;

my %Dat = $Cgi->Vars;

if (exists $Dat{func} && $Dat{func} eq 'writes') {
   writes ($Dat{datei});
} elsif (exists $Dat{func} && $Dat{func} eq 'writed') {
   writed ($Dat{datei}, $Dat{text});
} else {
   first();
}

sub first{
 printhead('Datenschreiber');
 print $Cgi->p('In welche Datei soll geschrieben werden?'),
   $Cgi->start_form,
   $Cgi->textfield (-name => 'datei', -size => 40),
   $Cgi->hidden (-name => 'func', -default => 'writes'),
   $Cgi->submit (-value => 'Senden'),
   $Cgi->end_form;
 printfoot();
}

sub writes{
 my ($file) = @_;
 if ($file =~ /([.\w-]+)/) {   # nur Folgen von A-Z, a-z, 0-9, ., - oder _ zulassen
     $file = $1;
 } else {
     $file = 'test.dat';       # Fallback
 }

 open(DATEI, '<', $FilePath . $file) or die "Kann Datei $file nicht lesen: $!";
 my @zeilen = <DATEI>;
 close DATEI;

 printhead('Datenschreiber');
 print $Cgi->p("In der Datei $file steht Folgendes:"),
   $Cgi->p(join '<br />', @zeilen);

 print $Cgi->p('Wollen Sie etwas schreiben, so geben Sie es hier ein:'),
   $Cgi->start_form,
   $Cgi->textarea (-name => 'text', -rows => 10, -columns => 40, -wrap => 'virtual'),
   $Cgi->br,
   $Cgi->hidden (-name => 'func', -default => 'writed'),
   $Cgi->hidden (-name => 'datei', -default => $file),
   $Cgi->submit (-value => 'Speichern'),
   $Cgi->reset (),
   $Cgi->end_form;
 printfoot();
}

sub writed{
 my ($file, $text) = @_;
 if ($file =~ /([.\w-]+)/) {   # nur Folgen von A-Z, a-z, 0-9, ., - oder _ zulassen
     $file = $1;
 } else {
     $file = 'test.dat';       # Fallback
 }

 open(DATS, '>>', $FilePath . $file) or die "Kann Datei $file nicht schreiben: $!";
 print DATS $text;
 close(DATS);
 printhead('Datenschreiber');
 $text =~ s/\n/<br>/g;
 print $Cgi->h1("Schreiben erfolgreich!"),
   $Cgi->p("In die Datei $file wurde Folgendes geschrieben:"),
   $Cgi->p($text);
 printfoot();
}

sub printhead
{
 my ($title) = @_;
 print $Cgi->header(),
   $Cgi->start_html($title);
}

sub printfoot
{
 print $Cgi->end_html;
}


Ob man CGI.pm auch fuer den HTML-Code benutzt ist Geschmackssache, aber zumindest fuer Header und Formulare ist es anzuraten.

View full thread Mailmodul: Alternative zu Mime::Lite?