Marten 9.14.0
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)DictionaryContainsKeyFilter—Dictionary.ContainsKey(key)(Newtonsoft serializer + the Enum branch, which bypass System.Text.Json's quote escaping)SelectParser— a constant string projected throughSelect(x => new { L = runtimeString })DeleteAllForTenant— tenant id reaching per-tenant projection teardown (now parameterized)DatabaseScopedTenantPartitions— tenant id inlined into partition DDLEventLoader— 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) —
ProjectionCoordinatorBaseterminates the leadership loop on a disposed data source / wrapped cancellation instead of re-polling. - Weasel 9.16.2 (weasel#349/#350) —
AdvisoryLockguards against a disposedNpgsqlDataSourceduring shutdown (short-circuits while disposing and treats a disposed-poolObjectDisposedExceptionas 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)