File: 0010-CVE-2010-3906.diff

package info (click to toggle)
git-core 1%3A1.5.6.5-3%2Blenny3.3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 12,112 kB
  • ctags: 8,762
  • sloc: ansic: 76,755; sh: 43,148; perl: 18,864; tcl: 16,366; python: 2,820; makefile: 1,889; lisp: 1,793; asm: 220
file content (151 lines) | stat: -rw-r--r-- 5,900 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
From 9b177cb2455c30aef3ff88100372cb55c7b0595d Mon Sep 17 00:00:00 2001
From: Jakub Narebski <jnareb@gmail.com>
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 <e.gentili@tigersecurity.it>
Helped-by: John 'Warthog9' Hawley <warthog9@kernel.org>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
(cherry picked from commit 3017ed62f47ce14a959e2d315c434d4980cf4243)
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 gitweb/gitweb.perl |   35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f88ce35..6dc9a6a 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -730,6 +730,13 @@ sub esc_url {
 	return $str;
 }
 
+# quote unsafe characters in HTML attributes
+sub esc_attr {
+
+	# for XHTML conformance escaping '"' to '&quot;' is not enough
+	return esc_html(@_);
+}
+
 # replace invalid utf8 character with SUBSTITUTION sequence
 sub esc_html ($;%) {
 	my $str = shift;
@@ -1106,7 +1113,7 @@ sub format_ref_marker {
 				$name = $ref;
 			}
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
+			$markers .= " <span class=\"".esc_attr($type)."\" title=\"".esc_attr($ref)."\">" .
 			            esc_html($name) . "</span>";
 		}
 	}
@@ -2517,11 +2524,11 @@ EOF
 # print out each stylesheet that exist
 	if (defined $stylesheet) {
 #provides backwards capability for those people who define style sheet in a config file
-		print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
+		print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
 	} else {
 		foreach my $stylesheet (@stylesheets) {
 			next unless $stylesheet;
-			print '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'"/>'."\n";
+			print '<link rel="stylesheet" type="text/css" href="'.esc_url($stylesheet).'"/>'."\n";
 		}
 	}
 	if (defined $project) {
@@ -2534,7 +2541,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"
 			);
 
@@ -2561,13 +2568,13 @@ EOF
 	} else {
 		printf('<link rel="alternate" title="%s projects list" '.
 		       'href="%s" type="text/plain; charset=utf-8" />'."\n",
-		       $site_name, href(project=>undef, action=>"project_index"));
+		       esc_attr($site_name), href(project=>undef, action=>"project_index"));
 		printf('<link rel="alternate" title="%s projects feeds" '.
 		       'href="%s" type="text/x-opml" />'."\n",
-		       $site_name, href(project=>undef, action=>"opml"));
+		       esc_attr($site_name), href(project=>undef, action=>"opml"));
 	}
 	if (defined $favicon) {
-		print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
+		print qq(<link rel="shortcut icon" href=").esc_url($favicon).qq(" type="image/png" />\n);
 	}
 
 	print "</head>\n" .
@@ -2582,7 +2589,7 @@ EOF
 	print "<div class=\"page_header\">\n" .
 	      $cgi->a({-href => esc_url($logo_url),
 	               -title => $logo_label},
-	              qq(<img src="$logo" width="72" height="27" alt="git" class="logo"/>));
+	              qq(<img src=").esc_url($logo).qq(" width="72" height="27" alt="git" class="logo"/>));
 	print $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / ";
 	if (defined $project) {
 		print $cgi->a({-href => href(action=>"summary")}, esc_html($project));
@@ -4287,7 +4294,7 @@ HTML
 			$lineno   = $4;
 			$data     = $5;
 		} else {
-			print qq(  <tr><td colspan="5" class="error">Unable to parse: $line</td></tr>\n);
+			print qq(  <tr><td colspan="5" class="error">Unable to parse: ).esc_html($line).qq(</td></tr>\n);
 			next;
 		}
 		$short_rev  = substr ($long_rev, 0, 8);
@@ -4444,14 +4451,14 @@ sub git_blob {
 	} else {
 		print "<div class=\"page_nav\">\n" .
 		      "<br/><br/></div>\n" .
-		      "<div class=\"title\">$hash</div>\n";
+		      "<div class=\"title\">".esc_html($hash)."</div>\n";
 	}
 	git_print_page_path($file_name, "blob", $hash_base);
 	print "<div class=\"page_body\">\n";
 	if ($mimetype =~ m!^image/!) {
-		print qq!<img type="$mimetype"!;
+		print qq!<img type="!.esc_attr($mimetype).qq!"!;
 		if ($file_name) {
-			print qq! alt="$file_name" title="$file_name"!;
+			print qq! alt="!.esc_attr($file_name).qq!" title="!.esc_attr($file_name).qq!"!;
 		}
 		print qq! src="! .
 		      href(action=>"blob_plain", hash=>$hash,
@@ -4517,7 +4524,7 @@ sub git_tree {
 		undef $hash_base;
 		print "<div class=\"page_nav\">\n";
 		print "<br/><br/></div>\n";
-		print "<div class=\"title\">$hash</div>\n";
+		print "<div class=\"title\">".esc_html($hash)."</div>\n";
 	}
 	if (defined $file_name) {
 		$basedir = $file_name;
@@ -4942,7 +4949,7 @@ sub git_blobdiff {
 			git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 		} else {
 			print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n";
-			print "<div class=\"title\">$hash vs $hash_parent</div>\n";
+			print "<div class=\"title\">".esc_html("$hash vs $hash_parent")."</div>\n";
 		}
 		if (defined $file_name) {
 			git_print_page_path($file_name, "blob", $hash_base);
-- 
1.7.4.rc2