Skip to content

Marten 9.14.0

Choose a tag to compare

@jeremydmiller jeremydmiller released this 08 Jul 18:26

Marten 9.14.0 is the recommended upgrade for all 9.x users. It combines the LINQ SQL-injection security fix (first shipped in 9.13.0) with the fix for the projection-coordinator shutdown race in #4874 and the accompanying dependency updates.

Beyond the LINQ updates, this made the new Per-Tenant Event Partitioning much more robust as we're testing that in conjunction with a JasperFx client for ludicrous scalability.

🔒 Security — SQL injection in the LINQ provider (GHSA-rfx3-98h7-v3xp)

Several LINQ / tenant-management code paths interpolated a runtime, potentially attacker-influenced value into generated SQL as a single-quoted literal without escaping or parameterization. A value containing a single quote could break out of the literal and inject SQL. The primary vector — a Dictionary<,> indexer key in a Where filter (a common "filter by attribute name" / EAV pattern) — was reported privately with an executed proof-of-concept and enabled filter / multi-tenant authorization bypass and blind data exfiltration.

Fixed sinks (#4911):

  • DictionaryItemMember — dictionary indexer key, e.g. Where(x => x.Attributes[key] == v)
  • DictionaryContainsKeyFilterDictionary.ContainsKey(key) (Newtonsoft serializer + the Enum branch, which bypass System.Text.Json's quote escaping)
  • SelectParser — a constant string projected through Select(x => new { L = runtimeString })
  • DeleteAllForTenant — tenant id reaching per-tenant projection teardown (now parameterized)
  • DatabaseScopedTenantPartitions — tenant id inlined into partition DDL
  • EventLoader — per-tenant partition-pruning literal (defense-in-depth)

Each sink now escapes embedded single quotes or binds the value as a parameter; regression tests lock down every vector, and a follow-up LINQ-wide audit cleared the rest of the query hot path (full-text search, string-method translations, comparisons, IsOneOf/Contains/subset operators, and patching paths). Affected versions: 7.0.0 – 9.12.0. Also patched in 8.37.4 (8.x line) and 9.13.0.

Reported responsibly by @svenclaesson — thank you. See advisory GHSA-rfx3-98h7-v3xp (CVE pending assignment).

🛠️ Reliability — projection-coordinator shutdown drain race (#4874)

On host shutdown, the native HotCold projection coordinator could abort with ObjectDisposedException: 'Npgsql.PoolingDataSource' — the coordinator's leadership poll issued an OpenAsync against an already-disposed data source while tenancy was tearing down. This is the "case B" ordering storm reported against #4874 (distinct from the async-tenancy foundation laid in #4907, which did not resolve it).

The fix ships through the dependency updates below, with a Marten-side regression test (Bug_4874_coordinator_drain_ordering, #4912):

  • JasperFx 2.24.1 (#499/#500) — ProjectionCoordinatorBase terminates the leadership loop on a disposed data source / wrapped cancellation instead of re-polling.
  • Weasel 9.16.2 (weasel#349/#350) — AdvisoryLock guards against a disposed NpgsqlDataSource during shutdown (short-circuits while disposing and treats a disposed-pool ObjectDisposedException as a non-acquire rather than propagating).

⬆️ Dependency updates

  • JasperFx 2.24.0 → 2.24.1
  • Weasel 9.16.1 → 9.16.2
  • Weasel.EntityFrameworkCore 9.2.1 → 9.16.2 (released from its prior version hold now that the Weasel line is published)

Full changelog since 9.13.0

  • #4911 — SQL injection fix in the LINQ provider (carried into this release)
  • #4912 — regression test for the #4874 case-B coordinator-drain ordering storm
  • JasperFx 2.24.1 / Weasel 9.16.2 / EFCore 9.16.2 bump (#4874 shutdown-race fix)