I'm writing a global subroutine to "wrap" CGI::param() and I want it to strip out characters based on situational "patterns." For example, if it's a session id it might require digits only. If it's an html page it might be letters, a period and possibly a dash. If it's a password it could allow digits, letters and some special characters.
I came up with this approach and want to know if there's a more elegant way to do it. And also if this would be acceptable security in an online application?
#!/usr/bin/perl -T
use strict;
use warnings;
my $x = shift || '';
my $y = ParamData($x,'d');
print "[$y]\n";
$y = ParamData($x,'w');
print "[$y]\n";
$y = ParamData($x,'dw');
print "[$y]\n";
$y = ParamData($x,'dw ');
print "[$y]\n";
$y = ParamData($x,'dw- .');
print "[$y]\n";
$y = ParamData($x,'w ');
print "[$y]\n";
exit(0);
sub ParamData {
my $v = shift || return; # value
my $p = shift || return; # pattern
my $r = ''; # regex
print "[$p] = ";
foreach my $i (0 .. length($p) - 1) {
my $c = substr($p,$i,1);
for ($c) {
/^d$/ and do { $r .= '0-9'; last; };
/^w$/ and do { $r .= 'A-Za-z'; last; };
/^ $/ and do { $r .= ' '; last; };
/^-$/ and do { $r .= '-'; last; };
/^\.$/ and do { $r .= '\.'; last; };
}
}
$v =~ s/[^$r]//g;
if ($v =~ /^([$r]).$/) {
$v = $1; # untaint
}
return($v);
}
Here's output of a sample run:
$ ./paramdata.pl 'h.-1-.i m.2.o+m.3'
[d] = [123]
[w] = [himom]
[dw] = [h1im2om3]
[dw ] = [h1i m2om3]
[dw- .] = [h.-1-.i m.2.om.3]
[w ] = [hi mom]
What do you think? Thanks.
Aucun commentaire:
Enregistrer un commentaire