compile: tighten up the 'git config' feature

Gitolite allows you to set git repo options using the "config" keyword;
see conf/example.conf for details and syntax.

However, if you are in an installation where the repo admin does not
(and should not) have shell access to the server, then allowing him to
set arbitrary repo config options *may* be a security risk -- some
config settings may allow executing arbitrary commands.

This patch fixes it, introducing a new RC variable to control the
behaviour.  See conf/example.gitolite.rc for details
This commit is contained in:
Sitaram Chamarty 2010-02-07 13:09:16 +05:30
parent b299ff09c3
commit a472bf30df
3 changed files with 34 additions and 2 deletions

View file

@ -236,6 +236,10 @@ gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corpora
# REPO SPECIFIC GITCONFIG # REPO SPECIFIC GITCONFIG
# ----------------------- # -----------------------
# update 2010-02-06; this won't work unless the rc file has the right
# settings; please see comments around the variable $GL_GITCONFIG_KEYS in
# conf/example.gitolite.rc for details and security information.
# (Thanks to teemu dot matilainen at iki dot fi) # (Thanks to teemu dot matilainen at iki dot fi)
# this should be specified within a "repo" stanza # this should be specified within a "repo" stanza

View file

@ -122,6 +122,32 @@ $GIT_PATH="";
# --------------------------------------
# ALLOW REPO ADMIN TO SET GITCONFIG KEYS
#
# Gitolite allows you to set git repo options using the "config" keyword; see
# conf/example.conf for details and syntax.
#
# However, if you are in an installation where the repo admin does not (and
# should not) have shell access to the server, then allowing him to set
# arbitrary repo config options *may* be a security risk -- some config
# settings may allow executing arbitrary commands.
#
# You have 3 choices. By default $GL_GITCONFIG_KEYS is left undefined, which
# completely disables this feature (meaning you cannot set git configs from
# the repo config).
#
# The second choice is to give it a space separated list of settings you
# consider safe. (These are actually treated as a set of regular expression
# patterns, and any one of them must match). For example:
# $GL_GITCONFIG_KEYS = "core\.logAllRefUpdates core\..*compression";
# allows repo admins to set one of those 3 config keys (yes, that second
# pattern matches two settings from "man git-config", if you look)
#
# The third choice (which you may have guessed already if you're familiar with
# regular expressions) is to allow anything and everything:
# $GL_GITCONFIG_KEYS = ".*";
# -------------------------------------- # --------------------------------------
# EXTERNAL COMMAND HELPER -- HTPASSWD # EXTERNAL COMMAND HELPER -- HTPASSWD

View file

@ -61,7 +61,7 @@ $Data::Dumper::Sortkeys = sub { return [ reverse sort keys %{$_[0]} ]; };
open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q'); open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q');
# these are set by the "rc" file # these are set by the "rc" file
our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $SHELL_USERS, $GL_WILDREPOS); our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $SHELL_USERS, $GL_WILDREPOS, $GL_GITCONFIG_KEYS);
# and these are set by gitolite.pm # and these are set by gitolite.pm
our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN); our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN);
@ -288,7 +288,9 @@ sub parse_conf_file
elsif (/^config (.+) = ?(.*)/) elsif (/^config (.+) = ?(.*)/)
{ {
my ($key, $value) = ($1, $2); my ($key, $value) = ($1, $2);
die "$WARN $fragment attempting to set repo configuration\n" if $fragment ne 'master'; my @validkeys = split (' ', ($GL_GITCONFIG_KEYS || ''));
my @matched = grep { $key =~ /^$_$/ } @validkeys;
die "$ABRT git config $key not allowed\n" if (@matched < 1);
for my $repo (@repos) # each repo in the current stanza for my $repo (@repos) # each repo in the current stanza
{ {
$repo_config{$repo}{$key} = $value; $repo_config{$repo}{$key} = $value;