Aug 4, 2026·6 min read·5 visits
Sequelize versions prior to 6.37.4 fail to escape single quotes when string inputs start with TO_DATE or TO_TIMESTAMP, leading to critical SQL injection in applications using the Oracle dialect.
A critical SQL injection vulnerability was discovered in Sequelize when configured to use the Oracle database dialect. Due to a flawed optimization design in the SQL escaping subsystem (src/sql-string.js), strings that begin with native Oracle date functions bypass standard escaping. This allows unauthenticated remote attackers to execute arbitrary SQL commands on the target database.
Sequelize is an object-relational mapper (ORM) for Node.js that simplifies interaction with relational databases by abstracting SQL query generation. Applications leverage Sequelize to interact with multiple SQL dialects, including MySQL, PostgreSQL, SQLite, MSSQL, and Oracle. To prevent SQL injection, Sequelize handles automatic parameter escaping and binding of user input within its internal query generation workflows. This abstraction establishes a secure trust boundary between application input and database execution.\n\nThe security boundary is compromised when Sequelize utilizes the Oracle database dialect. A flaw within the escaping subsystem in src/sql-string.js permits certain input strings to bypass standard escaping processes entirely. Specifically, inputs designed to mimic native Oracle SQL function calls—specifically TO_DATE and TO_TIMESTAMP—are handled improperly by the SQL string generation logic.\n\nAn attacker can craft string inputs that trigger an early escape bypass check. Because the escaping routines yield unescaped characters directly to the query compiler, the database driver processes injected SQL commands. This bypass facilitates unauthenticated remote SQL injection (SQLi) against Oracle database servers, completely subverting the ORM security controls.
The root cause of this vulnerability lies in the implementation of the string escaping logic within src/sql-string.js for the Oracle dialect. In Sequelize, strings are passed to dialect-specific formatting routines. The Oracle database supports specific native operations, such as dates formatted using the TO_DATE or TO_TIMESTAMP functions, which require their literal arguments to remain intact during standard serialization.\n\nTo accommodate these functional date literals without wrapping them in an extra layer of single quotes, the developers designed an optimization conditional. The conditional evaluates if a string value begins with the prefix TO_TIMESTAMP or TO_DATE. If this validation succeeds, the routine concludes that the string is a system-generated date function call, bypasses the standard single-quote escaping mechanism, and returns the raw string.\n\nThe vulnerability manifests because the input check is performed using the JavaScript .startsWith() string method directly on the unvalidated parameter. Because this parameter may originate from user-controlled HTTP request data, the function cannot differentiate between a legitimate internal query component and a malicious external string prefixed with TO_DATE or TO_TIMESTAMP. Consequently, any user input starting with these prefixes is passed directly into the SQL statement without the single quotes being escaped into double single quotes.
Comparing the vulnerable and patched implementations of escape in src/sql-string.js reveals how the flaw was introduced and resolved. In the vulnerable version, the engine executed an insecure conditional:\n\njavascript\n} else if (dialect === 'oracle' && typeof val === 'string') {\n if (val.startsWith('TO_TIMESTAMP') || val.startsWith('TO_DATE')) {\n return val;\n }\n val = val.replace(/'/g, \"''\");\n}\n\n\nThis check fails to evaluate the structure of the string beyond the initial prefix. This allows arbitrary SQL characters to append the matched prefix.\n\nThe patch replaces this simple conditional check with a strict parser validation block. The updated version ensures that the string strictly represents a safe date function structure and contains no external characters.\n\njavascript\nif (val.startsWith('TO_TIMESTAMP_TZ') || val.startsWith('TO_DATE')) {\n const splitVal = val.split(/\\(|\\)/);\n if (splitVal.length !== 3 || splitVal[2] !== '') {\n throw new Error('Invalid SQL function call.');\n }\n const functionName = splitVal[0].trim();\n const insideParens = splitVal[1].trim();\n if (functionName !== 'TO_TIMESTAMP_TZ' && functionName !== 'TO_DATE') {\n throw new Error('Invalid SQL function call. Expected TO_TIMESTAMP_TZ or TO_DATE.');\n }\n const params = insideParens.split(',');\n if (params.length !== 2) {\n throw new Error('Unexpected input received.');\n }\n}\n\n\nThis implementation secures the path in multiple ways. First, splitting the string by parentheses ensures that there is only one open and close set of parentheses, and that no code follows the function call. Second, it strictly enforces that exactly two arguments are provided within the parameters. Third, it validates both parameters using Moment.js to confirm that the input string matches expected datetime syntax. This effectively blocks any arbitrary SQL injection characters within the parameters.
To exploit the vulnerability, an attacker must identify an input field that is used directly within a Sequelize model query, such as a where filter condition, under an environment configured for Oracle. The application must pass the user input as a string type to the query builder. This is common in simple query patterns where developers pass input directly without using custom bind variables.\n\nmermaid\ngraph LR\n Attacker([\"Attacker Payload\"]) -->|HTTP Request| AppServer[\"Application Server\"]\n AppServer -->|Unvalidated Input| Sequelize[\"Sequelize ORM Engine\"]\n Sequelize -->|Regex/starts_with Bypass| SQLGen[\"SQL String Generator\"]\n SQLGen -->|Raw SQL String Injection| OracleDB[(\"Oracle Database Server\")]\n\n\nThe attacker supplies a payload starting with TO_DATE or TO_TIMESTAMP. For example, the string TO_DATE('0','Y')||'' OR 1=1-- is supplied as a search parameter. The input bypasses the escaping conditional check because it matches val.startsWith('TO_DATE'). Standard escaping of single quotes is skipped.\n\nThe raw payload is concatenated into the SQL statement template. The query compiler generates the execution statement: SELECT * FROM USERS WHERE username = 'TO_DATE('0','Y')||'' OR 1=1--'. The Oracle database parses 'TO_DATE(' as a string literal, performs concatenation using the || operator, and processes the subsequent malicious OR 1=1 statement. The trailing -- comment strips the final string literal delimiter, preventing database syntax errors and altering the logical flow of the query.
The impact of successful exploitation is critical, carrying a CVSS score of 9.8. This vulnerability allows unauthenticated, remote attackers to execute arbitrary SQL commands on the underlying Oracle database server. The scope of impact depends on the configuration and privileges of the database user account that Sequelize uses to connect.\n\nIn a standard configuration, SQL injection allows attackers to bypass application authentication mechanisms entirely. It grants full read permissions to the connected database tables, enabling unauthorized extraction of sensitive information, such as passwords, personal data, and business secrets. Attackers can also modify database tables, including updating records, inserting malicious admin accounts, or executing data deletion commands.\n\nDepending on the database schema and account permissions, an attacker may also be able to interact with administrative procedures. On Oracle database installations, advanced database privileges may permit attackers to write to the underlying file system or execute system commands, potentially moving from database compromise to complete host operating system compromise.
The primary and recommended remediation is to upgrade Sequelize to version 6.37.4 or higher, which replaces the weak validation routine with robust AST-style checking. If immediate upgrade is not feasible, developers must implement secondary input validation layers. Any string starting with TO_DATE or TO_TIMESTAMP (case-insensitive) should be blocked or stripped before passing it to Sequelize query parameters.\n\nbash\n# Upgrade package to patched release\nnpm install sequelize@6.37.4\n\n\nNetwork and host-based detection mechanisms can identify exploitation attempts. Web Application Firewalls (WAFs) should be configured with custom rules to inspect incoming query and post parameters. Rules must detect inputs starting with TO_DATE or TO_TIMESTAMP coupled with concatenation operators or logical conditions like OR and AND.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
sequelize Sequelize | < 6.37.4 | 6.37.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 |
| Attack Vector | Network (AV:N) |
| Attack Complexity | Low (AC:L) |
| Privileges Required | None (PR:N) |
| User Interaction | None (UI:N) |
| Impact | Confidentiality, Integrity, Availability (High) |
| Exploit Status | Proof of Concept (PoC) available |
| KEV Status | Not listed |
The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream database component.
GitPython prior to version 3.1.56 is vulnerable to argument injection in the Commit.count method. An attacker who controls keyword arguments passed to this method can inject arbitrary Git options, such as --output, leading to arbitrary file truncation on the host filesystem.
CVE-2026-59881 is a protocol compliance and input validation vulnerability in the client-side WebSocket implementation of the aiohttp asynchronous HTTP client/server framework for Python. Prior to version 3.14.2, the framework's parser unexpectedly accepts and attempts to decompress frames containing the RSV1 bit, even when the permessage-deflate extension has not been negotiated during the initial WebSocket handshake. This violation of RFC 6455 allows a malicious or compromised server to bypass client configuration, forcing decompression routines that can lead to high CPU and memory consumption, resulting in a denial-of-service condition.
An asynchronous HTTP client/server framework for asyncio and Python, aiohttp prior to version 3.14.2 is vulnerable to HTTP Request Smuggling. The server-side HTTP parser immediately transitions the protocol state to 'upgraded' upon receiving a WebSocket upgrade request before consuming the accompanying request body. If the backend handler rejects the upgrade request while keeping the TCP connection alive, the unconsumed request body remains in the socket buffer and is parsed as a subsequent pipelined HTTP request. This allows an attacker to smuggle requests, bypass frontend reverse proxy controls, and perform unauthorized actions.
A vulnerability in the Guzzle HTTP client allows session identifiers, auth tokens, or cookies to be leaked to unauthorized hosts due to incorrect cookie domain validation of noncanonical IPv4 host formats. Guzzle failed to recognize octal, hexadecimal, and percent-encoded IP addresses as IP literals, treating them as standard domains and incorrectly extending their scope to subdomains.
CVE-2026-69246 is a host validation bypass vulnerability in the Guzzle PHP HTTP client. The flaw resides in Guzzle's core HTTP transport handlers (cURL and PHP stream wrappers). Under specific conditions, a parser differential occurs between the host validation layer and the underlying network transport library (e.g., libcurl), allowing remote attackers to bypass SSRF filters, proxy routing rules, and redirect protections via crafted noncanonical URI representations.
A side-channel vulnerability in pyca/cryptography (versions 44.0.0 through 49.9.9) allows unauthenticated remote attackers to expose a Bleichenbacher oracle. This flaw exists within the PKCS#7 decryption module (specifically pkcs7_decrypt_der, pkcs7_decrypt_pem, and pkcs7_decrypt_smime) during Content Encryption Key (CEK) decryption when using RSA PKCS#1 v1.5 padding. Differences in error classification and symmetric execution timing allow an attacker to reconstruct plaintext keys.