mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Add check routines to sanitize user input.
Rename sanitize_revision to SanitizeRevision and move it to globals.pl. Bug #261616 r=timeless
This commit is contained in:
parent
89ac7432f0
commit
42bf1ea441
@ -49,6 +49,8 @@ sub url_quote {
|
||||
# Quotify a string, suitable for output as form values
|
||||
sub value_quote {
|
||||
my ($var) = (@_);
|
||||
|
||||
return "" if (!defined($var));
|
||||
$var =~ s/\&/\&/g;
|
||||
$var =~ s/</\</g;
|
||||
$var =~ s/>/\>/g;
|
||||
@ -75,19 +77,6 @@ sub url_encode2 {
|
||||
return $s;
|
||||
}
|
||||
|
||||
# Make sure CVS revisions are in a specific format
|
||||
sub sanitize_revision {
|
||||
my ($rev) = @_;
|
||||
if ($rev =~ /^[A-Za-z]+/) {
|
||||
$rev =~ s/^([\w-]+).*/$1/;
|
||||
} elsif ($rev =~ /^\d+\.\d+/) {
|
||||
$rev =~ s/^(\d+[\.\d+]+).*/$1/;
|
||||
} elsif (defined($rev) && $rev ne "") {
|
||||
$rev = "1.1";
|
||||
}
|
||||
return $rev;
|
||||
}
|
||||
|
||||
##
|
||||
## Routines to generate html as part of Bonsai
|
||||
##
|
||||
|
@ -96,7 +96,7 @@ my $url_file_tail = url_quote($file_tail);
|
||||
# Handle the "rev" argument
|
||||
#
|
||||
$::opt_rev = '';
|
||||
$::opt_rev = sanitize_revision($::FORM{rev}) if
|
||||
$::opt_rev = &SanitizeRevision($::FORM{rev}) if
|
||||
defined $::FORM{rev} and $::FORM{rev} ne 'HEAD';
|
||||
my $revstr = '';
|
||||
$revstr = "&rev=$::opt_rev" unless $::opt_rev eq '';
|
||||
|
@ -27,7 +27,7 @@ require 'CGI.pl';
|
||||
my $file= $::FORM{'file'};
|
||||
my $mark= $::FORM{'mark'};
|
||||
my $ln = ($mark > 10 ? $mark-10 : 1 );
|
||||
my $rev = sanitize_revision($::FORM{'rev'});
|
||||
my $rev = SanitizeRevision($::FORM{'rev'});
|
||||
my $debug = $::FORM{'debug'};
|
||||
|
||||
print "Content-Type: text/html\n\n";
|
||||
|
@ -76,7 +76,7 @@ my $url_file_tail = url_quote($file_tail);
|
||||
# Handle the "rev" argument
|
||||
#
|
||||
$::opt_rev = "";
|
||||
$::opt_rev = sanitize_revision($::FORM{'rev'}) if
|
||||
$::opt_rev = &SanitizeRevision($::FORM{'rev'}) if
|
||||
defined $::FORM{'rev'} && $::FORM{'rev'} !~ m/^(HEAD|MAIN)$/;
|
||||
my $revstr = '';
|
||||
$revstr = "&rev=$::opt_rev" unless $::opt_rev eq '';
|
||||
|
@ -119,7 +119,7 @@ print "</td></tr>";
|
||||
# Branch
|
||||
#
|
||||
if( defined $::FORM{branch} ){
|
||||
$b = sanitize_revision($::FORM{branch});
|
||||
$b = &SanitizeRevision($::FORM{branch});
|
||||
} else {
|
||||
$b = "HEAD";
|
||||
}
|
||||
|
@ -122,17 +122,17 @@ $prefix = $script_name . $ENV{PATH_INFO} . '?' if (exists($ENV{PATH_INFO}));
|
||||
# http://w3/cgi/cvsview.pl?subdir=foo&file=bar would assign
|
||||
# $opt_subdir = foo and $opt_file = bar.
|
||||
|
||||
my $opt_rev1 = sanitize_revision($request->param('rev1'));
|
||||
my $opt_rev2 = sanitize_revision($request->param('rev2'));
|
||||
my $opt_rev1 = &SanitizeRevision($request->param('rev1'));
|
||||
my $opt_rev2 = &SanitizeRevision($request->param('rev2'));
|
||||
my $opt_root = $request->param('root');
|
||||
my $opt_files = $request->param('files');
|
||||
my $opt_skip = $request->param('skip') || 0;
|
||||
my $opt_diff_mode = $request->param('diff_mode') || 'context';
|
||||
my $opt_whitespace_mode = $request->param('whitespace_mode') || 'show';
|
||||
my $opt_file = $request->param('file');
|
||||
my $opt_rev = sanitize_revision($request->param('rev'));
|
||||
my $opt_rev = &SanitizeRevision($request->param('rev'));
|
||||
my $opt_subdir = $request->param('subdir');
|
||||
my $opt_branch = sanitize_revision($request->param('branch'));
|
||||
my $opt_branch = &SanitizeRevision($request->param('branch'));
|
||||
my $opt_command = $request->param('command');
|
||||
my $url_file = url_quote($opt_file);
|
||||
|
||||
|
@ -25,6 +25,7 @@ $::TreeID = "default";
|
||||
|
||||
use strict;
|
||||
use DBI;
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
|
||||
use Date::Format; # For time2str().
|
||||
@ -1052,12 +1053,28 @@ sub validateRepository {
|
||||
}
|
||||
|
||||
my $escaped_root = html_quote($root);
|
||||
print "\n";
|
||||
print "Invalid repository `$escaped_root' selected.\n";
|
||||
print ConstructMailTo(Param('maintainer'), "Invalid Repository '$root'");
|
||||
print " if you think this should have worked.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
# Verify that the current script is being called from a specific other script
|
||||
sub validateReferer {
|
||||
my (@scripts) = @_;
|
||||
my $script;
|
||||
my $found = 0;
|
||||
my $script_path = dirname("$ENV{'SERVER_NAME'}$ENV{'SCRIPT_NAME'}");
|
||||
my $referer = $ENV{'HTTP_REFERER'} || "";
|
||||
|
||||
foreach $script (@scripts) {
|
||||
$found++ if
|
||||
($referer =~ m@^http(s)?://(\w+(:\w+)?\@)?$script_path/$script(\?|$)@i);
|
||||
}
|
||||
die "This script cannot be called directly.\n" if (!$found);
|
||||
}
|
||||
|
||||
sub formatSqlTime {
|
||||
my ($date) = @_;
|
||||
my $time = sprintf("%u", $date);
|
||||
@ -1068,6 +1085,23 @@ sub formatSqlTime {
|
||||
return $time;
|
||||
}
|
||||
|
||||
##
|
||||
## Miscelaneous routines from lloydcgi.pl
|
||||
##
|
||||
|
||||
my @weekdays = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
|
||||
my @months = ('Jan','Feb','Mar','Apr','May','Jun',
|
||||
'Jul','Aug','Sep','Oct','Nov','Dec');
|
||||
|
||||
sub toGMTString {
|
||||
my ($seconds) = $_[0];
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
|
||||
= gmtime($seconds);
|
||||
$year += 1900;
|
||||
|
||||
sprintf('%s, %02d-%s-%d %02d:%02d:%02d GMT',
|
||||
$weekdays[$wday],$mday,$months[$mon],$year,$hour,$min,$sec);
|
||||
}
|
||||
|
||||
# Returns true if the given directory or filename is one of the hidden ones
|
||||
# that we don't want to show users.
|
||||
@ -1118,6 +1152,8 @@ sub MarkUpText {
|
||||
my $bugsmatch = Param('bugsmatch');
|
||||
my %substs = ();
|
||||
|
||||
return $text if (!$bugsrpl);
|
||||
|
||||
$substs{'bug_id'} = '$1';
|
||||
$bugsrpl = PerformSubsts($bugsrpl, \%substs);
|
||||
|
||||
@ -1251,8 +1287,160 @@ sub Fix_BonsaiLink {
|
||||
# Quotify a string, suitable for invoking a shell process
|
||||
sub shell_escape {
|
||||
my ($file) = @_;
|
||||
$file =~ s/\000/_NULL_/g;
|
||||
$file =~ s/([ \"\'\`\~\^\?\$\&\|\!<>\(\)\[\]\;\:])/\\$1/g;
|
||||
return $file;
|
||||
}
|
||||
|
||||
#
|
||||
# Routines to enforce certain input restrictions
|
||||
#
|
||||
sub ExpectCheckinId {
|
||||
my ($id) = @_;
|
||||
die("Invalid checkin id.\n") unless ($id =~ m/^::checkin_\d+_\d+$/);
|
||||
return $id;
|
||||
}
|
||||
|
||||
sub ExpectDate {
|
||||
my ($date) = @_;
|
||||
my $res;
|
||||
|
||||
return $date if ($date =~ m/^\d+$/);
|
||||
$res = &str2time($date);
|
||||
return $res if (defined($res));
|
||||
die "Invalid date format.\n";
|
||||
}
|
||||
|
||||
sub ExpectDigit {
|
||||
my ($var, $str) = @_;
|
||||
|
||||
if (!defined($str) || $str !~ m/^\d+$/) {
|
||||
print STDERR "Expecting digit for $var. Got \"" .
|
||||
shell_escape($str) . "\" instead.\n";
|
||||
die "Invalid format for $var.\n";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
# match types: match, regexp or notregexp
|
||||
sub ExpectMatchtype {
|
||||
my ($matchtype) = @_;
|
||||
|
||||
return $matchtype if (!defined($matchtype) || $matchtype eq '' ||
|
||||
$matchtype eq 'match' || $matchtype eq 'regexp' ||
|
||||
$matchtype eq 'notregexp');
|
||||
die "Invalid matchtype.\n";
|
||||
}
|
||||
|
||||
sub ExpectOnOff {
|
||||
my ($var, $str) = @_;
|
||||
|
||||
if (!defined($str) || $str !~ m/^(on|off)/) {
|
||||
print STDERR "Expecting on/off value for $var. Got \"" .
|
||||
shell_escape($str) . "\" instead.\n";
|
||||
die "Invalid format for $var.\n";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
# The mark argument expects a specific format
|
||||
# digit or (d1)-(d2)
|
||||
# where digit is the line number to mark
|
||||
# and d1 & d2 are the optional beginning & ending of a range.
|
||||
# If d1 & d2 are omitted, the entire file is marked
|
||||
sub SanitizeMark {
|
||||
my ($mark_arg) = @_;
|
||||
my ($newmark) = "";
|
||||
|
||||
return "" if (!defined($mark_arg));
|
||||
foreach my $mark (split ',', $mark_arg) {
|
||||
if ($mark =~ m/^(\d*)-(\d*)$/) {
|
||||
$newmark .= ",$1-$2";
|
||||
} elsif ($mark =~ m/^\d+$/) {
|
||||
$newmark .= ",$mark";
|
||||
} else {
|
||||
# Ignore invalid input
|
||||
next;
|
||||
}
|
||||
}
|
||||
$newmark =~ s/^,//;
|
||||
return $newmark;
|
||||
}
|
||||
|
||||
# Strip garbage from module name
|
||||
# For now, assume: alphanumeric - . +
|
||||
sub SanitizeModule {
|
||||
my ($module) = @_;
|
||||
|
||||
return "" if (!defined($module));
|
||||
$module =~ s/\000/_NULL_/g;
|
||||
$module =~ s/([A-Za-z])([\w\-\.\+]*).*/$1$2/;
|
||||
return $module;
|
||||
}
|
||||
|
||||
# Make sure CVS revisions are in a specific format
|
||||
sub SanitizeRevision {
|
||||
my ($rev) = @_;
|
||||
|
||||
return "" if (!defined($rev) || $rev eq "");
|
||||
if ($rev =~ /^[A-Za-z]+/) {
|
||||
$rev =~ s/^([\w-]+).*/$1/;
|
||||
} elsif ($rev =~ /^\d+\.\d+/) {
|
||||
$rev =~ s/^(\d+[\.\d+]+).*/$1/;
|
||||
} else {
|
||||
die "Invalid revision format.\n";
|
||||
}
|
||||
return $rev;
|
||||
}
|
||||
|
||||
# Allow alphanumeric usernames that start with alphas
|
||||
# Also allow: % . - +
|
||||
# Use 'nobody' if username doesn't match the modified format
|
||||
sub SanitizeUsernames {
|
||||
my ($users) = @_;
|
||||
my $userlist = '';
|
||||
|
||||
return "" if (!defined($users));
|
||||
foreach my $user (split(/,/, $users)) {
|
||||
$user =~ s/\000/_NULL_/;
|
||||
$user =~ s/([A-Za-z])([\w\%\.\-\+]*).*/$1$2/;
|
||||
$userlist .= ",$user";
|
||||
}
|
||||
$userlist =~ s/^,//;
|
||||
return $userlist;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# We should use the routine from File::Spec but perl 5.004 doesn't have it
|
||||
#
|
||||
sub canonpath {
|
||||
my ($path) = @_;
|
||||
my (@list);
|
||||
|
||||
return "" if (!defined($path) || $path eq "");
|
||||
foreach my $dir (split('/', $path)) {
|
||||
if ($dir eq "\.\.") {
|
||||
pop @list;
|
||||
} else {
|
||||
push @list, $dir;
|
||||
}
|
||||
}
|
||||
$path = join("/",@list);
|
||||
$path =~ s@//+@/@g;
|
||||
return $path;
|
||||
}
|
||||
|
||||
# Do not allow access to files outside of cvsroot
|
||||
sub ChrootFilename {
|
||||
my ($root, $path) = @_;
|
||||
my $cpath = canonpath($path);
|
||||
#print STDERR "ChrootFilename($root, $path, $cpath)\n";
|
||||
CheckHidden($path);
|
||||
die "Browsing outside of cvsroot not allowed.\n"
|
||||
unless ($cpath =~ m@^$root/@ || $cpath eq $root);
|
||||
die "\nFiles in the CVSROOT are not accessible.\n" if
|
||||
($cpath =~ m@$root/CVSROOT@);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -63,7 +63,7 @@ if( $form{"allchanges"} ){
|
||||
}
|
||||
else {
|
||||
while( my ($k, $v) = each( %form ) ){
|
||||
push( @revs, sanitize_revision($k) );
|
||||
push( @revs, &SanitizeRevision($k) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ $dir =~ s/^\/([^:]*)/$1/;
|
||||
$dir =~ s/([^:]*)\/$/$1/;
|
||||
|
||||
my $rev = '';
|
||||
$rev = sanitize_revision($::FORM{"rev"}) if defined($::FORM{"rev"});
|
||||
$rev = &SanitizeRevision($::FORM{"rev"}) if defined($::FORM{"rev"});
|
||||
|
||||
print "Content-type: text/html\n\n";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user