Fix security issue related to unsanitized rcs version strings:

* Added sanitize_revision()
* Do not install SourceChecker.*
* Add ~ & ` to shell_escape()
Bug #39284 r=timeless
This commit is contained in:
cls%seawood.org 2004-09-15 22:44:55 +00:00
Родитель 6ab1ce036f
Коммит 6653ecac41
12 изменённых файлов: 43 добавлений и 46 удалений

Просмотреть файл

@ -89,10 +89,24 @@ sub url_encode3 {
# Quotify a string, suitable for invoking a shell process # Quotify a string, suitable for invoking a shell process
sub shell_escape { sub shell_escape {
my ($file) = @_; my ($file) = @_;
$file =~ s/([ \"\'\?\$\&\|\!<>\(\)\[\]\;\:])/\\$1/g; $file =~ s/([ \"\'\`\~\?\$\&\|\!<>\(\)\[\]\;\:])/\\$1/g;
return $file; return $file;
} }
# Make sure CVS revisions are in a specific format
sub sanitize_revision {
my ($rev) = @_;
print STDERR "Testing: |$rev|\n";
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 ## Routines to generate html as part of Bonsai
## ##

Просмотреть файл

@ -41,8 +41,6 @@ RCSDIFF=@RCSDIFF@
CVSGRAPH=@CVSGRAPH@ CVSGRAPH=@CVSGRAPH@
FILES = CGI.pl \ FILES = CGI.pl \
SourceChecker.cgi \
SourceChecker.pm \
addcheckin.pl \ addcheckin.pl \
admin.cgi \ admin.cgi \
adminfuncs.pl \ adminfuncs.pl \

Просмотреть файл

@ -76,13 +76,6 @@ accreted wildly. There is probably quite a lot of dead code in here.
Makefile.in: "make install" lets you specify where you store Makefile.in: "make install" lets you specify where you store
perl and bonsai on your system. perl and bonsai on your system.
SourceChecker.cgi scc wrote to help sanitize code. DELETE
Called by: nobody
SourceChecker.pm Called by:
SourceChecker.cgi
cvsblame.cgi when passed sanitize=<dictionary>
addcheckin.pl Perl. Add a checkin to a Bonsai hook. Determines addcheckin.pl Perl. Add a checkin to a Bonsai hook. Determines
if the tree was open or closed at the time, shunts if the tree was open or closed at the time, shunts
checkin to proper tree. checkin to proper tree.

Просмотреть файл

@ -54,7 +54,6 @@ sub sillyness {
require 'CGI.pl'; require 'CGI.pl';
require 'cvsblame.pl'; require 'cvsblame.pl';
use SourceChecker;
# Cope with the cookie and print the header, first thing. That way, if # Cope with the cookie and print the header, first thing. That way, if
# any errors result, they will show up for the user. # any errors result, they will show up for the user.
@ -73,15 +72,6 @@ my $SubHead = '';
my @src_roots = getRepositoryList(); my @src_roots = getRepositoryList();
# Init sanitiazation source checker
#
my $sanitization_dictionary = $::FORM{sanitize};
my $opt_sanitize = defined $sanitization_dictionary;
if ( $opt_sanitize )
{
dbmopen %SourceChecker::token_dictionary, "$sanitization_dictionary", 0664;
}
# Init byrd's 'feature' to allow html in comments # Init byrd's 'feature' to allow html in comments
# #
my $opt_html_comments = &html_comments_init(); my $opt_html_comments = &html_comments_init();
@ -107,7 +97,8 @@ my $url_file_tail = url_quote($file_tail);
# Handle the "rev" argument # Handle the "rev" argument
# #
$::opt_rev = ''; $::opt_rev = '';
$::opt_rev = $::FORM{rev} if defined $::FORM{rev} and $::FORM{rev} ne 'HEAD'; $::opt_rev = sanitize_revision($::FORM{rev}) if
defined $::FORM{rev} and $::FORM{rev} ne 'HEAD';
my $revstr = ''; my $revstr = '';
$revstr = "&rev=$::opt_rev" unless $::opt_rev eq ''; $revstr = "&rev=$::opt_rev" unless $::opt_rev eq '';
my $browse_revtag = 'HEAD'; my $browse_revtag = 'HEAD';
@ -322,9 +313,6 @@ foreach $revision (@::revision_map)
if ($opt_html_comments) { if ($opt_html_comments) {
# Don't escape HTML in C/C++ comments # Don't escape HTML in C/C++ comments
$text = &leave_html_comments($text); $text = &leave_html_comments($text);
} elsif ( $opt_sanitize ){
# Mark filty words and Escape HTML meta-characters
$text = markup_line($text);
} else { } else {
$text =~ s/&/&amp;/g; $text =~ s/&/&amp;/g;
$text =~ s/</&lt;/g; $text =~ s/</&lt;/g;
@ -438,11 +426,6 @@ if ($::use_layers || $::use_dom) {
&print_bottom; &print_bottom;
if ( $opt_sanitize )
{
dbmclose %SourceChecker::token_dictionary;
}
## END of main script ## END of main script
sub max { sub max {

Просмотреть файл

@ -28,7 +28,7 @@ require 'CGI.pl';
my $file= $::FORM{'file'}; my $file= $::FORM{'file'};
my $mark= $::FORM{'mark'}; my $mark= $::FORM{'mark'};
my $ln = ($mark > 10 ? $mark-10 : 1 ); my $ln = ($mark > 10 ? $mark-10 : 1 );
my $rev = $::FORM{'rev'}; my $rev = sanitize_revision($::FORM{'rev'});
my $debug = $::FORM{'debug'}; my $debug = $::FORM{'debug'};
print "Content-Type: text/html\n\n"; print "Content-Type: text/html\n\n";

Просмотреть файл

@ -73,7 +73,8 @@ my $url_file_tail = url_quote($file_tail);
# Handle the "rev" argument # Handle the "rev" argument
# #
$::opt_rev = ""; $::opt_rev = "";
$::opt_rev = $::FORM{'rev'} if defined $::FORM{'rev'} && $::FORM{'rev'} !~ m/^(HEAD|MAIN)$/; $::opt_rev = sanitize_revision($::FORM{'rev'}) if
defined $::FORM{'rev'} && $::FORM{'rev'} !~ m/^(HEAD|MAIN)$/;
my $revstr = ''; my $revstr = '';
$revstr = "&rev=$::opt_rev" unless $::opt_rev eq ''; $revstr = "&rev=$::opt_rev" unless $::opt_rev eq '';
my $browse_revtag = 'HEAD'; my $browse_revtag = 'HEAD';

Просмотреть файл

@ -120,9 +120,8 @@ print "</td></tr>";
# Branch # Branch
# #
if( defined $::FORM{branch} ){ if( defined $::FORM{branch} ){
$b = $::FORM{branch}; $b = sanitize_revision($::FORM{branch});
} } else {
else {
$b = "HEAD"; $b = "HEAD";
} }
print "<tr> print "<tr>

Просмотреть файл

@ -123,17 +123,17 @@ $prefix = $script_name . $ENV{PATH_INFO} . '?' if (exists($ENV{PATH_INFO}));
# http://w3/cgi/cvsview.pl?subdir=foo&file=bar would assign # http://w3/cgi/cvsview.pl?subdir=foo&file=bar would assign
# $opt_subdir = foo and $opt_file = bar. # $opt_subdir = foo and $opt_file = bar.
my $opt_rev1 = $request->param('rev1'); my $opt_rev1 = sanitize_revision($request->param('rev1'));
my $opt_rev2 = $request->param('rev2'); my $opt_rev2 = sanitize_revision($request->param('rev2'));
my $opt_root = $request->param('root'); my $opt_root = $request->param('root');
my $opt_files = $request->param('files'); my $opt_files = $request->param('files');
my $opt_skip = $request->param('skip') || 0; my $opt_skip = $request->param('skip') || 0;
my $opt_diff_mode = $request->param('diff_mode') || 'context'; my $opt_diff_mode = $request->param('diff_mode') || 'context';
my $opt_whitespace_mode = $request->param('whitespace_mode') || 'show'; my $opt_whitespace_mode = $request->param('whitespace_mode') || 'show';
my $opt_file = $request->param('file'); my $opt_file = $request->param('file');
my $opt_rev = $request->param('diff_mode'); my $opt_rev = sanitize_revision($request->param('rev'));
my $opt_subdir = $request->param('subdir'); my $opt_subdir = $request->param('subdir');
my $opt_branch = $request->param('branch'); my $opt_branch = sanitize_revision($request->param('branch'));
my $opt_command = $request->param('command'); my $opt_command = $request->param('command');
my $url_file = url_quote($opt_file); my $url_file = url_quote($opt_file);

Просмотреть файл

@ -42,7 +42,13 @@ my $RealFilename = DataDir() . "/$Filename";
Lock(); Lock();
my $Text = ''; my $Text = '';
$Text = `cat $RealFilename` if -f $RealFilename; if (-f $RealFilename) {
open(FILE, $ReadFilename);
while (<FILE>) {
$Text .= $_;
}
close(FILE);
}
unless (FormData('origtext') eq $Text) { unless (FormData('origtext') eq $Text) {
PutsHeader("Oops!", "Oops!", "Someone else has been here!"); PutsHeader("Oops!", "Oops!", "Someone else has been here!");

Просмотреть файл

@ -39,7 +39,13 @@ my $Filename = FormData('msgname');
my $RealFilename = DataDir() . "/$Filename"; my $RealFilename = DataDir() . "/$Filename";
my $Text = ''; my $Text = '';
$Text = `cat $RealFilename` if -f $RealFilename; if (-f $RealFilename) {
open(FILE, $ReadFilename);
while (<FILE>) {
$Text .= $_;
}
close(FILE);
}
LoadTreeConfig(); LoadTreeConfig();
PutsHeader("Message Editor", "Message Editor", PutsHeader("Message Editor", "Message Editor",

Просмотреть файл

@ -65,7 +65,7 @@ if( $form{"allchanges"} ){
} }
else { else {
while( my ($k, $v) = each( %form ) ){ while( my ($k, $v) = each( %form ) ){
push( @revs, $k ); push( @revs, sanitize_revision($k) );
} }
} }

Просмотреть файл

@ -61,11 +61,8 @@ $dir = "" if ($dir =~ /^\.\.\/$/);
$dir =~ s/^\/([^:]*)/$1/; $dir =~ s/^\/([^:]*)/$1/;
$dir =~ s/([^:]*)\/$/$1/; $dir =~ s/([^:]*)\/$/$1/;
my $rev = $::FORM{"rev"}; my $rev = '';
$rev = sanitize_revision($::FORM{"rev"}) if defined($::FORM{"rev"});
if(!defined($rev)) {
$rev='';
}
print "Content-type: text/html\n\n"; print "Content-type: text/html\n\n";