Skip to content

lfshttp/certs_darwin: filter CA certs that are only fuzzy matches of CN#6037

Closed
stanhu wants to merge 1 commit intogit-lfs:mainfrom
stanhu:sh-macos-filter-certs
Closed

lfshttp/certs_darwin: filter CA certs that are only fuzzy matches of CN#6037
stanhu wants to merge 1 commit intogit-lfs:mainfrom
stanhu:sh-macos-filter-certs

Conversation

@stanhu
Copy link
Contributor

@stanhu stanhu commented Apr 22, 2025

In our organization (example.org), we use the Jamf endpoint, 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.

Because /usr/bin/security find-certificate does not support exact matches, this commit filters out non-matching CNs to avoid using the wrong cert for the given domain.

Resolves #6036.

@stanhu stanhu requested a review from a team as a code owner April 22, 2025 04:06
@stanhu stanhu force-pushed the sh-macos-filter-certs branch 2 times, most recently from 458ba8a to eaa5a7b Compare April 22, 2025 04:33
stanhu added a commit to stanhu/git-lfs that referenced this pull request Apr 22, 2025
In our organization (`example.org`), we use the Jamf endpoint, 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.

Because `/usr/bin/security find-certificate` does not support exact
matches, this commit filters out non-matching CNs to avoid using the
wrong cert for the given domain.

Closes git-lfs#6037
@stanhu stanhu force-pushed the sh-macos-filter-certs branch from eaa5a7b to 125c1fb Compare April 22, 2025 04:34
stanhu added a commit to stanhu/git-lfs that referenced this pull request Apr 22, 2025
In our organization (`example.org`), we use the Jamf endpoint, 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.

Because `/usr/bin/security find-certificate` does not support exact
matches, this commit filters out non-matching CNs to avoid using the
wrong cert for the given domain.

Closes git-lfs#6037
@stanhu stanhu force-pushed the sh-macos-filter-certs branch from 125c1fb to 2ffdeef Compare April 22, 2025 04:52
stanhu added a commit to stanhu/git-lfs that referenced this pull request Apr 22, 2025
In our organization (`example.org`), we use the Jamf endpoint, 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.

Because `/usr/bin/security find-certificate` does not support exact
matches, this commit filters out non-matching CNs to avoid using the
wrong cert for the given domain.

Closes git-lfs#6037
@stanhu stanhu force-pushed the sh-macos-filter-certs branch from 2ffdeef to 2037b79 Compare April 22, 2025 05:07
stanhu added a commit to stanhu/git-lfs that referenced this pull request Apr 22, 2025
In our organization (`example.org`), we use the Jamf endpoint, 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.

Because `/usr/bin/security find-certificate` does not support exact
matches, this commit filters out non-matching CNs to avoid using the
wrong cert for the given domain.

Closes git-lfs#6037
@stanhu stanhu force-pushed the sh-macos-filter-certs branch 2 times, most recently from 6e78656 to 510ee42 Compare April 22, 2025 05:09
@stanhu stanhu changed the title lfshttp/certs_darwin: filter certs that do not match CN of hostname lfshttp/certs_darwin: filter certs that are only fuzzy matches of CN Apr 22, 2025
In our organization (`example.org`), we use the Jamf endpoint, 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.

Because `/usr/bin/security find-certificate` does not support exact
matches, this commit filters out non-matching CNs to avoid using the
wrong cert for the given domain.

Closes git-lfs#6036
@stanhu stanhu force-pushed the sh-macos-filter-certs branch from 510ee42 to f941108 Compare April 22, 2025 05:10
@stanhu stanhu changed the title lfshttp/certs_darwin: filter certs that are only fuzzy matches of CN lfshttp/certs_darwin: filter CA certs that are only fuzzy matches of CN Apr 22, 2025
// but not an exact match (like "example.com JSS Built-in Certificate Authority")
if cert.IsCA &&
strings.Contains(cert.Subject.CommonName, hostname) &&
!strings.EqualFold(cert.Subject.CommonName, hostname) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this is problematic if you happen to have a TLS cert that requires this bundle:

  1. example.org
  2. example.org Intermediate CA
  3. example.org Root CA

It's possible all three certs are needed here? I guess this is really a problem with /usr/bin/security find-certificate not doing exact matching, or these intermediate certificates having a misleading CN?

@chrisd8088
Copy link
Member

Hey, thanks for this pull request and the description of the issue it is designed to address! We really appreciate contributions like these which include tests and a thorough explanation of how the changes are intended to operate.

I'll aim to take a closer look as soon as possible, with the caveat that it might take me a little while before I can give this the careful review it deserves.

Thank you again very much for this PR!

@stanhu
Copy link
Contributor Author

stanhu commented May 5, 2025

Closing in favor of #6049.

@stanhu stanhu closed this May 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants