diff mbox series

[v6,2/5] Documentation: define protected configuration

Message ID 43627c05c0b997ea407c865b04994cba630297d6.1656612839.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series config: introduce discovery.bare and protected config | expand

Commit Message

Glen Choo June 30, 2022, 6:13 p.m. UTC
From: Glen Choo <chooglen@google.com>

For security reasons, there are config variables that are only trusted
when they are specified in certain configuration scopes, which are
sometimes referred to on-list as 'protected configuration' [1]. A future
commit will introduce another such variable, so let's define our terms
so that we can have consistent documentation and implementation.

In our documentation, define 'protected configuration' as the system,
global and command config scopes. As a shorthand, I will refer to
variables that are only respected in protected config as 'protected
configuration only', but this term is not used in the documentation.

This definition of protected config is based on whether or not Git can
reasonably protect the user by ignoring the configuration scope:

- System, global and command line config are considered protected
  because an attacker who has control over any of those can do plenty of
  harm without Git, so we gain very little by ignoring those scopes.
- On the other hand, local (and similarly, worktree) config are not
  considered protected because it is relatively easy for an attacker to
  control local config, e.g.:
  - On some shared user environments, a non-admin attacker can create a
    repository high up the directory hierarchy (e.g. C:\.git on
    Windows), and a user may accidentally use it when their PS1
    automatically invokes "git" commands.

    `safe.directory` prevents attacks of this form by making sure that
    the user intended to use the shared repository. It obviously
    shouldn't be read from the repository, because that would end up
    trusting the repository that Git was supposed to reject.
  - "git upload-pack" is expected to run in repositories that may not be
    controlled by the user. We cannot ignore all config in that
    repository (because "git upload-pack" would fail), but we can limit
    the risks by ignoring `uploadpack.packObjectsHook`.

Only `uploadpack.packObjectsHook` is 'protected configuration only'. The
following variables are intentionally excluded:

- `safe.directory` should be 'protected configuration only', but it does
  not technically fit the definition because it is not respected in the
  "command" scope. A future commit will fix this.

- `trace2.*` happens to read the same scopes as `safe.directory` because
  they share an implementation. However, this is not for security
  reasons; it is because we want to start tracing so early that
  repository-level config and "-c" are not available [2].

  This requirement is unique to `trace2.*`, so it does not makes sense
  for protected configuration to be subject to the same constraints.

[1] For example,
https://lore.kernel.org/git/6af83767-576b-75c4-c778-0284344a8fe7@github.com/
[2] https://lore.kernel.org/git/a0c89d0d-669e-bf56-25d2-cbb09b012e70@jeffhostetler.com/

Signed-off-by: Glen Choo <chooglen@google.com>
---
 Documentation/config/uploadpack.txt |  6 +++---
 Documentation/git-config.txt        | 13 +++++++++++++
 2 files changed, 16 insertions(+), 3 deletions(-)

Comments

Taylor Blau June 30, 2022, 11:49 p.m. UTC | #1
On Thu, Jun 30, 2022 at 06:13:56PM +0000, Glen Choo via GitGitGadget wrote:
> @@ -380,6 +381,18 @@ Most configuration options are respected regardless of the scope it is
>  defined in, but some options are only respected in certain scopes. See the
>  option's documentation for the full details.
>
> +Protected configuration
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Protected configuration refers to the 'system', 'global', and 'command' scopes.
> +For security reasons, certain options are only respected when they are
> +specified in protected configuration, and ignored otherwise.
> +
> +Git treats these scopes as if they are controlled by the user or a trusted
> +administrator. This is because an attacker who controls these scopes can do
> +substantial harm without using Git, so it is assumed that the user's environment
> +protects these scopes against attackers.
> +

I think this description is a good starting point, but I think I would
have liked to see some more from the commit description make it into the
documentation here.

One thing that I didn't see mentioned in either is that the list of
protected configuration is far from exhaustive. There are dozens upon
dozens of configuration values that Git will happily execute as a
subprocess (core.editor, core.pager, core.alternateRefsCommand, to name
just a few).

I don't think we should try and enumerate every possible path from
configuration to command execution. But it is worth noting in the
documentation that the list of configuration values which are only read
in the protected context is non-exhaustive and best-effort only.

Thanks,
Taylor
Glen Choo July 6, 2022, 6:21 p.m. UTC | #2
Taylor Blau <me@ttaylorr.com> writes:

> On Thu, Jun 30, 2022 at 06:13:56PM +0000, Glen Choo via GitGitGadget wrote:
>> @@ -380,6 +381,18 @@ Most configuration options are respected regardless of the scope it is
>>  defined in, but some options are only respected in certain scopes. See the
>>  option's documentation for the full details.
>>
>> +Protected configuration
>> +~~~~~~~~~~~~~~~~~~~~~~~
>> +
>> +Protected configuration refers to the 'system', 'global', and 'command' scopes.
>> +For security reasons, certain options are only respected when they are
>> +specified in protected configuration, and ignored otherwise.
>> +
>> +Git treats these scopes as if they are controlled by the user or a trusted
>> +administrator. This is because an attacker who controls these scopes can do
>> +substantial harm without using Git, so it is assumed that the user's environment
>> +protects these scopes against attackers.
>> +
>
> I think this description is a good starting point, but I think I would
> have liked to see some more from the commit description make it into the
> documentation here.

Yeah, there's a bit of a tradeoff here. Glossing over some of the
details helps keep the documentation briefer and easier to understand
for the less experienced/invested, but is bound to frustrate others. I'd
appreciate any wording suggestions if you have any.

> One thing that I didn't see mentioned in either is that the list of
> protected configuration is far from exhaustive. There are dozens upon
> dozens of configuration values that Git will happily execute as a
> subprocess (core.editor, core.pager, core.alternateRefsCommand, to name
> just a few).
>
> I don't think we should try and enumerate every possible path from
> configuration to command execution. But it is worth noting in the
> documentation that the list of configuration values which are only read
> in the protected context is non-exhaustive and best-effort only.

By referencing command execution, I think you are alluding to Stolee's
Security Boundary discussion thread [1], and in particular, the "Example
Security Boundary Question: Unprotected Config and Executing Code"
section?

That section discusses the problem of arbitrary command execution based
on repository-local config, and how protected configuration might give
us a way to prevent that. That's a reasonable extension to this series,
though it seems a little premature to include allusions to command
execution, especially since I don't think we're anywhere close to a
long-term direction on what should/shouldn't be inside protected
configuration. For example, Stolee noted that, most of the command
execution options really do want per-repository customization, so if we
want to continue to support that, we'll need to use protected
configuration in a somewhat sophisticated manner (and not, e.g. only
respect command execution options in protected configuration). Perhaps
we could shelve this wording change until we've committed to such a
direction.

[1] https://lore.kernel.org/git/6af83767-576b-75c4-c778-0284344a8fe7@github.com

> Thanks,
> Taylor
diff mbox series

Patch

diff --git a/Documentation/config/uploadpack.txt b/Documentation/config/uploadpack.txt
index 32fad5bbe81..029abbefdff 100644
--- a/Documentation/config/uploadpack.txt
+++ b/Documentation/config/uploadpack.txt
@@ -49,9 +49,9 @@  uploadpack.packObjectsHook::
 	`pack-objects` to the hook, and expects a completed packfile on
 	stdout.
 +
-Note that this configuration variable is ignored if it is seen in the
-repository-level config (this is a safety measure against fetching from
-untrusted repositories).
+Note that this configuration variable is only respected when it is specified
+in protected config (see <<SCOPES>>). This is a safety measure against
+fetching from untrusted repositories.
 
 uploadpack.allowFilter::
 	If this option is set, `upload-pack` will support partial
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index f93d437b898..f1810952891 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -343,6 +343,7 @@  You can change the way options are read/written by specifying the path to a
 file (`--file`), or by specifying a configuration scope (`--system`,
 `--global`, `--local`, `--worktree`); see <<OPTIONS>> above.
 
+[[SCOPES]]
 SCOPES
 ------
 
@@ -380,6 +381,18 @@  Most configuration options are respected regardless of the scope it is
 defined in, but some options are only respected in certain scopes. See the
 option's documentation for the full details.
 
+Protected configuration
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Protected configuration refers to the 'system', 'global', and 'command' scopes.
+For security reasons, certain options are only respected when they are
+specified in protected configuration, and ignored otherwise.
+
+Git treats these scopes as if they are controlled by the user or a trusted
+administrator. This is because an attacker who controls these scopes can do
+substantial harm without using Git, so it is assumed that the user's environment
+protects these scopes against attackers.
+
 ENVIRONMENT
 -----------