CWE-674
Allowed-with-ReviewUncontrolled Recursion
Abstraction: Class · Status: Draft
The product does not properly control the amount of recursion that takes place, consuming excessive resources, such as allocated memory or the program stack.
616 vulnerabilities reference this CWE, most recent first.
GHSA-F38Q-MGVJ-VPH7
Vulnerability from github – Published: 2026-06-15 17:27 – Updated: 2026-06-15 17:27Summary
protobufjs accepted certain schema-derived names that could collide with properties used by protobufjs runtime helpers. The known affected names are fields named hasOwnProperty, field or oneof names such as $type when loaded through protobufjs JSON/reflection descriptors, and service methods whose generated helper name is rpcCall.
When affected message or service types were used, protobufjs could read schema-controlled data where it expected an own-property helper, reflected type metadata, or the base RPC helper. This could cause deterministic exceptions or recursive calls in affected decode post-checks, verification, object conversion, reflected JSON serialization, or protobufjs RPC helper invocation.
Impact
An attacker who can provide or influence protobuf schemas or protobufjs JSON descriptors may be able to make affected message or service types unusable, resulting in denial of service for the affected processing path.
Applications using only trusted schemas are affected only if those schemas contain one of the problematic names and the application reaches the affected API path.
The issue is not known to allow code execution by itself.
Preconditions
- The application must use an affected protobufjs version.
- The application must load or use a schema or protobufjs JSON descriptor containing one of the problematic names:
- a field named
hasOwnProperty, - a field or oneof named
$typethrough protobufjs JSON/reflection descriptor input, - or a service method whose generated helper name is
rpcCall. - The application must reach the affected API path for that name: required-field decode post-checks,
verify, ortoObjectforhasOwnProperty; reflected message JSON serialization for$type; or protobufjs RPC service invocation forrpcCall.
Workarounds
Do not load protobuf schemas or protobufjs JSON descriptors from untrusted sources with affected versions. If untrusted schemas or descriptors must be accepted, validate schema-derived field, oneof, and service method names before loading and reject the problematic names described above.
Applications using trusted schemas can avoid the issue by renaming affected fields or service methods, or by avoiding the affected API path.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.6.2"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.6.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.5.0"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs-cli"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.5.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.3.2"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs-cli"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 8.5.0"
},
"package": {
"ecosystem": "npm",
"name": "protobufjs"
},
"ranges": [
{
"events": [
{
"introduced": "8.0.0"
},
{
"fixed": "8.6.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54269"
],
"database_specific": {
"cwe_ids": [
"CWE-674",
"CWE-754"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-15T17:27:18Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nprotobufjs accepted certain schema-derived names that could collide with properties used by protobufjs runtime helpers. The known affected names are fields named `hasOwnProperty`, field or oneof names such as `$type` when loaded through protobufjs JSON/reflection descriptors, and service methods whose generated helper name is `rpcCall`.\n\nWhen affected message or service types were used, protobufjs could read schema-controlled data where it expected an own-property helper, reflected type metadata, or the base RPC helper. This could cause deterministic exceptions or recursive calls in affected decode post-checks, verification, object conversion, reflected JSON serialization, or protobufjs RPC helper invocation.\n\n## Impact\n\nAn attacker who can provide or influence protobuf schemas or protobufjs JSON descriptors may be able to make affected message or service types unusable, resulting in denial of service for the affected processing path.\n\nApplications using only trusted schemas are affected only if those schemas contain one of the problematic names and the application reaches the affected API path.\n\nThe issue is not known to allow code execution by itself.\n\n## Preconditions\n\n* The application must use an affected protobufjs version.\n* The application must load or use a schema or protobufjs JSON descriptor containing one of the problematic names:\n * a field named `hasOwnProperty`,\n * a field or oneof named `$type` through protobufjs JSON/reflection descriptor input,\n * or a service method whose generated helper name is `rpcCall`.\n* The application must reach the affected API path for that name: required-field decode post-checks, `verify`, or `toObject` for `hasOwnProperty`; reflected message JSON serialization for `$type`; or protobufjs RPC service invocation for `rpcCall`.\n\n## Workarounds\n\nDo not load protobuf schemas or protobufjs JSON descriptors from untrusted sources with affected versions. If untrusted schemas or descriptors must be accepted, validate schema-derived field, oneof, and service method names before loading and reject the problematic names described above.\n\nApplications using trusted schemas can avoid the issue by renaming affected fields or service methods, or by avoiding the affected API path.",
"id": "GHSA-f38q-mgvj-vph7",
"modified": "2026-06-15T17:27:18Z",
"published": "2026-06-15T17:27:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/protobufjs/protobuf.js/security/advisories/GHSA-f38q-mgvj-vph7"
},
{
"type": "PACKAGE",
"url": "https://github.com/protobufjs/protobuf.js"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "protobufjs : Schema-derived names can shadow runtime-significant properties"
}
GHSA-F3PG-HPPR-JF6F
Vulnerability from github – Published: 2024-11-21 21:33 – Updated: 2024-12-24 15:30In the Linux kernel, the following vulnerability has been resolved:
afs: Fix lock recursion
afs_wake_up_async_call() can incur lock recursion. The problem is that it is called from AF_RXRPC whilst holding the ->notify_lock, but it tries to take a ref on the afs_call struct in order to pass it to a work queue - but if the afs_call is already queued, we then have an extraneous ref that must be put... calling afs_put_call() may call back down into AF_RXRPC through rxrpc_kernel_shutdown_call(), however, which might try taking the ->notify_lock again.
This case isn't very common, however, so defer it to a workqueue. The oops looks something like:
BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646 lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0 CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351 Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014 Call Trace: dump_stack_lvl+0x47/0x70 do_raw_spin_lock+0x3c/0x90 rxrpc_kernel_shutdown_call+0x83/0xb0 afs_put_call+0xd7/0x180 rxrpc_notify_socket+0xa0/0x190 rxrpc_input_split_jumbo+0x198/0x1d0 rxrpc_input_data+0x14b/0x1e0 ? rxrpc_input_call_packet+0xc2/0x1f0 rxrpc_input_call_event+0xad/0x6b0 rxrpc_input_packet_on_conn+0x1e1/0x210 rxrpc_input_packet+0x3f2/0x4d0 rxrpc_io_thread+0x243/0x410 ? __pfx_rxrpc_io_thread+0x10/0x10 kthread+0xcf/0xe0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x24/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30
{
"affected": [],
"aliases": [
"CVE-2024-53090"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-21T19:15:12Z",
"severity": "MODERATE"
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nafs: Fix lock recursion\n\nafs_wake_up_async_call() can incur lock recursion. The problem is that it\nis called from AF_RXRPC whilst holding the -\u003enotify_lock, but it tries to\ntake a ref on the afs_call struct in order to pass it to a work queue - but\nif the afs_call is already queued, we then have an extraneous ref that must\nbe put... calling afs_put_call() may call back down into AF_RXRPC through\nrxrpc_kernel_shutdown_call(), however, which might try taking the\n-\u003enotify_lock again.\n\nThis case isn\u0027t very common, however, so defer it to a workqueue. The oops\nlooks something like:\n\n BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646\n lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0\n CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351\n Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014\n Call Trace:\n \u003cTASK\u003e\n dump_stack_lvl+0x47/0x70\n do_raw_spin_lock+0x3c/0x90\n rxrpc_kernel_shutdown_call+0x83/0xb0\n afs_put_call+0xd7/0x180\n rxrpc_notify_socket+0xa0/0x190\n rxrpc_input_split_jumbo+0x198/0x1d0\n rxrpc_input_data+0x14b/0x1e0\n ? rxrpc_input_call_packet+0xc2/0x1f0\n rxrpc_input_call_event+0xad/0x6b0\n rxrpc_input_packet_on_conn+0x1e1/0x210\n rxrpc_input_packet+0x3f2/0x4d0\n rxrpc_io_thread+0x243/0x410\n ? __pfx_rxrpc_io_thread+0x10/0x10\n kthread+0xcf/0xe0\n ? __pfx_kthread+0x10/0x10\n ret_from_fork+0x24/0x40\n ? __pfx_kthread+0x10/0x10\n ret_from_fork_asm+0x1a/0x30\n \u003c/TASK\u003e",
"id": "GHSA-f3pg-hppr-jf6f",
"modified": "2024-12-24T15:30:31Z",
"published": "2024-11-21T21:33:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-53090"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/610a79ffea02102899a1373fe226d949944a7ed6"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/d7cbf81df996b1eae2dee8deb6df08e2eba78661"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-F4QM-VJ5J-9XPW
Vulnerability from github – Published: 2026-04-14 18:48 – Updated: 2026-04-14 18:48A stack overflow vulnerability in ImageMagick's FX expression parser allows an attacker to crash the process by providing a deeply nested expression.
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.12.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33902"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T18:48:06Z",
"nvd_published_at": "2026-04-13T22:16:28Z",
"severity": "MODERATE"
},
"details": "A stack overflow vulnerability in ImageMagick\u0027s FX expression parser allows an attacker to crash the process by providing a deeply nested expression.",
"id": "GHSA-f4qm-vj5j-9xpw",
"modified": "2026-04-14T18:48:07Z",
"published": "2026-04-14T18:48:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-f4qm-vj5j-9xpw"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33902"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/commit/d3c0a37485314c5ccef72efb18f3847cd53868ba"
},
{
"type": "PACKAGE",
"url": "https://github.com/ImageMagick/ImageMagick"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/releases/tag/7.1.2-19"
},
{
"type": "WEB",
"url": "https://github.com/dlemstra/Magick.NET/releases/tag/14.12.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": " ImageMagick has a Stack Overflow via Recursive FX Expression Parsing"
}
GHSA-F5V8-V6Q3-Q4H6
Vulnerability from github – Published: 2026-04-16 22:50 – Updated: 2026-04-16 22:50Summary
Meridian v2.1.0 (Meridian.Mapping and Meridian.Mediator) shipped with nine defense-in-depth gaps reachable through its public APIs. Two are HIGH severity — the advertised DefaultMaxCollectionItems and DefaultMaxDepth safety caps are silently bypassed on the IMapper.Map(source, destination) overload and anywhere .UseDestinationValue() is configured on a collection-typed property. Four are MEDIUM (constructor invariant bypass, OpenTelemetry stack-trace info disclosure, retry amplification, notification fan-out amplification). Three are LOW (exception message disclosure, dictionary duplicate-key echo, static mediator cache growth under closed-generic types).
All nine are patched in v2.1.1. Upgrade is a drop-in NuGet bump; see the v2.1.1 CHANGELOG for the four behavioural changes (constructor selection, OTel default, publisher fan-out cap, retry caps).
Severity Matrix
| # | Severity | CWE | Finding | Fix |
|---|---|---|---|---|
| 1 | HIGH | CWE-770 | MappingEngine.TryMapCollectionOntoExisting enumerated the source without enforcing DefaultMaxCollectionItems. Reachable via Mapper.Map<TSrc,TDst>(src, dst) and any .ForMember(..., o => o.UseDestinationValue()) on a collection member through a plain Map(src) call. |
Shared cap enforcement helper between MapCollection and TryMapCollectionOntoExisting. |
| 2 | HIGH | CWE-674 | Collection-item recursion in the existing-destination path did not increment ResolutionContext.Depth, so self-referential collection graphs could reach stack overflow before DefaultMaxDepth fired. |
Depth increments at every collection-item boundary. |
| 3 | MEDIUM | CWE-665 | ObjectCreator.CreateWithConstructorMapping always invoked the widest public constructor, silently filling unresolved parameters with default(T) and bypassing narrower-ctor invariants. |
Widest-ctor selection now requires every parameter to be bound via explicit ctor mapping, source-name match, or a C# optional default. |
| 4 | MEDIUM | CWE-532 | Mediator.MarkActivityFailure emitted the full ex.ToString() (stack + inner chain) to the OpenTelemetry exception.stacktrace activity tag by default, leaking context to any shared trace sink. |
Gated on MediatorTelemetryOptions.RecordExceptionStackTrace — opt-in, default false. |
| 5 | MEDIUM | CWE-400 | RetryBehavior retried every exception type with unbounded MaxRetries; the exponential-backoff delay overflowed TimeSpan at ~30 attempts. No cancellation exclusion. |
Server-side MaxRetriesCap = 10, MaxBackoff = 5 min, OperationCanceledException short-circuit, recommended RetryPolicy.TransientOnly helper. |
| 6 | MEDIUM | CWE-400 | TaskWhenAllPublisher started every registered handler concurrently with no bound on fan-out. |
New constructor parameter maxDegreeOfParallelism (default 16; -1 restores legacy unbounded). |
| 7 | LOW | CWE-209 | Public mapping exceptions leaked FullName of source/destination types and concatenated inner exception messages into top-level property-mapping errors. |
Scrubbed to type Name; inner details only via InnerException chain. |
| 8 | LOW | CWE-209 | Dictionary materialization threw ArgumentException on duplicate keys, echoing the attacker-supplied key's .ToString(). |
Last-write-wins indexer semantics. |
| 9 | LOW | CWE-1325 | Static mediator handler caches grow monotonically under closed-generic request types. Doc-only mitigation; no code change — consumers must not allow attacker-controlled runtime type materialization to reach Send, Publish, or CreateStream. |
Documented in docs/security-model.md. |
Exploitation
Finding 1 / 2 (headline): A consumer that maps user-supplied collection payloads onto an existing destination list via mapper.Map(userCollection, existingList) — a documented and commonly used AutoMapper-style idiom — processes the full attacker-supplied collection with no size cap and no depth cap. An attacker sending a single request with a large (or self-referential) collection payload can block the worker thread for seconds and exhaust the managed heap or the call stack. Equivalent exposure through .UseDestinationValue() on a collection-typed destination member, reachable via a plain Map(src) call whose destination type default-initializes that member.
Finding 3: A destination type with multiple public constructors that differ only in their parameter-binding invariants (e.g., new UserAccount(string name, Email email) enforcing a non-default Email) could be instantiated with the narrower ctor's invariants silently bypassed if any source field was absent — the widest ctor was always picked, with unbound parameters replaced by default(T).
Findings 4 / 5 / 6: Amplification / information-disclosure vectors described in the matrix above. Each requires moderate integration context (telemetry sink trust, handler count, retry policy) to weaponize, but each is reachable through public APIs without authentication.
Patches
Meridian.Mapping2.1.1 (published 2026-04-16)Meridian.Mediator2.1.1 (published 2026-04-16)
Verified via:
- GitHub Release assets at https://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1
- Sigstore attestation (actions/attest-build-provenance@v2 → gh attestation verify green on both .nupkg from the GitHub Release)
- NuGet.org indexed both packages within the release workflow run
Workarounds
Users who cannot upgrade immediately may:
1. Avoid mapper.Map(src, dst) and .UseDestinationValue() on collection-typed destination members.
2. Wrap input collection deserialization with an explicit size limit before handing the payload to Meridian.
3. Register TaskWhenAllPublisher with maxDegreeOfParallelism ≤ 16 manually (v2.1.1+ only).
4. Disable OpenTelemetry exception.stacktrace tag emission at the trace exporter level if your trace sink is less trusted than your application.
These are defense-in-depth; the only complete mitigation is upgrading to 2.1.1.
Supported Versions
As of this advisory the supported security branch is 2.1.x. The 2.0.x line (published 2026-04-15) is not receiving the Phase 1 safety-defaults infrastructure needed to carry the HIGH-severity fixes, so 2.0.x is deprecated in favor of 2.1.x. See SECURITY.md for the updated supported-versions table.
Credits
- UmutKorkmaz (reporter and maintainer)
References
- v2.1.1 CHANGELOG section: https://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16
docs/security-model.mdthreat model: https://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.mdSECURITY.mddisclosure policy: https://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md- AutoMapper CVE-2026-32933 (motivating precedent for Meridian's safety-defaults)
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "Meridian.Mapping"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Meridian.Mediator"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1325",
"CWE-209",
"CWE-400",
"CWE-532",
"CWE-665",
"CWE-674",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-16T22:50:37Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nMeridian v2.1.0 (`Meridian.Mapping` and `Meridian.Mediator`) shipped with nine defense-in-depth gaps reachable through its public APIs. Two are HIGH severity \u2014 the advertised `DefaultMaxCollectionItems` and `DefaultMaxDepth` safety caps are silently bypassed on the `IMapper.Map(source, destination)` overload and anywhere `.UseDestinationValue()` is configured on a collection-typed property. Four are MEDIUM (constructor invariant bypass, OpenTelemetry stack-trace info disclosure, retry amplification, notification fan-out amplification). Three are LOW (exception message disclosure, dictionary duplicate-key echo, static mediator cache growth under closed-generic types).\n\nAll nine are patched in **v2.1.1**. Upgrade is a drop-in NuGet bump; see the v2.1.1 CHANGELOG for the four behavioural changes (constructor selection, OTel default, publisher fan-out cap, retry caps).\n\n## Severity Matrix\n\n| # | Severity | CWE | Finding | Fix |\n|---|---|---|---|---|\n| 1 | **HIGH** | CWE-770 | `MappingEngine.TryMapCollectionOntoExisting` enumerated the source without enforcing `DefaultMaxCollectionItems`. Reachable via `Mapper.Map\u003cTSrc,TDst\u003e(src, dst)` and any `.ForMember(..., o =\u003e o.UseDestinationValue())` on a collection member through a plain `Map(src)` call. | Shared cap enforcement helper between `MapCollection` and `TryMapCollectionOntoExisting`. |\n| 2 | **HIGH** | CWE-674 | Collection-item recursion in the existing-destination path did not increment `ResolutionContext.Depth`, so self-referential collection graphs could reach stack overflow before `DefaultMaxDepth` fired. | Depth increments at every collection-item boundary. |\n| 3 | MEDIUM | CWE-665 | `ObjectCreator.CreateWithConstructorMapping` always invoked the widest public constructor, silently filling unresolved parameters with `default(T)` and bypassing narrower-ctor invariants. | Widest-ctor selection now requires every parameter to be bound via explicit ctor mapping, source-name match, or a C# optional default. |\n| 4 | MEDIUM | CWE-532 | `Mediator.MarkActivityFailure` emitted the full `ex.ToString()` (stack + inner chain) to the OpenTelemetry `exception.stacktrace` activity tag by default, leaking context to any shared trace sink. | Gated on `MediatorTelemetryOptions.RecordExceptionStackTrace` \u2014 opt-in, default `false`. |\n| 5 | MEDIUM | CWE-400 | `RetryBehavior` retried every exception type with unbounded `MaxRetries`; the exponential-backoff delay overflowed `TimeSpan` at ~30 attempts. No cancellation exclusion. | Server-side `MaxRetriesCap = 10`, `MaxBackoff = 5 min`, `OperationCanceledException` short-circuit, recommended `RetryPolicy.TransientOnly` helper. |\n| 6 | MEDIUM | CWE-400 | `TaskWhenAllPublisher` started every registered handler concurrently with no bound on fan-out. | New constructor parameter `maxDegreeOfParallelism` (default 16; `-1` restores legacy unbounded). |\n| 7 | LOW | CWE-209 | Public mapping exceptions leaked `FullName` of source/destination types and concatenated inner exception messages into top-level property-mapping errors. | Scrubbed to type `Name`; inner details only via `InnerException` chain. |\n| 8 | LOW | CWE-209 | Dictionary materialization threw `ArgumentException` on duplicate keys, echoing the attacker-supplied key\u0027s `.ToString()`. | Last-write-wins indexer semantics. |\n| 9 | LOW | CWE-1325 | Static mediator handler caches grow monotonically under closed-generic request types. **Doc-only mitigation**; no code change \u2014 consumers must not allow attacker-controlled runtime type materialization to reach `Send`, `Publish`, or `CreateStream`. | Documented in `docs/security-model.md`. |\n\n## Exploitation\n\n**Finding 1 / 2 (headline):** A consumer that maps user-supplied collection payloads onto an existing destination list via `mapper.Map(userCollection, existingList)` \u2014 a documented and commonly used AutoMapper-style idiom \u2014 processes the full attacker-supplied collection with no size cap and no depth cap. An attacker sending a single request with a large (or self-referential) collection payload can block the worker thread for seconds and exhaust the managed heap or the call stack. Equivalent exposure through `.UseDestinationValue()` on a collection-typed destination member, reachable via a plain `Map(src)` call whose destination type default-initializes that member.\n\n**Finding 3:** A destination type with multiple public constructors that differ only in their parameter-binding invariants (e.g., `new UserAccount(string name, Email email)` enforcing a non-default `Email`) could be instantiated with the narrower ctor\u0027s invariants silently bypassed if any source field was absent \u2014 the widest ctor was always picked, with unbound parameters replaced by `default(T)`.\n\n**Findings 4 / 5 / 6:** Amplification / information-disclosure vectors described in the matrix above. Each requires moderate integration context (telemetry sink trust, handler count, retry policy) to weaponize, but each is reachable through public APIs without authentication.\n\n## Patches\n\n- `Meridian.Mapping` **2.1.1** (published 2026-04-16)\n- `Meridian.Mediator` **2.1.1** (published 2026-04-16)\n\nVerified via:\n- GitHub Release assets at \u003chttps://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1\u003e\n- Sigstore attestation (`actions/attest-build-provenance@v2` \u2192 `gh attestation verify` green on both `.nupkg` from the GitHub Release)\n- NuGet.org indexed both packages within the release workflow run\n\n## Workarounds\n\nUsers who cannot upgrade immediately may:\n1. Avoid `mapper.Map(src, dst)` and `.UseDestinationValue()` on collection-typed destination members.\n2. Wrap input collection deserialization with an explicit size limit before handing the payload to Meridian.\n3. Register `TaskWhenAllPublisher` with `maxDegreeOfParallelism` \u2264 16 manually (v2.1.1+ only).\n4. Disable OpenTelemetry `exception.stacktrace` tag emission at the trace exporter level if your trace sink is less trusted than your application.\n\nThese are defense-in-depth; the only complete mitigation is upgrading to 2.1.1.\n\n## Supported Versions\n\nAs of this advisory the supported security branch is **2.1.x**. The 2.0.x line (published 2026-04-15) is not receiving the Phase 1 safety-defaults infrastructure needed to carry the HIGH-severity fixes, so 2.0.x is deprecated in favor of 2.1.x. See `SECURITY.md` for the updated supported-versions table.\n\n## Credits\n\n- UmutKorkmaz (reporter and maintainer)\n\n## References\n\n- v2.1.1 CHANGELOG section: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16\u003e\n- `docs/security-model.md` threat model: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.md\u003e\n- `SECURITY.md` disclosure policy: \u003chttps://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md\u003e\n- AutoMapper CVE-2026-32933 (motivating precedent for Meridian\u0027s safety-defaults)",
"id": "GHSA-f5v8-v6q3-q4h6",
"modified": "2026-04-16T22:50:37Z",
"published": "2026-04-16T22:50:37Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/security/advisories/GHSA-f5v8-v6q3-q4h6"
},
{
"type": "PACKAGE",
"url": "https://github.com/UmutKorkmaz/meridian"
},
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16"
},
{
"type": "WEB",
"url": "https://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Meridian: Multiple defense-in-depth gaps (collection/depth caps, telemetry, retry, fan-out)"
}
GHSA-FCGC-C6HR-PQM2
Vulnerability from github – Published: 2023-01-05 18:30 – Updated: 2023-01-11 21:30GPAC MP4Box 2.1-DEV-rev649-ga8f438d20 has a segment fault (/stack overflow) due to infinite recursion in Media_GetSample isomedia/media.c:662
{
"affected": [],
"aliases": [
"CVE-2022-47662"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-01-05T16:15:00Z",
"severity": "MODERATE"
},
"details": "GPAC MP4Box 2.1-DEV-rev649-ga8f438d20 has a segment fault (/stack overflow) due to infinite recursion in Media_GetSample isomedia/media.c:662",
"id": "GHSA-fcgc-c6hr-pqm2",
"modified": "2023-01-11T21:30:40Z",
"published": "2023-01-05T18:30:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-47662"
},
{
"type": "WEB",
"url": "https://github.com/gpac/gpac/issues/2359"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2023/dsa-5411"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-FF5X-7QG5-VWF2
Vulnerability from github – Published: 2023-12-13 13:32 – Updated: 2023-12-13 13:32Summary
When parsing the attributes passed to a use tag inside an svg document, we can cause the system to go to an infinite recursion. Depending on the system configuration and attack pattern this could exhaust the memory available to the executing process and/or to the server itself.
Details
Inside Svg\Tag\UseTag::before, php-svg-lib parses the attributes passed to an use tag inside an svg document. When it finds a href or xlink:href, it will try to retrieve the object representing this tag:
$link = $attributes["href"] ?? $attributes["xlink:href"];
$this->reference = $document->getDef($link);
if ($this->reference) {
$this->reference->before($attributes);
}
$document->getDef is implemented as follow:
public function getDef($id) {
$id = ltrim($id, "#");
return isset($this->defs[$id]) ? $this->defs[$id] : null;
}
Note: the $id in the above method is actually the link being used in use tag. This part is important, because this behaviour here actually leads to the vulnerability. It will be mentioned later on in this report.
If it finds the referenced object, it will try to call the before method on the referenced object (this is still inside Svg\Tag\UseTag::before) :
if ($this->reference) {
$this->reference->before($attributes);
}
In order to cause an infinte loop, we need to be able to control the $id used in the $this->defs[$id] code above. This defs property (Svg\Document::defs) is being populated when Svg\Document::_tagStart is called. This is the handler being used when the php-svg-lib is parsing the svg structure:
// Svg\Document line 343
if ($tag) {
if (isset($attributes["id"])) {
$this->defs[$attributes["id"]] = $tag;
}
else {
// ...
}
// ...
}
So if the use tag contains an id, then that use tag will be added to the $defs array with it's id as the key.
Now as noted before, when there is a link inside the use tag, the library uses that link as the id to actually find the object or tag that has been added to the Svg\Document::defs.
So if the id attribute is equal to the link attribute inside the use tag, then the referenced object (in this case it is the Use tag object) will be called recursively until the memory given to the script is exhausted.
PoC
This is an example svg file that can be used to demonstrate the vulnerability.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use id="selfref" xlink:href="#selfref" />
</svg>
Impact
When the lib parses the above payload, it will crash:
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 262144 bytes) in /xxx/dompdf/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php on line 37
An attacker sending multiple request to a system to render the above payload can potentially cause resource exhaustion to the point that the system is unable to handle incoming request.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "phenx/php-svg-lib"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.5.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-50251"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": true,
"github_reviewed_at": "2023-12-13T13:32:21Z",
"nvd_published_at": "2023-12-12T21:15:08Z",
"severity": "MODERATE"
},
"details": "### Summary\nWhen parsing the attributes passed to a `use` tag inside an svg document, we can cause the system to go to an infinite recursion. Depending on the system configuration and attack pattern this could exhaust the memory available to the executing process and/or to the server itself.\n\n### Details\nInside `Svg\\Tag\\UseTag::before`, php-svg-lib parses the attributes passed to an `use` tag inside an svg document. When it finds a `href` or `xlink:href`, it will try to retrieve the object representing this tag:\n\n```\n$link = $attributes[\"href\"] ?? $attributes[\"xlink:href\"];\n$this-\u003ereference = $document-\u003egetDef($link);\n\nif ($this-\u003ereference) {\n $this-\u003ereference-\u003ebefore($attributes);\n}\n```\n\n`$document-\u003egetDef` is implemented as follow:\n\n```\npublic function getDef($id) {\n $id = ltrim($id, \"#\");\n\n return isset($this-\u003edefs[$id]) ? $this-\u003edefs[$id] : null;\n}\n```\n\n_Note:_ the `$id` in the above method is actually the _link_ being used in `use` tag. This part is important, because this behaviour here actually leads to the vulnerability. It will be mentioned later on in this report.\n\nIf it finds the referenced object, it will try to call the `before` method on the referenced object (this is still inside `Svg\\Tag\\UseTag::before`) :\n\n```\nif ($this-\u003ereference) {\n $this-\u003ereference-\u003ebefore($attributes);\n}\n```\n\nIn order to cause an infinte loop, we need to be able to control the `$id` used in the `$this-\u003edefs[$id]` code above. This `defs` property (`Svg\\Document::defs`) is being populated when `Svg\\Document::_tagStart` is called. This is the handler being used when the php-svg-lib is parsing the svg structure:\n\n```\n// Svg\\Document line 343\nif ($tag) {\n if (isset($attributes[\"id\"])) {\n $this-\u003edefs[$attributes[\"id\"]] = $tag;\n }\n else {\n // ...\n }\n\n // ...\n}\n```\n\nSo if the `use` tag contains an `id`, then that `use` tag will be added to the `$defs` array with it\u0027s `id` as the key.\n\nNow as noted before, when there is a link inside the `use` tag, the library uses that link as the `id` to actually find the object or `tag` that has been added to the `Svg\\Document::defs`.\n\nSo if the `id` attribute is equal to the link attribute inside the `use` tag, then the referenced object (in this case it is the `Use` tag object) will be called recursively until the memory given to the script is exhausted.\n\n### PoC\n\nThis is an example svg file that can be used to demonstrate the vulnerability.\n\n```\n\u003csvg width=\"200\" height=\"200\"\n xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\u003e\n \u003cuse id=\"selfref\" xlink:href=\"#selfref\" /\u003e\n\u003c/svg\u003e\n```\n\n### Impact\n\nWhen the lib parses the above payload, it will crash:\n\n```\nPHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 262144 bytes) in /xxx/dompdf/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php on line 37\n```\n\nAn attacker sending multiple request to a system to render the above payload can potentially cause resource exhaustion to the point that the system is unable to handle incoming request.",
"id": "GHSA-ff5x-7qg5-vwf2",
"modified": "2023-12-13T13:32:21Z",
"published": "2023-12-13T13:32:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dompdf/php-svg-lib/security/advisories/GHSA-ff5x-7qg5-vwf2"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-50251"
},
{
"type": "WEB",
"url": "https://github.com/dompdf/php-svg-lib/commit/88163cbe562d9b391b3a352e54d9c89d02d77ee0"
},
{
"type": "PACKAGE",
"url": "https://github.com/dompdf/php-svg-lib"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Denial of service caused by infinite recursion when parsing SVG document"
}
GHSA-FJCC-FH45-XQ5M
Vulnerability from github – Published: 2026-04-27 00:30 – Updated: 2026-04-27 00:30Nmap 7.70 contains a denial of service vulnerability that allows local attackers to crash the application by processing malicious XML files with exponential entity expansion. Attackers can create a crafted XML file with nested entity definitions and open it through ZenMap's scan import functionality to cause the program to consume excessive system resources and crash.
{
"affected": [],
"aliases": [
"CVE-2018-25282"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-26T22:17:28Z",
"severity": "MODERATE"
},
"details": "Nmap 7.70 contains a denial of service vulnerability that allows local attackers to crash the application by processing malicious XML files with exponential entity expansion. Attackers can create a crafted XML file with nested entity definitions and open it through ZenMap\u0027s scan import functionality to cause the program to consume excessive system resources and crash.",
"id": "GHSA-fjcc-fh45-xq5m",
"modified": "2026-04-27T00:30:26Z",
"published": "2026-04-27T00:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-25282"
},
{
"type": "WEB",
"url": "https://nmap.org/dist/nmap-7.70-setup.exe"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/45357"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/nmap-denial-of-service-via-xml-entity-expansion"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-FMC6-PG58-457G
Vulnerability from github – Published: 2022-05-13 01:21 – Updated: 2026-04-24 15:32The load_pnm function in frompnm.c in libsixel.a in libsixel 1.8.2 has infinite recursion.
{
"affected": [],
"aliases": [
"CVE-2019-11024"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-04-08T23:29:00Z",
"severity": "MODERATE"
},
"details": "The load_pnm function in frompnm.c in libsixel.a in libsixel 1.8.2 has infinite recursion.",
"id": "GHSA-fmc6-pg58-457g",
"modified": "2026-04-24T15:32:15Z",
"published": "2022-05-13T01:21:57Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-11024"
},
{
"type": "WEB",
"url": "https://github.com/saitoha/libsixel/issues/85"
},
{
"type": "WEB",
"url": "https://research.loginsoft.com/bugs/1501"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-FMJ5-RVMP-845R
Vulnerability from github – Published: 2025-09-10 21:30 – Updated: 2026-05-12 15:31Uncontrolled recursion in XPath evaluation in libxml2 up to and including version 2.9.14 allows a local attacker to cause a stack overflow via crafted expressions. XPath processing functions xmlXPathRunEval, xmlXPathCtxtCompile, and xmlXPathEvalExpr were resetting recursion depth to zero before making potentially recursive calls. When such functions were called recursively this could allow for uncontrolled recursion and lead to a stack overflow. These functions now preserve recursion depth across recursive calls, allowing recursion depth to be controlled.
{
"affected": [],
"aliases": [
"CVE-2025-9714"
],
"database_specific": {
"cwe_ids": [
"CWE-674"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-10T19:15:42Z",
"severity": "MODERATE"
},
"details": "Uncontrolled recursion in\u00a0XPath evaluation\u00a0in libxml2 up to and including version 2.9.14 allows a local attacker to cause a stack overflow via crafted expressions. XPath processing functions `xmlXPathRunEval`, `xmlXPathCtxtCompile`, and `xmlXPathEvalExpr` were resetting recursion depth to zero before making potentially recursive calls. When such functions were called recursively this could allow for uncontrolled recursion and lead to a stack overflow. These functions now preserve recursion depth across recursive calls, allowing recursion depth to be controlled.",
"id": "GHSA-fmj5-rvmp-845r",
"modified": "2026-05-12T15:31:05Z",
"published": "2025-09-10T21:30:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-9714"
},
{
"type": "WEB",
"url": "https://cert-portal.siemens.com/productcert/html/ssa-577017.html"
},
{
"type": "WEB",
"url": "https://gitlab.gnome.org/GNOME/libxml2/-/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2025/09/msg00035.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-FMJ9-77Q8-G6C4
Vulnerability from github – Published: 2024-08-27 18:14 – Updated: 2024-09-13 13:35Impact
Instances of @apollo/query-planner >=2.0.0 and <2.8.5 are impacted by a denial-of-service vulnerability. @apollo/gateway versions >=2.0.0 and < 2.8.5 and Apollo Router <1.52.1 are also impacted through their use of @apollo/query-planner.
If @apollo/query-planner is asked to plan a sufficiently complex query, it may loop infinitely and never complete. This results in unbounded memory consumption and either a crash or out-of-memory (OOM) termination.
This issue can be triggered if you have at least one non-@key field that can be resolved by multiple subgraphs. To identify these shared fields, the schema for each subgraph must be reviewed. The mechanism to identify shared fields varies based on the version of Federation your subgraphs are using.
You can check if your subgraphs are using Federation 1 or Federation 2 by reviewing their schemas. Federation 2 subgraph schemas will contain a @link directive referencing the version of Federation being used while Federation 1 subgraphs will not. For example, in a Federation 2 subgraph, you will find a line like @link(url: "https://specs.apollo.dev/federation/v2.0"). If a similar @link directive is not present in your subgraph schema, it is using Federation 1. Note that a supergraph can contain a mix of Federation 1 and Federation 2 subgraphs.
To review Federation 1 subgraphs for impact:
In Federation 1 subgraphs, fields are implicitly shareable across subgraphs. To review for impact, you will need to review for cases where multiple subgraphs can resolve the same field. For example:
# Subgraph 1
type Query {
field: Int
}
# Subgraph 2
type Query {
field: Int
}
To review Federation 2 subgraphs for impact:
In Federation 2 subgraphs, fields must be explicitly defined as shareable across subgraphs. This is done via the @shareable directive. For example:
# Subgraph 1
@link(url: "https://specs.apollo.dev/federation/v2.0")
type Query {
field: Int @shareable
}
# Subgraph 2
@link(url: "https://specs.apollo.dev/federation/v2.0")
type Query {
field: Int @shareable
}
Impact Detail
This issue results from the Apollo query planner attempting to use a Number exceeding Javascript’s Number.MAX_VALUE in some cases. In Javascript, Number.MAX_VALUE is (2^1024 - 2^971).
When the query planner receives an inbound graphql request, it breaks the query into pieces and for each piece, generates a list of potential execution steps to solve the piece. These candidates represent the steps that the query planner will take to satisfy the pieces of the larger query. As part of normal operations, the query planner requires and calculates the number of possible query plans for the total query. That is, it needs the product of the number of query plan candidates for each piece of the query. Under normal circumstances, after generating all query plan candidates and calculating the number of all permutations, the query planner moves on to stack rank candidates and prune less-than-optimal options.
In particularly complex queries, especially those where fields can be solved through multiple subgraphs, this can cause the number of all query plan permutations to balloon. In worst-case scenarios, this can end up being a number larger than Number.MAX_VALUE. In Javascript, if Number.MAX_VALUE is exceeded, Javascript represents the value as “infinity”. If the count of candidates is evaluated as infinity, the component of the query planner responsible for pruning less-than-optimal query plans does not actually prune candidates, causing the query planner to evaluate many orders of magnitude more query plan candidates than necessary.
A given graph’s exposure to this issue varies based on its complexity. Consider the following Federation 2 subgraphs:
# Subgraph 1
type Query {
field: Int @shareable
}
# Subgraph 2
type Query {
field: Int @shareable
}
The query planner can solve requests for Query.field in one of two ways - either by querying subgraph 1 or subgraph 2.
The following query with 1024 aliased fields would trigger this issue because 2^1024 > Number.MAX_VALUE:
query {
field_1: field
field_2: field
# ...
field_1023: field
field_1024: field
}
However, in a graph that provided 5 options to solve a given field, the bug could be encountered in a query that aliased the field approximately 440 times.
Patches
@apollo/query-planner 2.8.5 @apollo/gateway 2.8.5 Apollo Router 1.52.1
Workarounds
This issue can be avoided by ensuring there are no fields resolvable from multiple subgraphs. If all subgraphs are using Federation 2, you can confirm that you are not impacted by ensuring that none of your subgraph schemas use the @shareable directive. If you are using Federation 1 subgraphs, you will need to validate that there are no fields resolvable by multiple subgraphs.
Note that a supergraph can contain a mix of Federation 1 and Federation 2 subgraphs.
If you do have fields resolvable by multiple subgraphs, changing this behavior in response to this issue may be risky to the operation of your supergraph. We recommend that you update to a patched version of either Apollo Router or Apollo Gateway.
Apollo customers with an enterprise entitlement using the Apollo Router can also mitigate much of the risk from this issue by implementing Apollo’s Persisted Queries (PQ) feature. With PQ enabled, the Apollo Router will only execute safelisted queries. While customers would need to ensure that queries that induce this issue are not added to the safelist, PQs would mitigate the risk of clients submitting ad hoc queries that exploit this issue.
References
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "apollo-router"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.52.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@apollo/query-planner"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.8.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@apollo/gateway"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.8.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-43414"
],
"database_specific": {
"cwe_ids": [
"CWE-673",
"CWE-674"
],
"github_reviewed": true,
"github_reviewed_at": "2024-08-27T18:14:12Z",
"nvd_published_at": "2024-08-27T18:15:15Z",
"severity": "HIGH"
},
"details": "### Impact\nInstances of @apollo/query-planner \u003e=2.0.0 and \u003c2.8.5 are impacted by a denial-of-service vulnerability. @apollo/gateway versions \u003e=2.0.0 and \u003c 2.8.5 and Apollo Router \u003c1.52.1 are also impacted through their use of @apollo/query-planner. \n\nIf @apollo/query-planner is asked to plan a sufficiently complex query, it may loop infinitely and never complete. This results in unbounded memory consumption and either a crash or out-of-memory (OOM) termination.\n\nThis issue can be triggered if you have at least one non-`@key` field that can be resolved by multiple subgraphs. To identify these shared fields, the schema for each subgraph must be reviewed. The mechanism to identify shared fields varies based on the version of Federation your subgraphs are using.\n\nYou can check if your subgraphs are using Federation 1 or Federation 2 by reviewing their schemas. Federation 2 subgraph schemas will contain a `@link` directive referencing the version of Federation being used while Federation 1 subgraphs will not. For example, in a Federation 2 subgraph, you will find a line like `@link(url: \"https://specs.apollo.dev/federation/v2.0\")`. If a similar `@link` directive is not present in your subgraph schema, it is using Federation 1. Note that a supergraph can contain a mix of Federation 1 and Federation 2 subgraphs.\n\n**To review Federation 1 subgraphs for impact:**\n\nIn Federation 1 subgraphs, fields are implicitly shareable across subgraphs. To review for impact, you will need to review for cases where multiple subgraphs can resolve the same field. For example: \n\n```graphql\n# Subgraph 1\ntype Query {\n field: Int\n}\n\n# Subgraph 2\ntype Query {\n field: Int\n}\n```\n\n\n**To review Federation 2 subgraphs for impact:**\n\nIn Federation 2 subgraphs, fields must be explicitly defined as shareable across subgraphs. This is done via the `@shareable` directive. For example:\n\n```graphql\n# Subgraph 1\n@link(url: \"https://specs.apollo.dev/federation/v2.0\")\ntype Query {\n field: Int @shareable\n}\n\n# Subgraph 2\n@link(url: \"https://specs.apollo.dev/federation/v2.0\")\ntype Query {\n field: Int @shareable\n}\n```\n\n### Impact Detail\n\nThis issue results from the Apollo query planner attempting to use a `Number` exceeding Javascript\u2019s `Number.MAX_VALUE` in some cases. In Javascript, `Number.MAX_VALUE` is (2^1024 - 2^971).\n\nWhen the query planner receives an inbound graphql request, it breaks the query into pieces and for each piece, generates a list of potential execution steps to solve the piece. These candidates represent the steps that the query planner will take to satisfy the pieces of the larger query. As part of normal operations, the query planner requires and calculates the number of possible query plans for the total query. That is, it needs the product of the number of query plan candidates for each piece of the query. Under normal circumstances, after generating all query plan candidates and calculating the number of all permutations, the query planner moves on to stack rank candidates and prune less-than-optimal options. \n\nIn particularly complex queries, especially those where fields can be solved through multiple subgraphs, this can cause the number of all query plan permutations to balloon. In worst-case scenarios, this can end up being a number larger than `Number.MAX_VALUE`. In Javascript, if `Number.MAX_VALUE` is exceeded, Javascript represents the value as \u201cinfinity\u201d. If the count of candidates is evaluated as infinity, the component of the query planner responsible for pruning less-than-optimal query plans does not actually prune candidates, causing the query planner to evaluate many orders of magnitude more query plan candidates than necessary.\n\nA given graph\u2019s exposure to this issue varies based on its complexity. Consider the following Federation 2 subgraphs: \n\n```graphql\n# Subgraph 1\ntype Query {\n field: Int @shareable\n}\n\n# Subgraph 2\ntype Query {\n field: Int @shareable\n}\n```\n\nThe query planner can solve requests for `Query.field` in one of two ways - either by querying subgraph 1 or subgraph 2. \n\nThe following query with 1024 aliased fields would trigger this issue because 2^1024 \u003e `Number.MAX_VALUE`: \n\n```graphql\nquery {\n field_1: field\n field_2: field\n # ...\n field_1023: field\n field_1024: field\n}\n```\n\n\nHowever, in a graph that provided 5 options to solve a given field, the bug could be encountered in a query that aliased the field approximately 440 times.\n\n\n### Patches\n@apollo/query-planner 2.8.5\n@apollo/gateway 2.8.5\nApollo Router 1.52.1\n\n### Workarounds\nThis issue can be avoided by ensuring there are no fields resolvable from multiple subgraphs. If all subgraphs are using Federation 2, you can confirm that you are not impacted by ensuring that none of your subgraph schemas use the `@shareable` directive. If you are using Federation 1 subgraphs, you will need to validate that there are no fields resolvable by multiple subgraphs. \n\nNote that a supergraph can contain a mix of Federation 1 and Federation 2 subgraphs. \n\nIf you do have fields resolvable by multiple subgraphs, changing this behavior in response to this issue may be risky to the operation of your supergraph. We recommend that you update to a patched version of either Apollo Router or Apollo Gateway.\n\nApollo customers with an enterprise entitlement using the Apollo Router can also mitigate much of the risk from this issue by implementing [Apollo\u2019s Persisted Queries (PQ) feature](https://www.apollographql.com/docs/router/configuration/persisted-queries). With PQ enabled, the Apollo Router will only execute safelisted queries. While customers would need to ensure that queries that induce this issue are not added to the safelist, PQs would mitigate the risk of clients submitting ad hoc queries that exploit this issue.\n\n### References\n\n[Additional information on Query Plans](https://www.apollographql.com/docs/federation/query-plans/)\n",
"id": "GHSA-fmj9-77q8-g6c4",
"modified": "2024-09-13T13:35:59Z",
"published": "2024-08-27T18:14:12Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/apollographql/federation/security/advisories/GHSA-fmj9-77q8-g6c4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-43414"
},
{
"type": "WEB",
"url": "https://github.com/apollographql/router/commit/e309c9bb5a48c1304ff69c88b7eabdd08c26bf45"
},
{
"type": "PACKAGE",
"url": "https://github.com/apollographql/federation"
},
{
"type": "WEB",
"url": "https://www.apollographql.com/docs/federation/query-plans"
},
{
"type": "WEB",
"url": "https://www.apollographql.com/docs/router/configuration/persisted-queries"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Apollo Query Planner and Apollo Gateway may infinitely loop on sufficiently complex queries"
}
Mitigation
Ensure that an end condition will be reached under all logic conditions. The end condition may include checking against the depth of recursion and exiting with an error if the recursion goes too deep. The complexity of the end condition contributes to the effectiveness of this action.
Mitigation
Increase the stack size.
CAPEC-230: Serialized Data with Nested Payloads
Applications often need to transform data in and out of a data format (e.g., XML and YAML) by using a parser. It may be possible for an adversary to inject data that may have an adverse effect on the parser when it is being processed. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. By nesting these structures, causing the data to be repeatedly substituted, an adversary can cause the parser to consume more resources while processing, causing excessive memory consumption and CPU utilization.
CAPEC-231: Oversized Serialized Data Payloads
An adversary injects oversized serialized data payloads into a parser during data processing to produce adverse effects upon the parser such as exhausting system resources and arbitrary code execution.