Thread Warum ist das Ergebnis eines Regex-Matches je nach Input tainted? (7 answers)
Opened by clms at 2015-02-16 01:16

clms
 2015-02-16 01:16
#179680 #179680
User since
2010-08-29
373 Artikel
BenutzerIn
[default_avatar]
Hallo,

wenn ich use locale benutze, ist das Ergebnis eines Matches tainted, sobald ich in der Regex einen Konstrukt verwende, der von meinem setlocale beeinflusst wird, wie \w, \b oder \d.
So weit, so gut.
(Ich habe zwar noch nicht ganz kapiert, warum Perl das so macht, aber sei's drum.)

Als Konsequenz muss ich bei gesetztem use locale in der Regex z.B. \d durch [0-9] ersetzen (oder ab Perl 5.14 die 'a' Option beim Match setzen).

Jetzt bin ich aber auf eine Regex gestoßen, die IMHO kein davon betroffenes Konstrukt enthält, aber je nach Eingangsstring das Ergebnis trotzdem als 'tainted' markiert.
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/perl -T

use strict; 
use warnings;
use v5.10;

use Scalar::Util;
use locale;
use POSIX qw(locale_h);
setlocale(LC_CTYPE, "de_DE");

sub filter_string {
  my $s = shift;

  warn("raw string '$s' is tainted") if Scalar::Util::tainted($s);
  $s =~ m:^(.+?) \([0-9]{4}(/[IVX]+)?\).*?$: or die "String '$s' doesn't match";
  $s = $1;
  warn("filtered string '$s' is tainted") if Scalar::Util::tainted($s);
  $s;
}

my @strings = ('ABC1 (1945/IXV)',
               'ABC2 (1945)',
               'ABC3 (1945)',
               'ABC4 (1945) {DEF()}',
               'ABC5 (1945) {D ()}',
               'ABC6 (1945) {D(#)}',
               'ABC7 (1945) {D (#)}',
               'ABC8 (1945) {()}',
               'ABC9 (1945) {D ()}',
               'ABC10 (1945) ()',
               'ABC11 (1945) {()',
               'ABC12 (1945) { ()}',
               'ABC13 (1945) { ()',
               'ABC14 (1945) x(/',
               'ABC15 (1945) ( ',
               'ABC16 (1945) (',
               'ABC17 (1945) { (',
               'ABC18 (1945) { (#',
  );

foreach my $s (@strings) {
  say filter_string($s);
}


Mit perl 5.18.2 bekomme ich
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
filtered string 'ABC1' is tainted at ./check_taint.pl line 18.
ABC1
ABC2
ABC3
ABC4
filtered string 'ABC5' is tainted at ./check_taint.pl line 18.
ABC5
ABC6
filtered string 'ABC7' is tainted at ./check_taint.pl line 18.
ABC7
ABC8
filtered string 'ABC9' is tainted at ./check_taint.pl line 18.
ABC9
filtered string 'ABC10' is tainted at ./check_taint.pl line 18.
ABC10
ABC11
filtered string 'ABC12' is tainted at ./check_taint.pl line 18.
ABC12
filtered string 'ABC13' is tainted at ./check_taint.pl line 18.
ABC13
ABC14
filtered string 'ABC15' is tainted at ./check_taint.pl line 18.
ABC15
ABC16
ABC17
filtered string 'ABC18' is tainted at ./check_taint.pl line 18.
ABC18

Also: Wenn ich statt "(1945)" "(1945/IVX)" habe oder hinter dem "(1945)" noch ein String kommt der qr/ \(./ matched, ist das Ergebnis tainted, sonst nicht.

Kann mir das jemand erklären?
Last edited: 2015-02-16 23:21:58 +0100 (CET)

View full thread Warum ist das Ergebnis eines Regex-Matches je nach Input tainted?