I need to make sure that regex, that is passed as user input will not accidentally be terminated and turn into arbitrary Perl code, but at the same time work for basic filtering purposes.
Important! This part of the code is run in user-jailed mode, meaning that potentially, it can only be self-exploited. Apart from this, UI is only exposed to particular user, and potentially run against limited number of files, thus potential DoS risks are very minimal.
In order to reach my goal, I created custom function that would first quotemeta all, and later un-escape needed only for regex to run characters.
Example:
# Allow short range of special chars to be left unescaped
# to let regex work, while at the same time prevent possible
# command injection or premature regex termination
my $mask = $in{'mask'};
sub quotemeta_dangerous
{
my ($string) = @_;
$string = quotemeta($string);
$string =~ s/\\\\/\\/g;
$string =~ s/\\\+/+/g;
$string =~ s/\\\*/*/g;
$string =~ s/\\\$/\$/g;
$string =~ s/\\\^/\^/g;
$string =~ s/\\\(/\(/g;
$string =~ s/\\\)/\)/g;
$string =~ s/\\\{/\{/g;
$string =~ s/\\\}/\}/g;
$string =~ s/\\\[/\[/g;
$string =~ s/\\\]/\]/g;
$string =~ s/\\\?/?/g;
$string =~ s/\\\././g;
$string =~ s/\\\-/-/g;
return $string;
}
my $sanitized_mask = quotemeta_dangerous($mask);
if ($filename =~ /$sanitized_mask/) {
# matched
}
Questions:
Whether my solution above will help me to achieve my goals safely, considering mentioned, important side notes. What are the potential risks that I don't see here?
As side, but familiar question, when further running substitutions, does the replace part can be injected/exploited as well, and if it is, how to safely run substitutions in contents on matched files?
Example:
$file_contents =~ s/\Q$text_to_find\E/$text_to_replace_with/g;
Is $text_to_replace_with
can be avoided here as security risk, when passed from user as it is?