CVE-2026-65625 (GCVE-0-2026-65625)

Vulnerability from cvelistv5 – Published: 2026-10-26 19:52 – Updated: 2026-10-26 19:52
VLAI
Title
Attacker-controlled AES-GCM authentication tag length allows tag forgery in jose
Summary
The pure-Erlang AES-GCM fallback in jose_jwa_aes derives the number of verified authentication tag bits from the attacker-supplied tag itself. In the {aes_gcm, Bits} clause of block_decrypt/4, the incoming tag is guarded only by is_binary/1, with no check on its length. Verification in gcm_block_decrypt/6 then computes TBits = bit_size(T) and compares only those bits of the real 128-bit tag. An attacker who controls a JWE token can truncate the authentication tag to as little as 8 bits, so only 8 bits are ever checked. This reduces forgery resistance from 2^-128 to 2^-8, and a forged ciphertext is reliably accepted as authentic within 256 attempts without knowledge of the key (an authentication tag forgery and integrity bypass). Supplying a tag longer than 128 bits instead causes a badmatch that crashes the decrypting process. The fallback is reached through the public JWE decryption path whenever AES-GCM is not provided by a native crypto NIF, for example on FIPS or stripped or older OTP builds. This issue affects jose: from 1.2.0 before 1.11.13.
CWE
  • CWE-354 - Improper Validation of Integrity Check Value
Assigner
EEF CNA under the mitre root
CNA scorecard A 97/100 over 345 records in the last 180 days details
Impacted products
Vendor Product Version CPE status
potatosalad jose Affected: 1.2.0 , < 1.11.13 (semver)
    cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*
Create a notification for this product.
potatosalad jose Affected: 8848b172575fb7d7e1e2977e8ae0a21678d2157a , < 3fa1f8e3efda0da5ce6f4c9984789f979dc02740 (git)
    cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "jose_jwa_aes"
          ],
          "packageName": "jose",
          "packageURL": "pkg:hex/jose",
          "product": "jose",
          "programFiles": [
            "src/jwa/jose_jwa_aes.erl"
          ],
          "programRoutines": [
            {
              "name": "jose_jwa_aes:block_decrypt/4"
            },
            {
              "name": "jose_jwa_aes:gcm_block_decrypt/6"
            }
          ],
          "repo": "https://github.com/potatosalad/erlang-jose",
          "vendor": "potatosalad",
          "versions": [
            {
              "lessThan": "1.11.13",
              "status": "affected",
              "version": "1.2.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "jose_jwa_aes"
          ],
          "packageName": "potatosalad/erlang-jose",
          "packageURL": "pkg:github/potatosalad/erlang-jose",
          "product": "jose",
          "programFiles": [
            "src/jwa/jose_jwa_aes.erl"
          ],
          "programRoutines": [
            {
              "name": "jose_jwa_aes:block_decrypt/4"
            },
            {
              "name": "jose_jwa_aes:gcm_block_decrypt/6"
            }
          ],
          "repo": "https://github.com/potatosalad/erlang-jose",
          "vendor": "potatosalad",
          "versions": [
            {
              "lessThan": "3fa1f8e3efda0da5ce6f4c9984789f979dc02740",
              "status": "affected",
              "version": "8848b172575fb7d7e1e2977e8ae0a21678d2157a",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThis vulnerability is only exploitable when AES-GCM is handled by the pure-Erlang \u003ccode\u003ejose_jwa_aes\u003c/code\u003e fallback. That fallback is used on deployments where the Erlang/OTP \u003ccode\u003ecrypto\u003c/code\u003e NIF does not expose native AES-GCM (for example FIPS builds, or stripped or older OTP releases). Deployments with a native AES-GCM crypto provider dispatch GCM through \u003ccode\u003ecrypto\u003c/code\u003e and are not affected.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "This vulnerability is only exploitable when AES-GCM is handled by the pure-Erlang `jose_jwa_aes` fallback. That fallback is used on deployments where the Erlang/OTP `crypto` NIF does not expose native AES-GCM (for example FIPS builds, or stripped or older OTP releases). Deployments with a native AES-GCM crypto provider dispatch GCM through `crypto` and are not affected."
            }
          ],
          "value": "This vulnerability is only exploitable when AES-GCM is handled by the pure-Erlang jose_jwa_aes fallback. That fallback is used on deployments where the Erlang/OTP crypto NIF does not expose native AES-GCM (for example FIPS builds, or stripped or older OTP releases). Deployments with a native AES-GCM crypto provider dispatch GCM through crypto and are not affected."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.11.13",
                  "versionStartIncluding": "1.2.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "reporter",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Andrew Bennett"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eThe pure-Erlang AES-GCM fallback in \u003ccode\u003ejose_jwa_aes\u003c/code\u003e derives the number of verified authentication tag bits from the attacker-supplied tag itself. In the \u003ccode\u003e{aes_gcm, Bits}\u003c/code\u003e clause of \u003ccode\u003eblock_decrypt/4\u003c/code\u003e, the incoming tag is guarded only by \u003ccode\u003eis_binary/1\u003c/code\u003e, with no check on its length. Verification in \u003ccode\u003egcm_block_decrypt/6\u003c/code\u003e then computes \u003ccode\u003eTBits = bit_size(T)\u003c/code\u003e and compares only those bits of the real 128-bit tag. An attacker who controls a JWE token can truncate the authentication tag to as little as 8 bits, so only 8 bits are ever checked. This reduces forgery resistance from 2^-128 to 2^-8, and a forged ciphertext is reliably accepted as authentic within 256 attempts without knowledge of the key (an authentication tag forgery and integrity bypass). Supplying a tag longer than 128 bits instead causes a badmatch that crashes the decrypting process. The fallback is reached through the public JWE decryption path whenever AES-GCM is not provided by a native crypto NIF, for example on FIPS or stripped or older OTP builds.\u003c/p\u003e\n\u003cp\u003eThis issue affects jose: from 1.2.0 before 1.11.13.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "The pure-Erlang AES-GCM fallback in `jose_jwa_aes` derives the number of verified authentication tag bits from the attacker-supplied tag itself. In the `{aes_gcm, Bits}` clause of `block_decrypt/4`, the incoming tag is guarded only by `is_binary/1`, with no check on its length. Verification in `gcm_block_decrypt/6` then computes `TBits = bit_size(T)` and compares only those bits of the real 128-bit tag. An attacker who controls a JWE token can truncate the authentication tag to as little as 8 bits, so only 8 bits are ever checked. This reduces forgery resistance from 2^-128 to 2^-8, and a forged ciphertext is reliably accepted as authentic within 256 attempts without knowledge of the key (an authentication tag forgery and integrity bypass). Supplying a tag longer than 128 bits instead causes a badmatch that crashes the decrypting process. The fallback is reached through the public JWE decryption path whenever AES-GCM is not provided by a native crypto NIF, for example on FIPS or stripped or older OTP builds.\n\nThis issue affects jose: from 1.2.0 before 1.11.13."
            }
          ],
          "value": "The pure-Erlang AES-GCM fallback in jose_jwa_aes derives the number of verified authentication tag bits from the attacker-supplied tag itself. In the {aes_gcm, Bits} clause of block_decrypt/4, the incoming tag is guarded only by is_binary/1, with no check on its length. Verification in gcm_block_decrypt/6 then computes TBits = bit_size(T) and compares only those bits of the real 128-bit tag. An attacker who controls a JWE token can truncate the authentication tag to as little as 8 bits, so only 8 bits are ever checked. This reduces forgery resistance from 2^-128 to 2^-8, and a forged ciphertext is reliably accepted as authentic within 256 attempts without knowledge of the key (an authentication tag forgery and integrity bypass). Supplying a tag longer than 128 bits instead causes a badmatch that crashes the decrypting process. The fallback is reached through the public JWE decryption path whenever AES-GCM is not provided by a native crypto NIF, for example on FIPS or stripped or older OTP builds.\n\nThis issue affects jose: from 1.2.0 before 1.11.13."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-475",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-475 Signature Spoofing by Improper Validation"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "PRESENT",
            "attackVector": "LOCAL",
            "baseScore": 5.9,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "LOW",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "HIGH",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-354",
              "description": "CWE-354 Improper Validation of Integrity Check Value",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-26T19:52:54.987Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/potatosalad/erlang-jose/security/advisories/GHSA-6gxw-6f7r-cjr6"
        },
        {
          "name": "EEF CNA record for CVE-2026-65625",
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-65625.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-65625",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-65625"
        },
        {
          "name": "Introducing commit 8848b17 in potatosalad/erlang-jose",
          "tags": [
            "related"
          ],
          "url": "https://github.com/potatosalad/erlang-jose/commit/8848b172575fb7d7e1e2977e8ae0a21678d2157a"
        },
        {
          "name": "Fix commit 3fa1f8e in potatosalad/erlang-jose",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/potatosalad/erlang-jose/commit/3fa1f8e3efda0da5ce6f4c9984789f979dc02740"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Attacker-controlled AES-GCM authentication tag length allows tag forgery in jose",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eEnsure the runtime provides a crypto provider with native AES-GCM support (a standard Erlang/OTP build linked against OpenSSL) so that JOSE dispatches AES-GCM to the native \u003ccode\u003ecrypto\u003c/code\u003e NIF instead of the \u003ccode\u003ejose_jwa_aes\u003c/code\u003e fallback.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Ensure the runtime provides a crypto provider with native AES-GCM support (a standard Erlang/OTP build linked against OpenSSL) so that JOSE dispatches AES-GCM to the native `crypto` NIF instead of the `jose_jwa_aes` fallback."
            }
          ],
          "value": "Ensure the runtime provides a crypto provider with native AES-GCM support (a standard Erlang/OTP build linked against OpenSSL) so that JOSE dispatches AES-GCM to the native crypto NIF instead of the jose_jwa_aes fallback."
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-65625",
    "datePublished": "2026-10-26T19:52:54.987Z",
    "dateReserved": "2026-07-22T13:55:59.401Z",
    "dateUpdated": "2026-10-26T19:52:54.987Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-65625",
      "date": "2026-10-27",
      "epss": "0.00115",
      "percentile": "0.01539"
    },
    "nvd": {
      "cve": {
        "affected": [
          {
            "affectedData": [
              {
                "collectionURL": "https://repo.hex.pm",
                "cpes": [
                  "cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "jose_jwa_aes"
                ],
                "packageName": "jose",
                "packageURL": "pkg:hex/jose",
                "product": "jose",
                "programFiles": [
                  "src/jwa/jose_jwa_aes.erl"
                ],
                "programRoutines": [
                  {
                    "name": "jose_jwa_aes:block_decrypt/4"
                  },
                  {
                    "name": "jose_jwa_aes:gcm_block_decrypt/6"
                  }
                ],
                "repo": "https://github.com/potatosalad/erlang-jose",
                "vendor": "potatosalad",
                "versions": [
                  {
                    "lessThan": "1.11.13",
                    "status": "affected",
                    "version": "1.2.0",
                    "versionType": "semver"
                  }
                ]
              },
              {
                "collectionURL": "https://github.com",
                "cpes": [
                  "cpe:2.3:a:potatosalad:jose:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "jose_jwa_aes"
                ],
                "packageName": "potatosalad/erlang-jose",
                "packageURL": "pkg:github/potatosalad/erlang-jose",
                "product": "jose",
                "programFiles": [
                  "src/jwa/jose_jwa_aes.erl"
                ],
                "programRoutines": [
                  {
                    "name": "jose_jwa_aes:block_decrypt/4"
                  },
                  {
                    "name": "jose_jwa_aes:gcm_block_decrypt/6"
                  }
                ],
                "repo": "https://github.com/potatosalad/erlang-jose",
                "vendor": "potatosalad",
                "versions": [
                  {
                    "lessThan": "3fa1f8e3efda0da5ce6f4c9984789f979dc02740",
                    "status": "affected",
                    "version": "8848b172575fb7d7e1e2977e8ae0a21678d2157a",
                    "versionType": "git"
                  }
                ]
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
          }
        ],
        "cveTags": [],
        "descriptions": [
          {
            "lang": "en",
            "value": "The pure-Erlang AES-GCM fallback in jose_jwa_aes derives the number of verified authentication tag bits from the attacker-supplied tag itself. In the {aes_gcm, Bits} clause of block_decrypt/4, the incoming tag is guarded only by is_binary/1, with no check on its length. Verification in gcm_block_decrypt/6 then computes TBits = bit_size(T) and compares only those bits of the real 128-bit tag. An attacker who controls a JWE token can truncate the authentication tag to as little as 8 bits, so only 8 bits are ever checked. This reduces forgery resistance from 2^-128 to 2^-8, and a forged ciphertext is reliably accepted as authentic within 256 attempts without knowledge of the key (an authentication tag forgery and integrity bypass). Supplying a tag longer than 128 bits instead causes a badmatch that crashes the decrypting process. The fallback is reached through the public JWE decryption path whenever AES-GCM is not provided by a native crypto NIF, for example on FIPS or stripped or older OTP builds.\n\nThis issue affects jose: from 1.2.0 before 1.11.13."
          }
        ],
        "id": "CVE-2026-65625",
        "lastModified": "2026-10-27T15:00:49.240",
        "metrics": {
          "cvssMetricV40": [
            {
              "cvssData": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "LOW",
                "attackRequirements": "PRESENT",
                "attackVector": "LOCAL",
                "availabilityRequirement": "NOT_DEFINED",
                "baseScore": 5.9,
                "baseSeverity": "MEDIUM",
                "confidentialityRequirement": "NOT_DEFINED",
                "exploitMaturity": "NOT_DEFINED",
                "integrityRequirement": "NOT_DEFINED",
                "modifiedAttackComplexity": "NOT_DEFINED",
                "modifiedAttackRequirements": "NOT_DEFINED",
                "modifiedAttackVector": "NOT_DEFINED",
                "modifiedPrivilegesRequired": "NOT_DEFINED",
                "modifiedSubAvailabilityImpact": "NOT_DEFINED",
                "modifiedSubConfidentialityImpact": "NOT_DEFINED",
                "modifiedSubIntegrityImpact": "NOT_DEFINED",
                "modifiedUserInteraction": "NOT_DEFINED",
                "modifiedVulnAvailabilityImpact": "NOT_DEFINED",
                "modifiedVulnConfidentialityImpact": "NOT_DEFINED",
                "modifiedVulnIntegrityImpact": "NOT_DEFINED",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "NONE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/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",
                "version": "4.0",
                "vulnAvailabilityImpact": "LOW",
                "vulnConfidentialityImpact": "NONE",
                "vulnIntegrityImpact": "HIGH",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
              "type": "Secondary"
            }
          ]
        },
        "published": "2026-10-26T20:17:57.910",
        "references": [
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://cna.erlef.org/cves/CVE-2026-65625.html"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/potatosalad/erlang-jose/commit/3fa1f8e3efda0da5ce6f4c9984789f979dc02740"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/potatosalad/erlang-jose/commit/8848b172575fb7d7e1e2977e8ae0a21678d2157a"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/potatosalad/erlang-jose/security/advisories/GHSA-6gxw-6f7r-cjr6"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://osv.dev/vulnerability/EEF-CVE-2026-65625"
          }
        ],
        "sourceIdentifier": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "vulnStatus": "Deferred",
        "weaknesses": [
          {
            "description": [
              {
                "lang": "en",
                "value": "CWE-354"
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "type": "Secondary"
          }
        ]
      }
    }
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.