CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-61685

CVE-2026-61685: SQL Injection via Dynamic Query Parameters in ReactPress

Alon Barad
Alon Barad
Software Engineer

Sep 23, 2026·9 min read·2 visits

Executive Summary (TL;DR)

Unauthenticated remote SQL injection in ReactPress prior to v3.7.0 allows attackers to execute arbitrary SQL queries by tailoring query parameter keys in API requests, exposing sensitive database contents.

An unauthenticated remote SQL injection vulnerability exists in multiple API list endpoints of ReactPress prior to version 3.7.0. The vulnerability stems from unsafe construction of TypeORM QueryBuilder conditions, where untrusted HTTP query parameter keys are interpolated directly into SQL statements as identifiers without sanitization or validation.

Vulnerability Overview

The vulnerability designated as CVE-2026-61685 (also identified via GHSA-wmw4-mw6x-6vfm) is a high-severity SQL injection flaw affecting ReactPress, an open-source content publishing platform built on the NestJS framework and utilizing the TypeORM Object-Relational Mapper (ORM). The security flaw exists within the backend REST API endpoints responsible for retrieving lists of entities, including articles, comments, files, knowledge base items, and pages. These API components process user-supplied HTTP query parameters to enable dynamic filtering and pagination.

Under normal operations, clients query these endpoints using specific search parameters to locate records. However, because the application processes arbitrary query parameter keys as database column identifiers, the vulnerability exposes a direct attack surface to unauthenticated network clients. An attacker can construct malformed HTTP requests where the query keys contain embedded SQL commands. These commands bypass standard input validation, leading to direct execution of arbitrary database queries within the context of the application's database session.

This security advisory analyzes the underlying mechanics of this vulnerability, focusing on how TypeORM processes query builder conditions and why standard parameterization fails when SQL identifiers are dynamic. Additionally, this report outlines the precise code changes implemented in the patching release, provides concrete detection strategies, and discusses remediation paths for system administrators.

Root Cause Analysis

The root cause of CVE-2026-61685 lies in the insecure pattern of iterating over untrusted object keys and directly interpolating them into TypeORM's dynamic query builder statements. In NestJS-based architectures using TypeORM, developers often utilize SelectQueryBuilder to dynamically compile complex SQL queries based on HTTP request variables. In the vulnerable versions of ReactPress, the application extracted all unknown or miscellaneous query parameters into an object wrapper named otherParams. It then iterated through the keys of this object to build filtering conditions using the .andWhere() method.

While the value of the filter was correctly bound using parameterization (e.g., via .setParameter()), the key itself was interpolated directly into the query string using JavaScript template literals (article.${key}). In SQL engines and ORMs, parameterization is designed to secure data values, not database structure identifiers such as table names, column names, or operator syntax. When TypeORM compiles a query builder statement, it treats the string passed to .andWhere() as a raw template fragment, expecting the developer to have hardcoded or validated the structure. Because the application allowed arbitrary keys from the HTTP query string to define the column identifier, it effectively permitted the client to write arbitrary SQL fragments inside the query's conditional block.

To trigger the vulnerability, an attacker does not need to bypass authentication, as the affected listing endpoints are publicly accessible to support anonymous reading of published content. When the HTTP request is parsed by the NestJS controller, Express or Fastify maps the query string parameters into a key-value dictionary. The application's service layer processes every key-value pair in this dictionary, passing any unchecked key directly into the query builder. The SQL parser in the database engine then interprets the injected SQL syntax, ignoring the remainder of the legitimate query by utilizing comment markers (such as -- or /*).

Code Analysis & Patch Walkthrough

To understand the technical manifestation of the bug, consider the vulnerable code implementation in the article service layer prior to the patch. The findAll function dynamically constructed its selection queries as follows:

// Vulnerable Code Path: server/src/modules/article/article.service.ts
if (otherParams) {
  Object.keys(otherParams).forEach((key) => {
    // DANGER: The variable 'key' is sourced directly from HTTP request parameters
    // and interpolated directly into the SQL string without validation.
    query.andWhere(`article.${key} LIKE :${key}`).setParameter(`${key}`, `%${otherParams[key]}%`);
  });
}

In this implementation, the backend trustingly maps each key to a database column. To correct this vulnerability, the vendor introduced a central validation utility in the file server/src/utils/query-whitelist.util.ts. This utility defines a strict allowlist of permissible database columns for each schema entity. Any parameter key that does not match one of these explicitly allowed strings is discarded before the query is constructed:

// Patched Code: server/src/utils/query-whitelist.util.ts
const ALLOWED_COLUMNS: Record<string, string[]> = {
  article: [
    'id', 'title', 'content', 'html', 'summary',
    'status', 'views', 'likes', 'isRecommended',
    'needPassword', 'password', 'publishAt', 'createAt', 'updateAt'
  ],
  comment: [
    'id', 'hostId', 'name', 'email', 'content', 'html', 'pass',
    'userAgent', 'createAt', 'updateAt', 'parentCommentId',
    'replyUserName', 'replyUserEmail'
  ],
  file: ['id', 'originalname', 'filename', 'url', 'type', 'size', 'createAt', 'updateAt'],
  page: ['id', 'title', 'path', 'content', 'html', 'status', 'views', 'publishAt', 'createAt', 'updateAt'],
  knowledge: [
    'id', 'title', 'content', 'html', 'summary', 'status', 'views',
    'likes', 'order', 'parentId', 'publishAt', 'createAt', 'updateAt'
  ]
};
 
export function filterByWhitelist(entity: string, params: Record<string, unknown>): Record<string, unknown> {
  const whitelist = ALLOWED_COLUMNS[entity];
  if (!whitelist) return {};
 
  const { page, pageSize, status, pass, ...otherParams } = params as Record<string, unknown>;
  const filtered: Record<string, unknown> = {};
 
  Object.keys(otherParams).forEach((key) => {
    if (whitelist.includes(key)) {
      filtered[key] = otherParams[key];
    }
  });
 
  return filtered;
}

In the patched service files, the application calls this utility to filter the query parameters. The resulting filtered object contains only validated keys, which are then safe to interpolate into the query:

// Patched Code Path: server/src/modules/article/article.service.ts
const filtered = filterByWhitelist('article', queryParams);
Object.keys(filtered).forEach((key) => {
  // SECURE: 'key' is now guaranteed to be an element of the ALLOWED_COLUMNS array
  query.andWhere(`article.${key} LIKE :${key}`).setParameter(`${key}`, `%${filtered[key]}%`);
});

While this fix successfully blocks SQL injection by sanitizing the column identifiers, it is worth noting that dynamic SQL identifier interpolation remains an anti-pattern. A more robust design would involve mapping input parameters to strongly typed Query Transfer Objects (DTOs) enforced at the controller level using class-validator, rather than sanitizing generic dictionaries downstream in the service layer.

Exploitation & Attack Methodology

Exploitation of CVE-2026-61685 requires only the ability to send HTTP GET requests to the vulnerable endpoints. Because the vulnerability is triggered via the keys of the HTTP query string, standard payload structures must be modified to fit within the parsing logic of both the HTTP server and the database engine. In a typical scenario, an attacker targeting a PostgreSQL or MySQL backend utilizes time-based blind SQL injection to extract data.

To perform a basic check, an attacker sends an HTTP request where the parameter name itself contains the injection payload, terminated by a comment character to discard the remaining programmatically appended query syntax. A conceptual payload targeting PostgreSQL is structured as follows:

GET /api/article?id=1 AND pg_sleep(5) -- =test

When processed, the key is parsed as id=1 AND pg_sleep(5) -- and the value is parsed as test. The backend service constructs the following raw SQL fragment:

article.id=1 AND pg_sleep(5) -- LIKE :id=1 AND pg_sleep(5) --

When executed by the database engine, the double hyphen (--) comments out the trailing LIKE clause and its parameter placeholder. The database engine executes the command, pausing execution for 5 seconds before returning the HTTP response. By measuring this delay, the attacker confirms the injection point. To exfiltrate database contents, such as administrator session tokens or password hashes, the attacker can execute automated tools like sqlmap with custom parameters, or utilize a custom script to perform binary search exfiltration based on time-delays or conditional page sizes (Boolean-based).

Impact Assessment & Consequences

The successful exploitation of CVE-2026-61685 leads to complete database compromise. Because the database session executes queries with the permissions of the application's database user, the attacker can read any table accessible to that user. In standard deployments, the database user possesses read and write privileges over the entire ReactPress schema, including tables storing administrator credentials, cryptographic salt values, system configuration settings, and user publication drafts.

With read access to the database, an attacker can extract bcrypt-hashed administrator passwords. While these hashes are protected by one-way hashing algorithms, they remain vulnerable to offline brute-force or dictionary attacks. If the database engine configured under ReactPress is PostgreSQL or MySQL, and the database user has elevated system privileges, the attacker could theoretically perform arbitrary file read operations (e.g., using pg_read_file or LOAD_FILE) or execute system commands depending on database engine configurations (e.g., via xp_cmdshell or user-defined functions).

Although the dynamic query building is located within read-oriented search endpoints, preventing direct data modification via standard SQL injection statements, database-specific capabilities such as stacked queries (supported by certain drivers like Postgres when configured to allow them) could enable modification or deletion of database tables. Consequently, the CVSS 3.1 rating is calculated at 7.5 (High), reflecting high confidentiality impact with low prerequisites and unauthenticated network access.

Remediation & Detection Strategies

The primary remediation strategy for CVE-2026-61685 is upgrading the ReactPress server installation to version 3.7.0 or higher. This release integrates the strict whitelist-based filtering utility across all affected modules, rendering the query parameter keys immune to SQL syntax injection. Administrators running vulnerable versions can fetch and apply the patch directly from the repository:

git fetch --tags
git checkout tags/v3.7.0
npm install
npm run build

For deployments where immediate upgrading is not possible, a manual hotfix must be implemented. Developers should create the query-whitelist.util.ts helper and refactor the findAll methods within the five affected service files: article.service.ts, comment.service.ts, file.service.ts, knowledge.service.ts, and page.service.ts to utilize the whitelist filtering utility.

To detect active exploitation attempts at the network layer, Web Application Firewalls (WAFs) should be configured with custom rules. Standard WAF rules often fail to inspect query parameter keys, focusing exclusively on parameter values. The following ModSecurity rule can be deployed to intercept malicious SQL characters inside HTTP query string keys:

SecRule ARGS_NAMES "@rx (?:\b(select|union|insert|update|delete|pg_sleep|sleep|delay)\b|--|\/\*|\*\/|'|\"|\))" \
  "id:1000001,phase:2,deny,status:400,log,msg:'SQL Injection detected in query parameter key'"

Additionally, database query logs should be monitored for syntax errors containing incomplete SQL fragments, unexpected sleep statements, or comment characters occurring within column identifier positions.

Official Patches

fecommunityStrict parameter key whitelist validation fix commit

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
EPSS Probability
0.53%
Top 56% most exploited

Affected Systems

ReactPress (fecommunity/reactpress) backend server installations running versions prior to 3.7.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
ReactPress
fecommunity
< 3.7.03.7.0
AttributeDetail
CWE IDCWE-89
Attack VectorNetwork (Unauthenticated)
CVSS v3.1 Score7.5 (High)
EPSS Score0.00535 (44.13% percentile)
ImpactConfidentiality: High, Integrity: None, Availability: None
Exploit StatusProof-of-Concept (PoC)
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-89
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The software constructs an SQL command using externally-influenced input, but it does not neutralize or incorrectly neutralizes elements that could modify the intended SQL command when it is sent to the database.

Known Exploits & Detection

AdvisoryTime-based blind SQL injection proof-of-concept description

Vulnerability Timeline

Security patch committed and version 3.7.0 released
2026-06-19
GHSA Advisory published and CVE-2026-61685 assigned
2026-09-22
NVD records modified and CVSS score calculated
2026-09-23

References & Sources

  • [1]GHSA-wmw4-mw6x-6vfm: SQL Injection in ReactPress
  • [2]ReactPress Fix Commit 78ecb70af1c021455c05fdcbe137212c70e310d6
  • [3]ReactPress Release v3.7.0
  • [4]NVD - CVE-2026-61685 Detail

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-56669
7.5

CVE-2026-56669: Remote Denial of Service via Algorithmic Complexity and Interpretation Conflict in Elysia

CVE-2026-56669 is a high-severity vulnerability in the Elysia web framework (ElysiaJS) that combines Inefficient Algorithmic Complexity (CWE-407) and an Interpretation Conflict (CWE-436). It allows remote, unauthenticated attackers to cause a complete Denial of Service (DoS) via CPU resource exhaustion using specially crafted multipart or urlencoded payloads.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 3 hours ago•CVE-2026-86065
7.5

CVE-2026-86065: Denial of Service via Resource Exhaustion in klever-go WebSocket Subscription Endpoint

Prior to version 1.7.20, the default-open WebSocket `/subscribe` endpoint in klever-go was vulnerable to remote resource exhaustion. Unauthenticated, remote attackers could crash validator and node processes by exploiting unbounded frame reads, uncapped concurrent connections, unrestricted memory allocation for subscription address keys, and a permanent memory leak in subscription map tracking on client disconnects.

Alon Barad
Alon Barad
7 views•7 min read
•about 4 hours ago•CVE-2026-82405
8.7

CVE-2026-82405: Incorrect Authorization leading to Account Takeover in klever-go

A critical incorrect authorization vulnerability (CWE-863) exists in the Go implementation of the Klever blockchain protocol (klever-go) prior to version 1.7.20. The vulnerability allows an attacker to completely replace a target account's permission set by manipulating the RecipientAddr parameter in a VM built-in function, leading to total account takeover.

Amit Schendel
Amit Schendel
8 views•5 min read
•about 6 hours ago•CVE-2026-63000
6.4

CVE-2026-63000: Cross-Site Request Forgery in REDAXO CMS Package Update API

A Cross-Site Request Forgery (CSRF) vulnerability in REDAXO CMS prior to version 5.21.2 allows unauthenticated remote attackers to trigger unauthorized package updates by exploiting an insecure default configuration in the base API class.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 7 hours ago•CVE-2026-85724
9.6

CVE-2026-85724: Pattern-ACL Wildcard Injection & Cross-Tenant Authorization Bypass in Moquette MQTT Broker

CVE-2026-85724 is a critical vulnerability in the Moquette MQTT broker (versions prior to 0.18.1) where unvalidated substitution of client identifiers and usernames into pattern-based Access Control Lists (ACLs) permits remote authenticated attackers to bypass multi-tenant boundaries and trigger a Denial of Service.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 8 hours ago•CVE-2026-88974
5.4

CVE-2026-88974: Incorrect Authorization in WPGraphQL updatePost Mutation

CVE-2026-88974 is an incorrect authorization vulnerability in the WPGraphQL plugin for WordPress. Due to a failure to perform object-level capability checks or validate status-transition requirements in the updatePost mutation handler, authenticated Contributor-level users can publish their own draft posts without editorial approval or modify their previously published posts.

Amit Schendel
Amit Schendel
9 views•7 min read