CVE-2026-59894: sqlparse Generated Python And PHP Snippets Vulnerability

MODERATE
Advisory Identifier: GHSA-3496-9g83-7v6x
CWE-94
Published
Advisory Summary

CVE-2026-59894 is a MODERATE generated python and php snippets vulnerability (CWE-94: Improper Control of Generation of Code ('Code Injection')) affecting sqlparse libraries in the PyPI ecosystem. The issue involves generated python and php snippets allow sql string breakout through unescaped backslashes. Remediation is available by upgrading affected packages to version 0.6.0.

CVE-2026-59894 at a Glance

CVE Identifier CVE-2026-59894
GHSA Identifier GHSA-3496-9g83-7v6x
Severity MODERATE
CVSS v3.1 Base Score N/A
CWE Classification CWE-94: Improper Control of Generation of Code ('Code Injection')
Affected Product sqlparse
Package Ecosystem PyPI
Published Date
Last Updated

How to Fix CVE-2026-59894

To remediate this vulnerability, upgrade all affected sqlparse dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

sqlparse fixed: 0.6.0
pip install sqlparse>=0.6.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show sqlparse

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-59894, inspect your installed packages using pip:

pip show sqlparse

Analyze the terminal output to locate any version of sqlparse in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.6.0), your application is affected.

Note: The pip show sqlparse command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-94: Improper Control of Generation of Code ('Code Injection'), where the product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. In sqlparse, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary The documented Python and PHP output modes generate source-code snippets from caller-supplied SQL. Their output filters escape quote characters without first escaping existing backslashes. Crafted SQL can therefore neutralize the generated quote escape, terminate the intended language string, and place attacker-controlled code into the generated snippet. If a downstream consumer executes or imports that generated source, the injected code runs in the consumer's environment. ### Details The Python output filter places SQL in a single-quoted string and replaces each single quote with an escaped quote. The PHP output filter performs the equivalent operation for a double-quoted string. Neither transformation escapes pre-existing backslashes before escaping quotes. A backslash supplied immediately before a quote causes the generated backslash to be escaped instead of the quote, allowing the quote to close the string. The affected modes are exposed through `sqlparse.format(..., output_format='python')`, `sqlparse.format(..., output_format='php')`, and the corresponding `sqlformat -l` options. Formatting produces the injected source but does not itself execute it; code execution occurs when a downstream workflow treats the generated snippet as Python or PHP code. Relevant code locations: - `sqlparse/formatter.py:193` — selection of the output-language filters - `sqlparse/filters/output.py:45` — opening of the generated Python string - `sqlparse/filters/output.py:65` — incomplete Python quote escaping - `sqlparse/filters/output.py:91` — opening of the generated PHP string - `sqlparse/filters/output.py:114` — incomplete PHP quote escaping ### PoC A complete validated reproduction is attached as [output_format_snippet_injection-poc.zip](https://github.com/user-attachments/files/29410134/output_format_snippet_injection-poc.zip). The archive contains `reproduction/` at its root, uses Git and Docker, and validates the Python output path by generating and executing a snippet containing a controlled marker-file write. Extract the archive beside this report, then run: ```console ./reproduction/run.sh ``` Observed result: The generated Python snippet placed the attacker-controlled `pathlib.Path(...).write_text(...)` expression outside the intended SQL string. Executing the snippet wrote the expected proof marker, emitted `EVOHUNT_OUTPUT_FORMAT_INJECTION_VERIFIED`, and completed successfully. Verification method: The verification helper calls `sqlparse.format(..., output_format='python')`, executes the generated snippet, and fails unless the injected Python expression writes the exact proof marker file. Limitations: No reproduction blocker was recorded. The attached harness directly verifies the Python output path; exploitation also requires a downstream consumer to execute or import the generated source. ### Impact This is source-code injection in the opt-in Python and PHP snippet-generation modes. An attacker who controls SQL converted by one of these modes can inject language code into the generated artifact. If that artifact is subsequently executed, the attacker can run code with the permissions and access of the downstream Python or PHP process. The demonstrated end-to-end result is code execution through a generated Python snippet. Formatting the SQL alone does not execute the payload, and ordinary parsing, splitting, or formatting without these output modes is not shown to be affected.

CVE-2026-59894 Affected sqlparse Versions

1 component(s)
Fixed Versions:
0.6.0
Product / Package Ecosystem Affected Versions Fixed Version
sqlparse
PyPI
< 0.6.0
0.6.0

References

Frequently Asked Questions

What is CVE-2026-59894?
CVE-2026-59894 is a security vulnerability in sqlparse involving Generated Python and PHP snippets allow SQL string breakout through unescaped backslashes under CWE-94: Improper Control of Generation of Code ('Code Injection').
Which sqlparse versions are affected?
Affected versions include releases prior to 0.6.0 across affected packages: sqlparse.
What version fixes CVE-2026-59894?
Upgrading to 0.6.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is sqlparse affected?
Yes, sqlparse is affected in releases prior to 0.6.0. Upgrade your dependency to 0.6.0 or later.
What CWE is associated with CVE-2026-59894?
CVE-2026-59894 is classified under CWE-94: Improper Control of Generation of Code ('Code Injection') (The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.).
How can I check PyPI dependencies for CVE-2026-59894?
Run the dependency tree command: 'pip show sqlparse'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-3496-9g83-7v6x",
  "modified" : "2026-08-17T17:20:11Z",
  "published" : "2026-08-17T17:20:11Z",
  "aliases" : [ "CVE-2026-59894" ],
  "summary" : "sqlparse: Generated Python and PHP snippets allow SQL string breakout through unescaped backslashes",
  "details" : "### Summary\n\nThe documented Python and PHP output modes generate source-code snippets from caller-supplied SQL. Their output filters escape quote characters without first escaping existing backslashes. Crafted SQL can therefore neutralize the generated quote escape, terminate the intended language string, and place attacker-controlled code into the generated snippet. If a downstream consumer executes or imports that generated source, the injected code runs in the consumer's environment.\n\n### Details\n\nThe Python output filter places SQL in a single-quoted string and replaces each single quote with an escaped quote. The PHP output filter performs the equivalent operation for a double-quoted string. Neither transformation escapes pre-existing backslashes before escaping quotes. A backslash supplied immediately before a quote causes the generated backslash to be escaped instead of the quote, allowing the quote to close the string.\n\nThe affected modes are exposed through `sqlparse.format(..., output_format='python')`, `sqlparse.format(..., output_format='php')`, and the corresponding `sqlformat -l` options. Formatting produces the injected source but does not itself execute it; code execution occurs when a downstream workflow treats the generated snippet as Python or PHP code.\n\nRelevant code locations:\n\n- `sqlparse/formatter.py:193` — selection of the output-language filters\n- `sqlparse/filters/output.py:45` — opening of the generated Python string\n- `sqlparse/filters/output.py:65` — incomplete Python quote escaping\n- `sqlparse/filters/output.py:91` — opening of the generated PHP string\n- `sqlparse/filters/output.py:114` — incomplete PHP quote escaping\n\n### PoC\n\nA complete validated reproduction is attached as [output_format_snippet_injection-poc.zip](https://github.com/user-attachments/files/29410134/output_format_snippet_injection-poc.zip). The archive contains `reproduction/` at its root, uses Git and Docker, and validates the Python output path by generating and executing a snippet containing a controlled marker-file write.\n\nExtract the archive beside this report, then run:\n\n```console\n./reproduction/run.sh\n```\n\nObserved result:\n\nThe generated Python snippet placed the attacker-controlled `pathlib.Path(...).write_text(...)` expression outside the intended SQL string. Executing the snippet wrote the expected proof marker, emitted `EVOHUNT_OUTPUT_FORMAT_INJECTION_VERIFIED`, and completed successfully.\n\nVerification method:\n\nThe verification helper calls `sqlparse.format(..., output_format='python')`, executes the generated snippet, and fails unless the injected Python expression writes the exact proof marker file.\n\nLimitations:\n\nNo reproduction blocker was recorded. The attached harness directly verifies the Python output path; exploitation also requires a downstream consumer to execute or import the generated source.\n\n### Impact\n\nThis is source-code injection in the opt-in Python and PHP snippet-generation modes. An attacker who controls SQL converted by one of these modes can inject language code into the generated artifact. If that artifact is subsequently executed, the attacker can run code with the permissions and access of the downstream Python or PHP process.\n\nThe demonstrated end-to-end result is code execution through a generated Python snippet. Formatting the SQL alone does not execute the payload, and ordinary parsing, splitting, or formatting without these output modes is not shown to be affected.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "sqlparse"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.6.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.5.5"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/andialbrecht/sqlparse/security/advisories/GHSA-3496-9g83-7v6x"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/andialbrecht/sqlparse/commit/53ff44b53e27cff78259acc1af015506fea60f63"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/andialbrecht/sqlparse"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-94" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-17T17:20:11Z",
    "nvd_published_at" : null
  }
}