From ad1c95f23551ca4bbd459f6a6d73dfd68f24ee9a Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 15 Dec 2010 00:34:01 +0100 Subject: gitweb: Introduce esc_attr to escape attributes of HTML elements It is needed only to escape attributes of handcrafted HTML elements, and not those generated using CGI.pm subroutines / methods for HTML generation. While at it, add esc_url and esc_html where needed, and prefer to use CGI.pm HTML generating methods than handcrafted HTML code. Most of those are probably unnecessary (could be exploited only by person with write access to gitweb config, or at least access to the repository). This fixes CVE-2010-3906 Reported-by: Emanuele Gentili Helped-by: John 'Warthog9' Hawley Helped-by: Jonathan Nieder Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano (cherry picked from commit 3017ed62f47ce14a959e2d315c434d4980cf4243) Conflicts: gitweb/gitweb.perl Signed-off-by: Jonathan Nieder [For Ubuntu maverick, this patch has been slightly modified, so that hunk 8 applies cleanly; in the debian unstable version (1:1.7.2.3-2.2) this patch is pulled from a patch w/git id d905742e7d9632cbb3ce3f309d429d3dadc448d0 to make the logo optional. Signed-off-by: Steve Beattie ] --- gitweb/gitweb.perl | 37 ++++++++++++++++++++++--------------- 1 files changed, 22 insertions(+), 15 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 348f94b..dfa5966 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1332,6 +1332,13 @@ sub esc_url { return $str; } +# quote unsafe characters in HTML attributes +sub esc_attr { + + # for XHTML conformance escaping '"' to '"' is not enough + return esc_html(@_); +} + # replace invalid utf8 character with SUBSTITUTION sequence sub esc_html { my $str = shift; @@ -1737,7 +1744,7 @@ sub format_ref_marker { hash=>$dest )}, $name); - $markers .= " " . + $markers .= " " . $link . ""; } } @@ -1821,7 +1828,7 @@ sub git_get_avatar { return $pre_white . "" . $post_white; } else { @@ -2532,7 +2539,7 @@ sub git_show_project_tagcloud { } else { my @tags = sort { $cloud->{$a}->{count} <=> $cloud->{$b}->{count} } keys %$cloud; return '

' . join (', ', map { - "$cloud->{$_}->{topname}" + $cgi->a({-href=>"$home_link?by_tag=$_"}, $cloud->{$_}->{topname}) } splice(@tags, 0, $count)) . '

'; } } @@ -3429,11 +3436,11 @@ EOF # print out each stylesheet that exist, providing backwards capability # for those people who defined $stylesheet in a config file if (defined $stylesheet) { - print ''."\n"; + print ''."\n"; } else { foreach my $stylesheet (@stylesheets) { next unless $stylesheet; - print ''."\n"; + print ''."\n"; } } if (defined $project) { @@ -3446,7 +3453,7 @@ EOF my $type = lc($format); my %link_attr = ( '-rel' => 'alternate', - '-title' => "$project - $href_params{'-title'} - $format feed", + '-title' => esc_attr("$project - $href_params{'-title'} - $format feed"), '-type' => "application/$type+xml" ); @@ -3473,13 +3480,13 @@ EOF } else { printf(''."\n", - $site_name, href(project=>undef, action=>"project_index")); + esc_attr($site_name), href(project=>undef, action=>"project_index")); printf(''."\n", - $site_name, href(project=>undef, action=>"opml")); + esc_attr($site_name), href(project=>undef, action=>"opml")); } if (defined $favicon) { - print qq(\n); + print qq(\n); } print "\n" . @@ -3493,7 +3500,7 @@ EOF print "
\n" . $cgi->a({-href => esc_url($logo_url), -title => $logo_label}, - qq()); + qq()); print $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / "; if (defined $project) { print $cgi->a({-href => href(action=>"summary")}, esc_html($project)); @@ -5612,14 +5619,14 @@ sub git_blob { } else { print "
\n" . "

\n" . - "
$hash
\n"; + "
".esc_html($hash)."
\n"; } git_print_page_path($file_name, "blob", $hash_base); print "
\n"; if ($mimetype =~ m!^image/!) { - print qq!$file_name$hash, @@ -5694,7 +5701,7 @@ sub git_tree { undef $hash_base; print "
\n"; print "

\n"; - print "
$hash
\n"; + print "
".esc_html($hash)."
\n"; } if (defined $file_name) { $basedir = $file_name; @@ -6162,7 +6169,7 @@ sub git_blobdiff { git_print_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "

$formats_nav
\n"; - print "
$hash vs $hash_parent
\n"; + print "
".esc_html("$hash vs $hash_parent")."
\n"; } if (defined $file_name) { git_print_page_path($file_name, "blob", $hash_base); -- 1.7.2.3