gitweb: add $prevent_xss option to prevent XSS by repository content

Add a gitweb configuration variable $prevent_xss that disables features
to prevent content in repositories from launching cross-site scripting
(XSS) attacks in the gitweb domain.  Currently, this option makes gitweb
ignore README.html (a better solution may be worked out in the future)
and serve a blob_plain file of an untrusted type with
"Content-Disposition: attachment", which tells the browser not to show
the file at its original URL.

The XSS prevention is currently off by default.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Matt McCutchen 2009-02-07 19:00:09 -05:00 committed by Junio C Hamano
parent 6e46cc0d92
commit 7e1100e9e9
2 changed files with 27 additions and 3 deletions

View File

@ -214,6 +214,11 @@ not include variables usually directly set during build):
Rename detection options for git-diff and git-diff-tree. By default Rename detection options for git-diff and git-diff-tree. By default
('-M'); set it to ('-C') or ('-C', '-C') to also detect copies, or ('-M'); set it to ('-C') or ('-C', '-C') to also detect copies, or
set it to () if you don't want to have renames detection. set it to () if you don't want to have renames detection.
* $prevent_xss
If true, some gitweb features are disabled to prevent content in
repositories from launching cross-site scripting (XSS) attacks. Set this
to true if you don't trust the content of your repositories. The default
is false.
Projects list file format Projects list file format
@ -260,7 +265,9 @@ You can use the following files in repository:
A .html file (HTML fragment) which is included on the gitweb project A .html file (HTML fragment) which is included on the gitweb project
summary page inside <div> block element. You can use it for longer summary page inside <div> block element. You can use it for longer
description of a project, to provide links (for example to project's description of a project, to provide links (for example to project's
homepage), etc. homepage), etc. This is recognized only if XSS prevention is off
($prevent_xss is false); a way to include a readme safely when XSS
prevention is on may be worked out in the future.
* description (or gitweb.description) * description (or gitweb.description)
Short (shortened by default to 25 characters in the projects list page) Short (shortened by default to 25 characters in the projects list page)
single line description of a project (of a repository). Plain text file; single line description of a project (of a repository). Plain text file;

View File

@ -132,6 +132,10 @@ our $fallback_encoding = 'latin1';
# - one might want to include '-B' option, e.g. '-B', '-M' # - one might want to include '-B' option, e.g. '-B', '-M'
our @diff_opts = ('-M'); # taken from git_commit our @diff_opts = ('-M'); # taken from git_commit
# Disables features that would allow repository owners to inject script into
# the gitweb domain.
our $prevent_xss = 0;
# information about snapshot formats that gitweb is capable of serving # information about snapshot formats that gitweb is capable of serving
our %known_snapshot_formats = ( our %known_snapshot_formats = (
# name => { # name => {
@ -4494,7 +4498,9 @@ sub git_summary {
print "</table>\n"; print "</table>\n";
if (-s "$projectroot/$project/README.html") { # If XSS prevention is on, we don't include README.html.
# TODO: Allow a readme in some safe format.
if (!$prevent_xss && -s "$projectroot/$project/README.html") {
print "<div class=\"title\">readme</div>\n" . print "<div class=\"title\">readme</div>\n" .
"<div class=\"readme\">\n"; "<div class=\"readme\">\n";
insert_file("$projectroot/$project/README.html"); insert_file("$projectroot/$project/README.html");
@ -4739,10 +4745,21 @@ sub git_blob_plain {
$save_as .= '.txt'; $save_as .= '.txt';
} }
# With XSS prevention on, blobs of all types except a few known safe
# ones are served with "Content-Disposition: attachment" to make sure
# they don't run in our security domain. For certain image types,
# blob view writes an <img> tag referring to blob_plain view, and we
# want to be sure not to break that by serving the image as an
# attachment (though Firefox 3 doesn't seem to care).
my $sandbox = $prevent_xss &&
$type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))$!;
print $cgi->header( print $cgi->header(
-type => $type, -type => $type,
-expires => $expires, -expires => $expires,
-content_disposition => 'inline; filename="' . $save_as . '"'); -content_disposition =>
($sandbox ? 'attachment' : 'inline')
. '; filename="' . $save_as . '"');
undef $/; undef $/;
binmode STDOUT, ':raw'; binmode STDOUT, ':raw';
print <$fd>; print <$fd>;