Executive Summary
A critical SQL injection vulnerability (CVE-2026-45288) has been disclosed in Marten, the popular .NET library that provides a transactional document database and event store on top of PostgreSQL. The vulnerability exists in Marten's full-text search APIs, which interpolate a user-supplied regConfig parameter directly into generated SQL queries without parameterization or validation.
CVSS Score: 9.8 (Critical)
Any application that exposes Marten's regConfig parameter to untrusted user input — through API query parameters, form fields, or other user-controlled data paths — is vulnerable to SQL injection. This can lead to unauthorized data access, data manipulation, and potentially remote code execution depending on PostgreSQL configuration and permissions.
The fix is available in Marten 8.36.1. Applications using any version prior to 8.36.1 that expose regConfig to user input should treat this as an emergency patching requirement.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-45288 |
| CVSS Score | 9.8 (Critical) |
| Type | SQL Injection (CWE-89) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | None |
| Confidentiality Impact | High |
| Integrity Impact | High |
| Availability Impact | High |
| Affected Library | Marten (JasperFx/marten) |
| Fixed In | Marten 8.36.1 |
Affected Products
| Product | Affected Versions | Remediation |
|---|---|---|
| Marten (.NET) | All versions prior to 8.36.1 | Upgrade to Marten 8.36.1 or later |
Technical Analysis
What Is Marten?
Marten is a widely used open-source .NET library that turns PostgreSQL into a document database and event store. It is used in production systems across financial services, healthcare, SaaS platforms, and enterprise .NET applications. Marten provides:
- Document storage via PostgreSQL's JSONB column type
- Event sourcing capabilities with an append-only event log
- LINQ-based querying of documents
- Full-text search using PostgreSQL's built-in text search capabilities
Marten's full-text search features allow developers to query documents using PostgreSQL's tsvector and tsquery functions, with regConfig being the text search configuration parameter (e.g., 'english', 'simple', 'french') that controls language-specific tokenization and stemming.
Root Cause
The vulnerability stems from Marten's full-text search query generation code interpolating the regConfig parameter directly into the SQL string rather than using parameterized queries:
// VULNERABLE pattern (simplified representation)
// regConfig is interpolated directly without sanitization
var sql = $"WHERE to_tsvector('{regConfig}', d.data->>'content') @@ to_tsquery('{query}')";
// If regConfig = "english') OR 1=1--" — classic SQL injectionBecause PostgreSQL's to_tsvector and related functions require regConfig to be a literal cast to the regconfig type rather than a parameter placeholder, naive string interpolation creates a direct SQL injection vector.
Every code path in Marten that exposes the regConfig parameter to untrusted data is affected. This includes:
SearchInto<T>()full-text search LINQ methodsPlainTextSearch()andPhraseSearch()variants that accept a configuration argument- Any custom query builder code that passes a user-controlled value as
regConfig
Exploitation Scenario
// Example: ASP.NET Core API endpoint passing user input to Marten full-text search
[HttpGet("search")]
public async Task<IActionResult> Search(string query, string language = "english")
{
// VULNERABLE: 'language' parameter flows from HTTP request into regConfig
var results = await _session.Query<Article>()
.Where(x => x.PlainTextSearch(query, language)) // language = regConfig
.ToListAsync();
return Ok(results);
}An attacker can send a crafted HTTP request:
GET /api/search?query=test&language=english%27)%3B+DROP+TABLE+mt_doc_article%3B--The malicious language parameter injects SQL that can:
- Extract data from other tables in the PostgreSQL database
- Modify or delete data including documents and event streams
- Execute PostgreSQL functions that read files or execute OS commands (if
pg_read_file,COPY TO/FROM, orplpython3uare accessible) - Bypass application-level authorization by accessing data across tenants
Fix in Marten 8.36.1
The fix validates regConfig against PostgreSQL's known text search configuration catalog before interpolating, and where possible uses explicit casting instead of string interpolation:
// FIXED pattern — validate regConfig against pg_ts_config
// Reject any value that is not a registered text search configuration name
var allowedConfigs = GetRegisteredTsConfigs(connection); // SELECT cfgname FROM pg_ts_config
if (!allowedConfigs.Contains(regConfig))
throw new ArgumentException($"Invalid text search configuration: {regConfig}");Impact Assessment
| Impact Area | Description |
|---|---|
| Data Exfiltration | Read access to all data in the PostgreSQL database, not just the Marten document store |
| Data Manipulation | Insert, update, or delete documents, events, and data in other tables |
| Cross-Tenant Data Access | In multi-tenant Marten deployments, bypass tenant isolation to access other tenants' data |
| PostgreSQL Escalation | Depending on database user permissions, may be able to read files, execute OS commands, or create backdoor users |
| Event Store Tampering | Marten event stores used in event-sourced architectures may have audit trails corrupted |
| Application Compromise | Secondary injection into application code via crafted data persisted through the exploit |
Immediate Remediation
Step 1: Upgrade Marten to 8.36.1
Update Marten via NuGet immediately:
# .NET CLI
dotnet add package Marten --version 8.36.1
# Package Manager Console (Visual Studio)
Install-Package Marten -Version 8.36.1
# Verify the update
dotnet list package | grep MartenStep 2: Audit Code for regConfig Exposure
While upgrading, audit all uses of Marten full-text search for regConfig exposure:
// Search your codebase for these patterns where regConfig comes from user input
// PlainTextSearch with a config argument
.PlainTextSearch(query, regConfig)
// PhraseSearch with a config argument
.PhraseSearch(query, regConfig)
// WebStyleSearch with a config argument
.WebStyleSearch(query, regConfig)
// SearchInto with a config argument
.SearchInto<T>(query, regConfig)For each occurrence, verify that regConfig is a hardcoded string constant, not a value derived from user input.
Step 3: Input Validation Workaround (Pre-Patch)
If immediate upgrade is not possible, add explicit input validation:
// Whitelist approach — only allow known-good PostgreSQL text search config names
private static readonly HashSet<string> AllowedConfigs = new(StringComparer.OrdinalIgnoreCase)
{
"simple", "arabic", "armenian", "basque", "catalan", "danish", "dutch",
"english", "finnish", "french", "german", "greek", "hindi", "hungarian",
"indonesian", "irish", "italian", "lithuanian", "nepali", "norwegian",
"portuguese", "romanian", "russian", "serbian", "spanish", "swedish",
"tamil", "turkish", "yiddish"
};
public string ValidateRegConfig(string regConfig)
{
if (!AllowedConfigs.Contains(regConfig))
throw new ArgumentException($"Unsupported text search configuration: {regConfig}");
return regConfig;
}Step 4: Review PostgreSQL Database Permissions
Restrict the PostgreSQL user Marten connects with to minimize exploitation impact:
-- Review current permissions on the Marten database user
SELECT grantee, privilege_type, table_name
FROM information_schema.role_table_grants
WHERE grantee = 'marten_app_user';
-- Revoke any unnecessary superuser or file access privileges
REVOKE SUPERUSER FROM marten_app_user;
REVOKE pg_execute_server_program FROM marten_app_user;
REVOKE pg_read_server_files FROM marten_app_user;
-- Restrict to only the tables Marten needs
-- (principle of least privilege)Detection Indicators
| Indicator | Description |
|---|---|
Unexpected SQL errors in application logs containing regconfig cast failures | Probe attempts or failed exploitation |
Full-text search API calls with non-language regConfig values | Injection attempt — valid values are language names like english, french |
Unusual PostgreSQL query patterns in pg_stat_activity | Active exploitation or reconnaissance |
| Database queries accessing tables outside the Marten schema | Post-exploitation data access |
Unexpected PostgreSQL function calls to pg_read_file or COPY | Privilege escalation attempt |
Post-Remediation Checklist
- Upgrade all Marten installations to 8.36.1 across all environments (dev, staging, production)
- Audit application code for all full-text search call sites where
regConfigis user-controlled - Review PostgreSQL audit logs for evidence of SQL injection exploitation before the patch
- Check PostgreSQL
pg_stat_statementsfor unusual query patterns that may indicate prior exploitation - Rotate database credentials used by Marten-connected applications
- Review data access logs in multi-tenant deployments for cross-tenant access indicators
- Run database integrity checks to verify no data has been tampered with
- Update integration tests to add regression tests for this injection vector
- Notify your DPO if personal data in the Marten document store may have been accessed