Skip to content

Commit 3017ed6

Browse files
jnarebgitster
authored andcommitted
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 <[email protected]> Helped-by: John 'Warthog9' Hawley <[email protected]> Helped-by: Jonathan Nieder <[email protected]> Signed-off-by: Jakub Narebski <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1b0b962 commit 3017ed6

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

gitweb/gitweb.perl

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,13 @@ sub esc_url {
10841084
return $str;
10851085
}
10861086

1087+
# quote unsafe characters in HTML attributes
1088+
sub esc_attr {
1089+
1090+
# for XHTML conformance escaping '"' to '&quot;' is not enough
1091+
return esc_html(@_);
1092+
}
1093+
10871094
# replace invalid utf8 character with SUBSTITUTION sequence
10881095
sub esc_html {
10891096
my $str = shift;
@@ -1489,7 +1496,7 @@ sub format_ref_marker {
14891496
hash=>$dest
14901497
)}, $name);
14911498

1492-
$markers .= " <span class=\"$class\" title=\"$ref\">" .
1499+
$markers .= " <span class=\"".esc_attr($class)."\" title=\"".esc_attr($ref)."\">" .
14931500
$link . "</span>";
14941501
}
14951502
}
@@ -1573,7 +1580,7 @@ sub git_get_avatar {
15731580
return $pre_white .
15741581
"<img width=\"$size\" " .
15751582
"class=\"avatar\" " .
1576-
"src=\"$url\" " .
1583+
"src=\"".esc_url($url)."\" " .
15771584
"alt=\"\" " .
15781585
"/>" . $post_white;
15791586
} else {
@@ -2245,7 +2252,7 @@ sub git_show_project_tagcloud {
22452252
} else {
22462253
my @tags = sort { $cloud->{$a}->{count} <=> $cloud->{$b}->{count} } keys %$cloud;
22472254
return '<p align="center">' . join (', ', map {
2248-
"<a href=\"$home_link?by_tag=$_\">$cloud->{$_}->{topname}</a>"
2255+
$cgi->a({-href=>"$home_link?by_tag=$_"}, $cloud->{$_}->{topname})
22492256
} splice(@tags, 0, $count)) . '</p>';
22502257
}
22512258
}
@@ -3061,11 +3068,11 @@ sub git_header_html {
30613068
# print out each stylesheet that exist, providing backwards capability
30623069
# for those people who defined $stylesheet in a config file
30633070
if (defined $stylesheet) {
3064-
print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
3071+
print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
30653072
} else {
30663073
foreach my $stylesheet (@stylesheets) {
30673074
next unless $stylesheet;
3068-
print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
3075+
print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
30693076
}
30703077
}
30713078
if (defined $project) {
@@ -3078,7 +3085,7 @@ sub git_header_html {
30783085
my $type = lc($format);
30793086
my %link_attr = (
30803087
'-rel' => 'alternate',
3081-
'-title' => "$project - $href_params{'-title'} - $format feed",
3088+
'-title' => esc_attr("$project - $href_params{'-title'} - $format feed"),
30823089
'-type' => "application/$type+xml"
30833090
);
30843091

@@ -3105,13 +3112,13 @@ sub git_header_html {
31053112
} else {
31063113
printf('<link rel="alternate" title="%s projects list" '.
31073114
'href="%s" type="text/plain; charset=utf-8" />'."\n",
3108-
$site_name, href(project=>undef, action=>"project_index"));
3115+
esc_attr($site_name), href(project=>undef, action=>"project_index"));
31093116
printf('<link rel="alternate" title="%s projects feeds" '.
31103117
'href="%s" type="text/x-opml" />'."\n",
3111-
$site_name, href(project=>undef, action=>"opml"));
3118+
esc_attr($site_name), href(project=>undef, action=>"opml"));
31123119
}
31133120
if (defined $favicon) {
3114-
print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
3121+
print qq(<link rel="shortcut icon" href=").esc_url($favicon).qq(" type="image/png" />\n);
31153122
}
31163123

31173124
print "</head>\n" .
@@ -3124,7 +3131,7 @@ sub git_header_html {
31243131
print "<div class=\"page_header\">\n" .
31253132
$cgi->a({-href => esc_url($logo_url),
31263133
-title => $logo_label},
3127-
qq(<img src="$logo" width="72" height="27" alt="git" class="logo"/>));
3134+
qq(<img src=").esc_url($logo).qq(" width="72" height="27" alt="git" class="logo"/>));
31283135
print $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / ";
31293136
if (defined $project) {
31303137
print $cgi->a({-href => href(action=>"summary")}, esc_html($project));
@@ -5016,14 +5023,14 @@ sub git_blob {
50165023
} else {
50175024
print "<div class=\"page_nav\">\n" .
50185025
"<br/><br/></div>\n" .
5019-
"<div class=\"title\">$hash</div>\n";
5026+
"<div class=\"title\">".esc_html($hash)."</div>\n";
50205027
}
50215028
git_print_page_path($file_name, "blob", $hash_base);
50225029
print "<div class=\"page_body\">\n";
50235030
if ($mimetype =~ m!^image/!) {
5024-
print qq!<img type="$mimetype"!;
5031+
print qq!<img type="!.esc_attr($mimetype).qq!"!;
50255032
if ($file_name) {
5026-
print qq! alt="$file_name" title="$file_name"!;
5033+
print qq! alt="!.esc_attr($file_name).qq!" title="!.esc_attr($file_name).qq!"!;
50275034
}
50285035
print qq! src="! .
50295036
href(action=>"blob_plain", hash=>$hash,
@@ -5094,7 +5101,7 @@ sub git_tree {
50945101
undef $hash_base;
50955102
print "<div class=\"page_nav\">\n";
50965103
print "<br/><br/></div>\n";
5097-
print "<div class=\"title\">$hash</div>\n";
5104+
print "<div class=\"title\">".esc_html($hash)."</div>\n";
50985105
}
50995106
if (defined $file_name) {
51005107
$basedir = $file_name;
@@ -5511,7 +5518,7 @@ sub git_blobdiff {
55115518
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
55125519
} else {
55135520
print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
5514-
print "<div class=\"title\">$hash vs $hash_parent</div>\n";
5521+
print "<div class=\"title\">".esc_html("$hash vs $hash_parent")."</div>\n";
55155522
}
55165523
if (defined $file_name) {
55175524
git_print_page_path($file_name, "blob", $hash_base);

0 commit comments

Comments
 (0)