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

Re: [BUG] git-credential-libsecret writes secret to stdout on store

From
Mantas Mikulėnas <grawity@gmail.com>
Date
Apr 22, 2026, 05:49 UTC
Message-ID
<0b2370ed-f3e1-4011-8a2c-8da539759881@gmail.com>
In-Reply-To
<60cf5f7c-9ccb-4dfe-82e4-9b6e54b3c2c0@wateringcan.de>
(Re-adding list to recipients.)
On 21/04/2026 14.47, Lutz-Christian Quander wrote:
Show 14 quoted lines
> Thanks — fair correction. I tested `git credential approve` with the
> libsecret helper and it does not leak: git discards the helper's
> stdout on `store`, so the documented user-facing interface is safe.
> The leak only manifests when the helper binary is invoked directly.
>
> That narrows the argument, but I'd still submit that the fix is
> worth landing for two reasons:
>
> 1. gitcredentials(7) specifies that helpers should use stderr (not
>    stdout) for messages on `store`/`erase`, and that helper stdout
>    is ignored on those operations. The current unconditional
>    `credential_write()` violates that contract regardless of how the
>    helper is invoked -- it just happens to be harmless when git is
>    the caller because git discards the stream.

The API contract isn't violated IMO, as documenting "output is ignored" gives permission to produce output, even if that output is unnecessary. (that is, from my reading, it implies that output *will* go to /dev/null – and running the helper manually is what really violates the API contract from the other side by not ignoring the helper's output...)

I agree that the unconditional credential_write() is a bit weird upon a closer look – it and the entire main() was just copied as-is from the older "gnomekeyring" helper, under assumption that that was "the expected way" the credential_*() functions were to be used.

Show 11 quoted lines
>
> 2. The direct-invocation pattern shows up widely in distro docs,
>    StackOverflow answers, and automation scripts -- empirically the
>    "internal protocol" boundary is porous. Fixing the helper is one
>    line; documenting the internal boundary across the ecosystem is
>    not.
>
> If the preferred answer is instead "users should only use
> `git credential approve`", that would also work for me, but it may
> deserve a note in gitcredentials(7) to steer people away from the
> direct pattern -- the current docs don't actively discourage it.

I think it should be fixed to remove the useless output, especially if the command is as widely documented as you say (although I'm actually surprised that any CI environments even have a libsecret backend running *in the first place*; I would have assumed that they would use git-credential-cache or something instead). You should send a patch.

At the same time, I also think it's a bit too much 'self-inflicted' of a security issue to be CVE-worthy, so to speak... I mean, I don't like automatically blaming the user for holding it wrong, but in this particular case, I'd like to think that one would test the command on their own machine first and see how it behaves before putting it in a script.

Show 35 quoted lines
>
> Happy with whichever direction you prefer.
>
> Best regards
>
> Lutz-Christian Quander
>
> p.s.
>
> Thank you for your very quick reponse and your Open Source work
>
>
> Am 21.04.26 um 13:37 schrieb Mantas Mikulėnas:
>> On 21/04/2026 14.03, Lutz-Christian Quander wrote:
>>> The documented pattern for seeding credentials non-interactively is:
>>>
>>>     printf "protocol=...\nhost=...\nusername=...\npassword=...\n\n" 
>>> | git-credential-<helper> store
>>>
>>> Running this at a terminal prints the secret into scrollback.
>>> Running it in a shell script whose stdout goes to a log file
>>> persists the secret in that log. Running it in CI captures the
>>> secret in the pipeline artefact. Every real-world use of the
>>> documented pattern is affected.
>>>
>>> Severity is moderate: the leak requires the user to run a legitimate
>>> command -- no attacker-controlled input path -- but the leak happens
>>> on the "correct" documented workflow, silently, with exit code 0.
>>
>> Is it actually the correct documented workflow? I couldn't find it in 
>> the Git docs. My understanding was that writing to "git credential 
>> approve" was the sole user interface, while "git-credential-<helper> 
>> store" was the internal interface between the git-credential builtin 
>> and the helper.
>>
Previous: Mantas MikulėnasNext: Phillip Wood
Message 3 of 4 in “[BUG] git-credential-libsecret writes secret to stdout on store”
  1. Lutz-Christian QuanderApr 21, 2026
  2. Mantas MikulėnasApr 21, 2026
  3. Mantas MikulėnasApr 22, 2026
  4. Phillip WoodApr 22, 2026

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.