Skip to content

darwin: Git LFS improperly adds certificates that cause SSL validation to fail #6036

@stanhu

Description

@stanhu

Describe the bug

In our organization (example.org), we use the Jamf endpoint management system, which adds a self-signed SSL certificate with the CN:

CN=example.org JSS Built-in Certificate Authority

This causes SSL validation to fail when accessing Git LFS on example.org:

Post "https://example.org/group/project/info/lfs/locks/verify": x509: certificate signed by unknown authority

This is happening because:

  1. When accessing example.org endpoints, Git LFS checks if there are any custom certificates to trust for that host.
  2. It calls appendRootCAsForHostFromKeychain with the hostname example.org.
  3. This function executes /usr/bin/security find-certificate -a -p -c example.org <keychain>, which performs a substring match on the Common Name.
  4. If the System keychain contains a certificate with CN example.org JSS Built-in Certificate Authority, this gets returned by the fuzzy match.
  5. Git LFS then adds this CA certificate to the trust store for connections to example.org.
  6. When connecting to the real example.org, Git LFS is now trying to validate the official TLS certificate against this self-signed JAMF CA certificate, which will always fail.

To Reproduce

Steps to reproduce the behavior:

  1. Install a self-signed cert that has a matching Git LFS server hostname in the CN.
  2. Attempt to pull or push LFS files.

System environment

macOS

Output of git lfs env

git-lfs/3.6.1 (GitHub; darwin arm64; go 1.23.4)
git version 2.49.0

Endpoint=https://github.com/git-lfs/git-lfs.git/info/lfs (auth=none)
LocalWorkingDir=/Users/stanhu/github/git-lfs
LocalGitDir=/Users/stanhu/github/git-lfs/.git
LocalGitStorageDir=/Users/stanhu/github/git-lfs/.git
LocalMediaDir=/Users/stanhu/github/git-lfs/.git/lfs/objects
LocalReferenceDirs=
TempDir=/Users/stanhu/github/git-lfs/.git/lfs/tmp
ConcurrentTransfers=8
TusTransfers=false
BasicTransfersOnly=false
SkipDownloadErrors=false
FetchRecentAlways=false
FetchRecentRefsDays=7
FetchRecentCommitsDays=0
FetchRecentRefsIncludeRemotes=true
PruneOffsetDays=3
PruneVerifyRemoteAlways=false
PruneVerifyUnreachableAlways=false
PruneRemoteName=origin
LfsStorageDir=/Users/stanhu/github/git-lfs/.git/lfs
AccessDownload=none
AccessUpload=none
DownloadTransfers=basic,lfs-standalone-file,ssh
UploadTransfers=basic,lfs-standalone-file,ssh
GIT_APPEND_BUILD_OPTIONS=LIBPCREDIR=/opt/homebrew/opt/pcre2
GIT_EXEC_PATH=/opt/homebrew/opt/git/libexec/git-core
git config filter.lfs.process = "git-lfs filter-process"
git config filter.lfs.smudge = "git-lfs smudge -- %f"
git config filter.lfs.clean = "git-lfs clean -- %f"

Additional context

It isn't possible to make security find-certificate return a strict match, but we can make the Git LFS code perform filtering: #6037

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions