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



GHSA-JF75-Q64Q-G65R

GHSA-jf75-q64q-g65r: NoSQL Query Manipulation and Partial Authentication Bypass in Waline Server

Alon Barad
Alon Barad
Software Engineer

Oct 29, 2026·10 min read·2 visits

Executive Summary (TL;DR)

Waline versions <= 1.40.3 fail to validate the data type of the email parameter during authentication at POST /api/token. When backed by MongoDB, passing a non-string value (such as a JSON object) causes the query builder to drop the email constraint and execute an empty filter query. Because the login controller selects the first returned record—which corresponds to the primary site administrator—an attacker can perform targeted password guessing or credential stuffing against the administrator account without knowing its email address.

An improper input validation and NoSQL query construction vulnerability exists in the Waline comment system server (@waline/vercel) version 1.40.3 and earlier. When MongoDB is used as the backend storage engine, the POST /api/token authentication endpoint fails to validate that the user-supplied email parameter is a string. Supplying a JSON object or array operator causes the MongoDB storage adapter to omit the email filter or construct an unintended match-all query, returning all user records and allowing unauthenticated attackers to target the site administrator account directly without knowing the administrator's email address.

Vulnerability Overview

Waline is an open-source comment system featuring a server component (@waline/vercel, located in packages/server of the walinejs/waline monorepo) built on top of the ThinkJS Node.js framework. The server supports multiple database backends—including SQLite, MySQL, PostgreSQL, and MongoDB—through custom storage adapter services. User authentication for comment moderation and site administration is handled via the POST /api/token REST endpoint, which processes inbound JSON credentials and issues JSON Web Tokens (JWTs) upon successful verification.

In @waline/vercel versions 1.40.3 and earlier, the authentication routine exhibits an improper authentication weakness (CWE-287) coupled with improper neutralization of special elements in data query logic (CWE-943). Specifically, the TokenLogic and TokenController modules accept deserialized JSON parameters from the request body without verifying that the email field is a primitive string before passing it to the database abstraction layer.

When the application is configured to use MongoDB as its backing store, passing a non-string value—such as a nested JSON object ({"$ne": null}) or a two-element array (["!=", ""])—alters the query construction behavior inside packages/server/src/service/storage/mongodb.js. If an arbitrary object is supplied, the query builder fails to match any expected type branch and silently drops the email filter key, resulting in an empty MongoDB filter ({}). If a formatted array is supplied, the adapter translates it into an explicit inequality filter.

Executing an unconstrained db.users.find({}) query returns the entire collection of registered users in natural insertion order. Because the login controller unconditionally evaluates the password hash against the first element of the result array (user[0]), and because Waline assigns administrator privileges to the first registered user during initial setup, any authentication attempt using a non-string email parameter deterministically targets the site administrator account. This eliminates the requirement for an attacker to discover the administrator's email address prior to conducting password guessing or credential stuffing attacks.

Root Cause Analysis

The root cause of GHSA-jf75-q64q-g65r spans three distinct layers of the Waline server architecture: missing type validation in the ThinkJS logic layer, permissive fallback behavior in the MongoDB storage service's query parser, and unsafe array indexing in the authentication controller.

In ThinkJS applications, incoming request validation is handled by a Logic class that executes prior to the corresponding Controller action. Prior to version 1.41.0, the postAction() method in packages/server/src/logic/token.js only invoked await this.useCaptchaCheck() and defined no schema rules (this.rules) for the request payload. When a client sends an HTTP POST request with Content-Type: application/json, the framework's body parser deserializes the payload into native JavaScript types. Consequently, this.post() in packages/server/src/controller/token.js extracts email regardless of whether it is a string, object, or array, and passes { email } directly to this.modelInstance.select({ email }).

Within the MongoDB storage adapter (packages/server/src/service/storage/mongodb.js), the parseWhere() method iterates over the properties of the where object to construct a MongoDB filter dictionary. For each key k, the method checks three primary conditions:

  1. if (think.isString(where[k])): Appends a strict equality match { $eq: where[k] } to the filter.
  2. if (where[k] === undefined): Skips the field.
  3. if (Array.isArray(where[k]) && where[k][0]): Parses custom query operators such as IN, LIKE, !=, or comparison operators.

There is no else branch or type assertion to reject unexpected data types. When an attacker provides a plain JavaScript object such as {"email": {"$ne": null}}, all three conditional checks evaluate to false. The loop completes without adding an email key to the filter object, causing the adapter to execute instance.where({}) against the MongoDB collection. Alternatively, if the attacker supplies a two-element array such as ["!= ", ""], the third branch is entered, translating the input into a MongoDB inequality query that similarly matches all user documents.

Once select() returns the full array of user documents from MongoDB, TokenController.postAction() checks if (think.isEmpty(user) || isVerifyUser || isBannedUser). Because at least one user exists in an initialized instance, think.isEmpty(user) evaluates to false. The controller then immediately executes this.checkPassword(password, user[0].password), implicitly assuming that a query on a unique email attribute could only return a single matching user record.

Code Analysis

Examining the vulnerable implementation across the controller and storage layers illustrates how untyped input propagates into database query execution. In packages/server/src/controller/token.js, the controller retrieves request parameters and queries the user model without defensive checks on the parameter types or the cardinality of the returned result set:

// packages/server/src/controller/token.js (Vulnerable Path)
const { email, password, code } = this.post();
// If email is an object, { email } passes an object into the query builder
const user = await this.modelInstance.select({ email });
 
if (think.isEmpty(user) || isVerifyUser || isBannedUser) {
  return this.fail();
}
 
// Unconditionally selects the first document returned by the database
const checkPassword = this.checkPassword(password, user[0].password);

When this.modelInstance.select({ email }) is invoked on a MongoDB-backed deployment, execution reaches parseWhere() in packages/server/src/service/storage/mongodb.js:

// packages/server/src/service/storage/mongodb.js
if (think.isString(where[k])) {
  filter[parseKey(k)] = { $eq: where[k] };
  continue;
}
if (where[k] === undefined) {
  // skip undefined fields
}
if (Array.isArray(where[k]) && where[k][0]) {
  // operator handling (IN / LIKE / != / > ...)
}
// Missing fallback: Objects fall through silently without modifying `filter`

In commit e611aed4e571c2a86103f5cee48791ca6b460360 (Pull Request #3646), the maintainers remediated the vulnerability at the validation boundary in packages/server/src/logic/token.js. By defining this.rules inside TokenLogic.postAction(), ThinkJS intercepts the request before TokenController.postAction() is invoked:

--- a/packages/server/src/logic/token.js
+++ b/packages/server/src/logic/token.js
@@ -35,6 +35,17 @@ module.exports = class TokenLogic extends Base {
    * @apiSuccess (200) {String}  errmsg  return error message if error
    */
   async postAction() {
+    this.rules = {
+      email: {
+        required: true,
+        email: true, // Enforces string type and valid email format
+      },
+      password: {
+        required: true,
+        string: true, // Enforces string type for password
+      },
+    };
+
     await this.useCaptchaCheck();
   }

> [!NOTE] > Assessment of Fix Completeness: The patch in packages/server/src/logic/token.js effectively prevents GHSA-jf75-q64q-g65r on the POST /api/token endpoint because ThinkJS's email: true validator strictly requires the value to be a string matching a standard email regular expression. Non-string inputs (objects, arrays, numbers) immediately trigger validation error 1001 before reaching the controller or storage layer. However, the underlying parseWhere() implementation in packages/server/src/service/storage/mongodb.js was not modified in commit e611aed4e571c2a86103f5cee48791ca6b460360. Consequently, any other controller endpoint that passes unvalidated user input directly to modelInstance.select(), update(), or delete() without corresponding Logic rules remains susceptible to similar filter-dropping or array-operator injection behavior when running on MongoDB.

Exploitation

Exploiting GHSA-jf75-q64q-g65r requires network access to the Waline server's HTTP API (POST /api/token) and requires that the target instance is configured to use MongoDB as its database provider (configured via MONGO_DB environment variables). No prior authentication, session tokens, or knowledge of registered user email addresses is required.

To trigger the match-all query, an attacker sends an HTTP POST request with a Content-Type: application/json header where the email field is set to a JSON object instead of a string. A minimal proof-of-concept request takes the following form:

POST /api/token HTTP/1.1
Host: target-waline-instance.example.com
Content-Type: application/json
Accept: application/json
 
{
  "email": {
    "$ne": null
  },
  "password": "CandidatePassword123!"
}

Note that because parseWhere() ignores all non-array objects, the contents of the email object do not need to be valid MongoDB operators; even an empty JSON object ("email": {}) will cause think.isString() and Array.isArray() to return false, resulting in the exact same empty {} filter query against the Users collection.

When the server processes this payload, three distinct operational impacts occur:

  1. Bypassing the Non-Existent User Branch: Under normal operation with an unknown email string, select({ email }) returns an empty array [], causing think.isEmpty(user) to return true and immediately terminating the request before password hashing occurs. With `

Impact Assessment

The severity of GHSA-jf75-q64q-g65r is rated as Medium with a CVSS v3.1 base score of 6.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N). The vulnerability is exploitable over the network (AV:N) with low attack complexity (AC:L), requiring no privileges (PR:N) and no user interaction (UI:N).

The primary security impact is the degradation of the authentication mechanism from a two-factor knowledge requirement (valid administrator email address + valid administrator password) to a single-factor requirement (valid administrator password only). In standard Waline deployments, administrator email addresses may not be publicly exposed if the administrator does not post public comments or if email hashes are obfuscated. By forcing the backend to query db.users.find({}) and select user[0], an attacker deterministically targets the primary administrator account created during system initialization.

Furthermore, this flaw enables unauthenticated user state discovery and brute-force amplification. By observing response timings and status codes when submitting {"email": {"$ne": null}}, an attacker can confirm whether the target Waline instance uses MongoDB and has at least one active, verified, non-banned user account (as BCrypt password verification via this.checkPassword() is only executed when user[0] exists and passes verification/ban checks). If an attacker successfully guesses or stuffs the administrator's password, the /api/token endpoint returns a valid JWT signed with the server's JWT_TOKEN secret.

Possession of an administrator JWT grants complete control over the Waline comment moderation interface. An authenticated administrator can read private user metadata (including real email addresses and IP addresses of all commenters), approve or delete arbitrary comments, modify user roles, and ban legitimate users, resulting in measurable impacts to both application confidentiality (C:L) and data integrity (I:L).

Remediation

Site operators and developers using Waline must upgrade the server package @waline/vercel to version 1.41.0 or later. Version 1.41.0 incorporates commit e611aed4e571c2a86103f5cee48791ca6b460360, which enforces strict schema validation on POST /api/token via ThinkJS Logic rules, ensuring that requests containing missing, non-string, or improperly formatted email or password parameters are rejected with error code 1001 prior to database query generation.

To upgrade a standard deployment managed via npm, run the following command and redeploy the serverless function or Node.js container:

npm install @waline/vercel@^1.41.0

For organizations maintaining custom forks of walinejs/waline or custom ThinkJS storage adapters, two defense-in-depth measures are recommended beyond applying the TokenLogic rules:

  1. Strict Type Enforcement in parseWhere(): Modify packages/server/src/service/storage/mongodb.js so that unrecognized data types (such as plain objects or booleans) throw an explicit exception or coerce values to strings rather than silently omitting the key from the MongoDB filter object.
  2. Enable Captcha and Rate Limiting: Configure Waline's built-in Captcha verification (TURNSTILE_KEY / RECAPTCHA_V3_KEY) and deploy upstream rate limiting on /api/token to mitigate automated credential stuffing against the authentication endpoint.

If immediate patching is not feasible, administrators can deploy a Web Application Firewall (WAF) or reverse proxy rule to inspect inbound POST bodies directed at /api/token and block requests where the email attribute contains nested JSON objects ({...}) or arrays ([...]).

Official Patches

walinejsPull Request #3646 enforcing token validation rules and regression test suite
walinejsOfficial patch commit e611aed4e571c2a86103f5cee48791ca6b460360

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Affected Systems

@waline/vercelwalinejs/waline (packages/server)

Affected Versions Detail

Product
Affected Versions
Fixed Version
@waline/vercel
walinejs
<= 1.40.31.41.0
AttributeDetail
Vulnerability IDGHSA-jf75-q64q-g65r
Weakness ClassCWE-287 (Improper Authentication) / CWE-943 (NoSQL Injection)
Attack VectorNetwork (HTTP POST to /api/token)
CVSS v3.1 Score6.5 Medium (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N)
Affected Component@waline/vercel <= 1.40.3 (with MongoDB storage)
Patched Version@waline/vercel 1.41.0
ImpactPartial authentication bypass (factor elimination) and targeted admin credential stuffing
Exploit StatusProof-of-Concept (PoC) Publicly Documented

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1110.004Brute Force: Credential Stuffing
Credential Access
T1110.001Brute Force: Password Guessing
Credential Access
T1087.002Account Discovery: Domain Account
Discovery
T1078.004Valid Accounts: Cloud Accounts
Defense Evasion
CWE-287
Improper Authentication

When an actor claims to have a given identity, the software does not prove or insufficiently proves that the claim is correct, combined with CWE-943 (Improper Neutralization of Special Elements in Data Query Logic).

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory containing proof-of-concept explanation demonstrating non-string email parameter handling in MongoDB deployments.

Vulnerability Timeline

Pull Request #3646 merged with fix commit e611aed4e571c2a86103f5cee48791ca6b460360 adding input validation rules to TokenLogic.
2026-06-14
GitHub Security Advisory GHSA-jf75-q64q-g65r published and reviewed.
2026-10-28

References & Sources

  • [1]GitHub Advisory Record: GHSA-jf75-q64q-g65r
  • [2]Waline Repository Security Advisory: GHSA-jf75-q64q-g65r
  • [3]Fix Pull Request #3646
  • [4]Fix Commit e611aed4e571c2a86103f5cee48791ca6b460360
  • [5]Reporter Credit Profile (dizconnectz)

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

•23 minutes ago•CVE-2026-116581
7.5

CVE-2026-116581: Unauthenticated Event-Loop Denial of Service via Unvalidated Sequence Indices in Seroval

Seroval, a JavaScript serialization library used for transferring complex structures across network boundaries, contains an input validation vulnerability in versions prior to 1.6.8. The `fromJSON` and `fromCrossJSON` deserializers fail to validate array element lists and the termination boundaries (`done` and `throw` indices) of sequence nodes. By supplying out-of-bounds indices or forged array-like structures, an unauthenticated remote attacker can construct an iterator with an unreachable exit condition or trigger excessive loop iterations, halting the single-threaded JavaScript event loop and causing a denial of service.

Amit Schendel
Amit Schendel
2 views•10 min read
•about 1 hour ago•CVE-2026-116582
4.7

CVE-2026-116582: Cross-Site Scripting via Unescaped RegExp Serialization in Seroval

CVE-2026-116582 is an improper output escaping vulnerability in the Seroval JavaScript serialization library that leads to cross-site scripting (XSS). When Seroval serializes RegExp objects into executable JavaScript literals for embedding in HTML script elements, it fails to neutralize the less-than character ('<'). If an application constructs a regular expression from untrusted input and embeds the serialized output inside an inline script block during server-side rendering (SSR), an attacker can inject a closing script tag to break out of the JavaScript context and execute arbitrary client-side code.

Amit Schendel
Amit Schendel
2 views•11 min read
•about 2 hours ago•CVE-2026-116583
5.3

CVE-2026-116583: Code Injection via TypedArray Constructor Property Spoofing in Seroval

CVE-2026-116583 (GHSA-f86p-h4j2-7qgj) is a code injection and cross-site scripting (XSS) vulnerability in Seroval, a JavaScript object serialization library. In versions 1.6.0 prior to 1.6.11, Seroval derives the constructor name of a TypedArray directly from the `current.constructor.name` property expression during serialization. If an attacker supplies untrusted properties that are merged onto a TypedArray instance, an own `constructor` property overrides the prototype property and gets emitted unescaped after the `new` keyword in the generated JavaScript output. Evaluating or rendering this output in a browser or JavaScript runtime results in arbitrary code execution.

Alon Barad
Alon Barad
3 views•8 min read
•about 4 hours ago•GHSA-2HW4-C9M4-F2FJ
6.5

CVE-2026-54462: Unbounded Request-Body Memory Exhaustion in Knative Admission Webhooks

An uncontrolled resource consumption vulnerability in the knative.dev/pkg/webhook package allows network-adjacent attackers within a Kubernetes cluster to trigger Out-Of-Memory (OOM) terminations of admission controller pods. The admission webhook HTTP server processes incoming AdmissionReview requests through an io.TeeReader and json.Decoder pipeline without enforcing an upper bound on request body size. Due to internal buffer reallocation mechanics, incoming payloads experience a 4.5x memory amplification factor. Because knative.dev/pkg provides the shared webhook server foundation for numerous cloud-native projects—including Knative Serving, Knative Eventing, Tekton, KEDA, Sigstore Policy Controller, and Kpack—exploitation can halt resource admission across entire Kubernetes clusters or bypass critical security validation policies.

Alon Barad
Alon Barad
3 views•10 min read
•about 5 hours ago•CVE-2026-115923
6.5

CVE-2026-115923: Path Traversal and Catalog Rule Bypass in Backstage Catalog Backend

CVE-2026-115923 (GHSA-w658-mh9p-ww8f) is a path traversal and access control bypass vulnerability in Spotify's Backstage developer portal framework, specifically within the @backstage/plugin-catalog-backend package. Prior to patched versions, DefaultCatalogRulesEnforcer evaluated user-supplied URL catalog locations against configured catalog.rules patterns using raw, uncanonicalized strings. Because downstream URL readers canonicalize URLs and resolve dot segments before fetching resources, an authenticated attacker with location registration permissions can supply percent-encoded traversal sequences (such as %2e%2e) to bypass location restrictions and register untrusted catalog entities.

Amit Schendel
Amit Schendel
5 views•9 min read
•about 6 hours ago•CVE-2026-116576
7.8

CVE-2026-116576: OS Command Injection via Unicode Quotation Marks in Node.js systeminformation

CVE-2026-116576 (GHSA-3f7j-7jwc-fxfj) is an OS Command Injection vulnerability (CWE-78) in the Node.js systeminformation library prior to version 5.33.16 on Microsoft Windows. The services() API function dynamically constructs a PowerShell Get-CimInstance command using caller-supplied service names passed through sanitizeShellString(). While the sanitizer strips standard ASCII quotation marks, it permits Unicode typographic quotation marks (U+2018 through U+201E). Because the Windows PowerShell tokenizer recognizes Unicode quotation marks as valid string literal delimiters, an attacker who controls the service name input can break out of the CIM filter string and execute arbitrary PowerShell commands within the security context of the Node.js process.

Alon Barad
Alon Barad
6 views•11 min read