Thread Sicherheit von @ARGV (43 answers)
Opened by bianca at 2020-01-15 18:01

haj
 2020-01-19 21:50
#191154 #191154
User since
2015-01-07
521 Artikel
BenutzerIn

user image
2020-01-19T10:53:07 rosti
[...]
Code (perl): (dl )
1
2
3
 my $classfile = $class;
 $classfile =~ s|::|/|g;
 require "$classfile.pm";


daß sowas mit -T in der shebang nicht durchgeht. Wobei in $class eine Klasse steht die ich selbst da reingeschrieben habe, die wird aus der Routingtable (Binärdatei) gelesen.

Daten aus einer Datei sind "tainted", das gilt auch für Kopien und Modifikationen der Daten. Somit funktioniert das genau so wie beschrieben!

2020-01-19T10:53:07 rosti
Nun, interessant deswegen, weil es Frameworks gibt, da steht der Name der Klasse im URL!

Aber meine Frage ist natürlich, was ich tun muss damit meine Klasse mit -T geladen werden kann.

Die Frameworks müssen dann den Klassennamen auch reinwaschen, denn auch die URL kommt "von extern". Wer die Konfigurationsdatei des Webservers kontrolliert, hat sonst völlig in der Hand, was da geladen und ausgeführt wird.

Reinwaschen kann man Variablen beispielsweise dadurch, dass man sie als "capture" eines regulären Ausdrucks bezieht. Das ist schon so beabsichtigt, weil reguläre Ausdrücke sich ganz natürlich dazu eignen, nur die gültigen Zeichen aus einen String rauszufiltern. Dabei kann man, wen man der Quelle vertraut, auch mogeln und im regulären Ausdruck einfach alles von vorn bis hinten mit qr/(.*)/ zulassen:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env -S perl -T
use strict;
use warnings;
use 5.020;
use Scalar::Util qw(tainted);

sub untaint_unchecked {
    ($_[0] =~ /(.*)/)[0];
}

sub check_taint {
    my ($name,$var) = @_;;
    my $tainted = tainted($var) ? '' : ' nicht';
    say "$name mit Wert '$var' ist$tainted verdorben";
}

check_taint("Umgebungsvariable HOME", $ENV{HOME});

my $var = $ENV{HOME} =~ s!/!::!gr;
check_taint("Modifizierte Kopie",$var);

my $laundered = untaint_unchecked($var);
check_taint("Reingewaschene Variable",$laundered);

Es hat übrigens selbst beim Mogel-Reinwaschen einen Sinn, das in einem Unterprogramm zu erledigen und den Einzeiler nicht "Inline" da hinzuschreiben, wo er gebraucht wird: Auf diesem Weg hat man jederzeit die Möglichkeit, herauszufinden, ob und wie die Variable validiert wurde, und überlegen, ob man Sicherheit gewinnt, wenn man schärfer validiert.

View full thread Sicherheit von @ARGV