From a472bf30df3e87991eb92002ffef5386db0620a3 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 7 Feb 2010 13:09:16 +0530 Subject: [PATCH] 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 --- conf/example.conf | 4 ++++ conf/example.gitolite.rc | 26 ++++++++++++++++++++++++++ src/gl-compile-conf | 6 ++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/conf/example.conf b/conf/example.conf index a17161e..01ea6d4 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -236,6 +236,10 @@ gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corpora # 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) # this should be specified within a "repo" stanza diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index ddf5baa..00e6a57 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -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 diff --git a/src/gl-compile-conf b/src/gl-compile-conf index e173a56..6a02107 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -61,7 +61,7 @@ $Data::Dumper::Sortkeys = sub { return [ reverse sort keys %{$_[0]} ]; }; open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q'); # 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 our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN); @@ -288,7 +288,9 @@ sub parse_conf_file elsif (/^config (.+) = ?(.*)/) { 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 { $repo_config{$repo}{$key} = $value;