GHSA-f5v8-v6q3-q4h6: Meridian Multiple Defense-in-depth Gaps (collection/depth Caps, Vulnerability

HIGH
Advisory Summary

GHSA-f5v8-v6q3-q4h6 is a HIGH (CVSS 7.5) multiple defense-in-depth gaps (collection/depth caps, vulnerability (CWE-532: Insertion of Sensitive Information into Log File) affecting Meridian libraries in the NuGet ecosystem. The issue involves multiple defense-in-depth gaps (collection/depth caps, telemetry, retry, fan-out). Remediation is available by upgrading affected packages to version 2.1.1.

GHSA-f5v8-v6q3-q4h6 at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-f5v8-v6q3-q4h6
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-532: Insertion of Sensitive Information into Log File
Affected Product Meridian
Package Ecosystem NuGet
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity None (I:N)
Availability High (A:H)

How to Fix GHSA-f5v8-v6q3-q4h6

To remediate this vulnerability, upgrade all affected Meridian dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

Meridian.Mapping fixed: 2.1.1
Upgrade Meridian.Mapping to 2.1.1
Meridian.Mediator fixed: 2.1.1
Upgrade Meridian.Mediator to 2.1.1
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for Meridian.Mapping

How to Check if You Are Affected

To determine whether your application is affected by GHSA-f5v8-v6q3-q4h6, inspect your project dependencies for Meridian:

inspect dependencies for Meridian.Mapping

Analyze the terminal output to locate any version of Meridian in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.1.1), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-532: Insertion of Sensitive Information into Log File, where the product writes sensitive information to a log file. In Meridian, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary 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.Mapping` **2.1.1** (published 2026-04-16) - `Meridian.Mediator` **2.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.md` threat model: <https://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.md> - `SECURITY.md` disclosure policy: <https://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md> - AutoMapper CVE-2026-32933 (motivating precedent for Meridian's safety-defaults)

GHSA-f5v8-v6q3-q4h6 Affected Meridian Versions

2 component(s)
Fixed Versions:
2.1.1
Product / Package Ecosystem Affected Versions Fixed Version
Meridian.Mapping
NuGet
≥ 2.0.0
< 2.1.1
2.1.1
Meridian.Mediator
NuGet
≥ 2.0.0
< 2.1.1
2.1.1

References

Frequently Asked Questions

What is GHSA-f5v8-v6q3-q4h6?
GHSA-f5v8-v6q3-q4h6 is a security vulnerability in Meridian involving Multiple defense-in-depth gaps (collection/depth caps, telemetry, retry, fan-out) under CWE-532: Insertion of Sensitive Information into Log File.
Which Meridian versions are affected?
Affected versions include releases prior to 2.1.1 across affected packages: Meridian.Mapping, Meridian.Mediator.
What version fixes GHSA-f5v8-v6q3-q4h6?
Upgrading to 2.1.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is Meridian.Mapping affected?
Yes, Meridian.Mapping is affected in releases prior to 2.1.1. Upgrade your dependency to 2.1.1 or later.
Is Meridian.Mediator affected?
Yes, Meridian.Mediator is affected in releases prior to 2.1.1. Upgrade your dependency to 2.1.1 or later.
What is the CVSS score of GHSA-f5v8-v6q3-q4h6?
GHSA-f5v8-v6q3-q4h6 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.
What CWE is associated with GHSA-f5v8-v6q3-q4h6?
GHSA-f5v8-v6q3-q4h6 is classified under CWE-532: Insertion of Sensitive Information into Log File (The product writes sensitive information to a log file.).
How can I check NuGet dependencies for GHSA-f5v8-v6q3-q4h6?
Run the dependency tree command: 'inspect dependencies for Meridian.Mapping'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-f5v8-v6q3-q4h6",
  "modified" : "2026-04-16T22:50:37Z",
  "published" : "2026-04-16T22:50:37Z",
  "aliases" : [ ],
  "summary" : "Meridian: Multiple defense-in-depth gaps (collection/depth caps, telemetry, retry, fan-out)",
  "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 — 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<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`. |\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` — 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's `.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 — 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)` — 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.\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's invariants silently bypassed if any source field was absent — 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 <https://github.com/UmutKorkmaz/meridian/releases/tag/v2.1.1>\n- Sigstore attestation (`actions/attest-build-provenance@v2` → `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` ≤ 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: <https://github.com/UmutKorkmaz/meridian/blob/main/CHANGELOG.md#211---2026-04-16>\n- `docs/security-model.md` threat model: <https://github.com/UmutKorkmaz/meridian/blob/main/docs/security-model.md>\n- `SECURITY.md` disclosure policy: <https://github.com/UmutKorkmaz/meridian/blob/main/SECURITY.md>\n- AutoMapper CVE-2026-32933 (motivating precedent for Meridian's safety-defaults)",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "NuGet",
      "name" : "Meridian.Mapping"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.1.1"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "NuGet",
      "name" : "Meridian.Mediator"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.1.1"
      } ]
    } ]
  } ],
  "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"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-1325", "CWE-209", "CWE-400", "CWE-532", "CWE-665", "CWE-674", "CWE-770" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-16T22:50:37Z",
    "nvd_published_at" : null
  }
}