critical · 9.8CVE-2026-69240Aug 3, 2026

CVE-2026-69240: Sequelize SQL Injection via Oracle TO_DATE/TO_TIMESTAMP Bypass

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Sequelize's Oracle dialect skips quote-escaping for strings that start with TO_DATE or TO_TIMESTAMP, letting an attacker inject arbitrary SQL through any user-controlled query parameter.

Packagesequelize
Ecosystemnpm
Affected< 6.37.4
Fixed in6.37.4
CVE-2026-69240: Sequelize SQL Injection via Oracle TO_DATE/TO_TIMESTAMP Bypass

The problem

In Sequelize's sql-string.js, the escape() function has a special Oracle branch that returns the raw string value, without any escaping, when that value begins with TO_TIMESTAMP or TO_DATE. This was added to support Oracle date literals, but it trusts the full input string uncritically.

Any user-controlled value passed into a Sequelize where clause is affected. An attacker can prefix their payload with TO_DATE( or TO_TIMESTAMP( and append arbitrary SQL after the closing parenthesis. No authentication is required. The impact is full read and write access to the database.

Proof of concept

A working proof-of-concept for CVE-2026-69240 in sequelize, with the exact payload below.

http
GET /students?firstName=TO_DATE('0','Y')||''%20OR%201=1-- HTTP/1.1
Host: target.example.com

-- Resulting SQL executed by Sequelize:
-- SELECT ... WHERE "Student"."firstName" = TO_DATE('0','Y')||'' OR 1=1-- ORDER BY "Student"."id" OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;

The root cause (CWE-89) is an unconditional early-return in the Oracle escape branch: if (val.startsWith('TO_TIMESTAMP') || val.startsWith('TO_DATE')) { return val; }. Because the entire string is returned verbatim, the concatenation operator || and the boolean clause OR 1=1-- pass straight into the final SQL, bypassing Sequelize's normal single-quote doubling.

The patch (commit 5deadd2) adds strict format validation so that only well-formed, expected date/timestamp literals are returned unescaped. Any string that matches the prefix but does not conform to the expected literal format is now run through the normal escaping path, closing the injection vector.

The fix

Upgrade to sequelize >= 6.37.4. The fix is in commit 5deadd2410ae9136a21fb652db206d27bb715f26. If you cannot upgrade immediately, avoid passing unvalidated user input directly into Sequelize where clauses, and add an allowlist check on any field that could receive Oracle date-function strings.

Reporter not attributed.

References: [1][2][3][4]

Related research