git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 0/2] setup.c: make bare repo discovery optional

From
Taylor Blau <me@ttaylorr.com>
Date
May 16, 2022, 22:43 UTC
Message-ID
<YoLTqxYU7VO91Dam@nand.local>
In-Reply-To
<5b969c5e-e802-c447-ad25-6acc0b784582@github.com>
On Mon, May 16, 2022 at 03:07:35PM -0400, Derrick Stolee wrote:
Show 10 quoted lines
> On 5/13/2022 7:37 PM, Glen Choo via GitGitGadget wrote:
> > Thanks all for the comments on v1, I've expanded this series somewhat to
> > address them,...
>
> Please include a full cover letter with each version, so reviewers
> can respond to the full series goals.
>
> Your series here intends to start protecting against malicious
> embedded bare repositories by allowing users to opt-in to a more
> protected state. [...]

Thanks for the summary, which I think will be especially helpful to others looking at this series for the very first time.

Show 6 quoted lines
> The 'never' option is a good one for very security-conscious
> users who really want to avoid problems. I don't anticipate that
> users who know about this option and set it themselves are the
> type that would fall for the social engineering required to
> attack using this vector, but I can imagine an IT department
> installing the value in system config across a fleet of machines.

When I first read this, I disagreed, since presumably that same crowd has legitimate bare repositories that they want to continue being able to operate in without having to pass `--git-dir` or `$GIT_DIR` in.

In fact...
> I also think that this protection is too rigid: it restricts
> _all_ bare repositories, not just embedded ones. There is no check
> to see if the parent directory of the bare repository is inside a
> non-bare repository.

...this resonates quite a bit more with me. "never" isn't a good option unless you aren't a user of bare repositories _and_ don't have any embedded bare repositories (either at all, or any ones that you trust).

Show 20 quoted lines
> This leads to what I think would be a valuable replacement for
> the 'cwd' option:
>
> * 'no-embedded' allows non-embedded bare repositories. An
>   _embedded bare repository_ is a bare repository whose parent
>   directory is contained in the worktree of a non-bare Git
>   repository. When in this mode, embedded bare repositories are
>   not allowed unless the parent non-bare Git repository has a
>   'safe.embedded' config value storing the path to the current
>   embedded bare repository.
>
> That was certainly difficult to write, but here it is as
> pseudo-code to hopefully remove some doubt as to how this might
> work:
>
>   if repo is bare:
>     if value == "always":
>        return ALLOWED
>     if value == "never":
>        return FORBIDDEN;

This is indeed very similar to a proposal I had made upthread (which you note lower down in this email). One thing that's nice is that we only have to traverse up to the parent repo when in the "no-embedded" mode. That may be slow (since it's unbounded all the way up to the filesystem root or a ceiling directory, whichever we encounter first), but I think it's unavoidable if you need to distinguish between embedded and non-embedded bare repositories.

Show 17 quoted lines
>     path = get_parent_repo()
>
>     if !path:
>        return ALLOWED
>
>     if config_file_has_value("{path}/.git/config", "safe.embedded", repo):
>        return ALLOWED
>
>     return FORBIDDEN
>
> With this kind of option, we can protect users from these
> social engineering attacks while providing an opt-in protection
> for scenarios where embedded bare repos are currently being used
> (while also not breaking anyone using non-embedded bare repos).
>
> I think Taylor was mentioning something like this in his previous
> replies, perhaps even to the previous thread on this topic.
Yep, see: https://lore.kernel.org/git/Ylobp7sntKeWTLDX@nand.local/.a
> This 'no-embedded' option is something that I could see as a
> potential new default, after it has proven itself in a released
> version of Git.

I would be totally happy to see "no-embedded" become the default. It might be nice to issue a warning when the top-level config is unset, to give users a heads up about cases that may be broken, perhaps like:

    if repo is bare:
      switch (value) {
      case "always":
        return ALLOWED;
      case "never":
        return FORBIDDEN;
      case "no-embedded": # fallthrough
      case "":
        path = get_parent_repo()
        if !path
          return ALLOWED;
        if config_file_has_value("{path}/.git/config", "safe.embedded", repo)
          return ALLOWED;
        if value == "no-embedded":
          return FORBIDDEN;
        # otherwise, we're in an embedded bare repository with an unset
        # discovery.bare config.
        #
        # warn that this will break in the future...
        warning(_("%s is embedded within %s"), the_repository.path, path);
        advise(_("to allow discovery for this embedded repo, either run"));
        advise(_(""));
        advise(_("  $ git config --global discovery.bare always, or"));
        advise(_("  $ git -C '%s' config --local safe.embedded '%s'"),
               path, relpath(path, the_repository.path));
        # ...but allow the invocation for now until the default is
        # changed.
        return ALLOWED;
      default:
        die(_("unrecognized value of discovery.bare: '%s'"), value);
      }
...where relpath is similar to Go's path/filepath.Rel function.

With an appropriate deprecation period, I think we could even get away from the "continue executing, but don't read config+hooks", which in retrospect is more error-prone and difficult to reason about than I initially had given it credit for.

Thanks, Taylor

Previous: Derrick StoleeNext: Junio C Hamano
Message 24 of 113 in “[RFC] setup.c: make bare repo discovery optional”
  1. [RFC] setup.c: make bare repo discovery optionalGlen Choo via GitGitGadget, May 6, 2022
  2. Junio C HamanoMay 6, 2022
  3. Taylor BlauMay 9, 2022
  4. Junio C HamanoMay 9, 2022
  5. Taylor BlauMay 9, 2022
  6. Junio C HamanoMay 10, 2022
  7. Glen ChooMay 10, 2022
  8. 0/2 setup.c: make bare repo discovery optionalGlen Choo via GitGitGadget, May 13, 2022
  9. 1/2 setup.c: make bare repo discovery optionalGlen Choo via GitGitGadget, May 13, 2022
  10. Glen ChooMay 16, 2022
  11. Derrick StoleeMay 16, 2022
  12. Taylor BlauMay 16, 2022
  13. Glen ChooMay 17, 2022
  14. Glen ChooMay 17, 2022
  15. 2/2 setup.c: learn discovery.bareRepository=cwdGlen Choo via GitGitGadget, May 13, 2022
  16. Derrick StoleeMay 16, 2022
  17. Junio C HamanoMay 16, 2022
  18. Glen ChooMay 16, 2022
  19. Junio C HamanoMay 16, 2022
  20. Glen ChooMay 16, 2022
  21. Junio C HamanoMay 16, 2022
  22. Junio C HamanoMay 16, 2022
  23. Derrick StoleeMay 16, 2022
  24. Taylor BlauMay 16, 2022
  25. Junio C HamanoMay 16, 2022
  26. Glen ChooMay 17, 2022
  27. 0/5 config: introduce discovery.bare and protected configGlen Choo via GitGitGadget, May 27, 2022
  28. 1/5 Documentation: define protected configurationGlen Choo via GitGitGadget, May 27, 2022
  29. Junio C HamanoMay 27, 2022
  30. Derrick StoleeJun 2, 2022
  31. Junio C HamanoJun 2, 2022
  32. Glen ChooJun 2, 2022
  33. Glen ChooJun 3, 2022
  34. 2/5 config: read protected config with `git_protected_config()`Glen Choo via GitGitGadget, May 27, 2022
  35. Junio C HamanoMay 28, 2022
  36. Glen ChooMay 31, 2022
  37. Junio C HamanoJun 1, 2022
  38. Derrick StoleeJun 2, 2022
  39. 3/5 setup.c: create `discovery.bare`Glen Choo via GitGitGadget, May 27, 2022
  40. Junio C HamanoMay 28, 2022
  41. Derrick StoleeJun 2, 2022
  42. 5/5 upload-pack: make uploadpack.packObjectsHook protectedGlen Choo via GitGitGadget, May 27, 2022
  43. Derrick StoleeJun 2, 2022
  44. 4/5 config: include "-c" in protected configGlen Choo via GitGitGadget, May 27, 2022
  45. Derrick StoleeJun 2, 2022
  46. 0/5 config: introduce discovery.bare and protected configGlen Choo via GitGitGadget, Jun 7, 2022
  47. 4/5 safe.directory: use git_protected_config()Glen Choo via GitGitGadget, Jun 7, 2022
  48. 3/5 config: read protected config with `git_protected_config()`Glen Choo via GitGitGadget, Jun 7, 2022
  49. Junio C HamanoJun 7, 2022
  50. Glen ChooJun 8, 2022
  51. 5/5 setup.c: create `discovery.bare`Glen Choo via GitGitGadget, Jun 7, 2022
  52. Glen ChooJun 7, 2022
  53. 2/5 Documentation: define protected configurationGlen Choo via GitGitGadget, Jun 7, 2022
  54. Jonathan TanJun 22, 2022
  55. Glen ChooJun 23, 2022
  56. 1/5 Documentation/git-config.txt: add SCOPES sectionGlen Choo via GitGitGadget, Jun 7, 2022
  57. Jonathan TanJun 22, 2022
  58. Glen ChooJun 23, 2022
  59. Junio C HamanoJun 23, 2022
  60. Glen ChooJun 27, 2022
  61. Glen ChooJun 27, 2022
  62. 0/5 config: introduce discovery.bare and protected configGlen Choo via GitGitGadget, Jun 27, 2022
  63. 2/5 Documentation: define protected configurationGlen Choo via GitGitGadget, Jun 27, 2022
  64. 4/5 safe.directory: use git_protected_config()Glen Choo via GitGitGadget, Jun 27, 2022
  65. 3/5 config: learn `git_protected_config()`Glen Choo via GitGitGadget, Jun 27, 2022
  66. 5/5 setup.c: create `discovery.bare`Glen Choo via GitGitGadget, Jun 27, 2022
  67. Ævar Arnfjörð BjarmasonJun 30, 2022
  68. Glen ChooJun 30, 2022
  69. 1/5 Documentation/git-config.txt: add SCOPES sectionGlen Choo via GitGitGadget, Jun 27, 2022
  70. 0/5 config: introduce discovery.bare and protected configGlen Choo via GitGitGadget, Jun 30, 2022
  71. 1/5 Documentation/git-config.txt: add SCOPES sectionGlen Choo via GitGitGadget, Jun 30, 2022
  72. Taylor BlauJun 30, 2022
  73. Glen ChooJul 6, 2022
  74. 2/5 Documentation: define protected configurationGlen Choo via GitGitGadget, Jun 30, 2022
  75. Taylor BlauJun 30, 2022
  76. Glen ChooJul 6, 2022
  77. 3/5 config: learn `git_protected_config()`Glen Choo via GitGitGadget, Jun 30, 2022
  78. Taylor BlauJul 1, 2022
  79. Glen ChooJul 6, 2022
  80. 4/5 safe.directory: use git_protected_config()Glen Choo via GitGitGadget, Jun 30, 2022
  81. 5/5 setup.c: create `discovery.bare`Glen Choo via GitGitGadget, Jun 30, 2022
  82. Taylor BlauJul 1, 2022
  83. Glen ChooJul 7, 2022
  84. Taylor BlauJun 30, 2022
  85. Ævar Arnfjörð BjarmasonJun 30, 2022
  86. Glen ChooJul 1, 2022
  87. Ævar Arnfjörð BjarmasonJul 8, 2022
  88. Glen ChooJul 12, 2022
  89. Ævar Arnfjörð BjarmasonJul 12, 2022
  90. 0/5 config: introduce discovery.bare and protected configGlen Choo via GitGitGadget, Jul 7, 2022
  91. 1/5 Documentation/git-config.txt: add SCOPES sectionGlen Choo via GitGitGadget, Jul 7, 2022
  92. Junio C HamanoJul 7, 2022
  93. Glen ChooJul 8, 2022
  94. Junio C HamanoJul 8, 2022
  95. Glen ChooJul 8, 2022
  96. 2/5 Documentation: define protected configurationGlen Choo via GitGitGadget, Jul 7, 2022
  97. Junio C HamanoJul 8, 2022
  98. 3/5 config: learn `git_protected_config()`Glen Choo via GitGitGadget, Jul 7, 2022
  99. 4/5 safe.directory: use git_protected_config()Glen Choo via GitGitGadget, Jul 7, 2022
  100. 5/5 setup.c: create `discovery.bare`Glen Choo via GitGitGadget, Jul 7, 2022
  101. Junio C HamanoJul 8, 2022
  102. Glen ChooJul 8, 2022
  103. Glen ChooJul 12, 2022
  104. 0/5 config: introduce safe.bareRepository and protected configGlen Choo via GitGitGadget, Jul 14, 2022
  105. 1/5 Documentation/git-config.txt: add SCOPES sectionGlen Choo via GitGitGadget, Jul 14, 2022
  106. 2/5 Documentation: define protected configurationGlen Choo via GitGitGadget, Jul 14, 2022
  107. 3/5 config: learn `git_protected_config()`Glen Choo via GitGitGadget, Jul 14, 2022
  108. SANITIZE=address failure on master (was: [PATCH v8 3/5] config: learn `git_protected_config()`)Ævar Arnfjörð Bjarmason, Jul 25, 2022
  109. Glen ChooJul 25, 2022
  110. Ævar Arnfjörð BjarmasonJul 25, 2022
  111. Glen ChooJul 25, 2022
  112. 4/5 safe.directory: use git_protected_config()Glen Choo via GitGitGadget, Jul 14, 2022
  113. 5/5 setup.c: create `safe.bareRepository`Glen Choo via GitGitGadget, Jul 14, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.