{
  "variant_id": "CVE-2026-40900-postgresql-previewSql-stacked",
  "validation_timestamp": "2026-05-25T23:30:00Z",
  "verdict": "VARIANT_CONFIRMED_ALTERNATE_TRIGGER",
  "verdict_summary": "A distinct alternate trigger for the same root cause was confirmed on the vulnerable version (v2.10.20). No true bypass of the fixed version (v2.10.21) was found. The variant uses a PostgreSQL datasource (type=pg) to reach the same unprotected previewSql sink, demonstrating that the lack of single-statement validation in DatasetDataManage.previewSql() affects multiple database types beyond MySQL.",
  "variant_confirmed": true,
  "bypass_of_fix": false,
  "blocked_on_fixed_version": true,
  "tests_performed": [
    {
      "variant_name": "mariadb type with allowMultiQueries=true",
      "description": "Uses the mariadb datasource type (which parses as Mysql.class) to stack SQL via previewSql.",
      "vulnerable_version_result": "CONFIRMED: datasource created with status=Success and stacked SQL injection succeeded (INSERT executed).",
      "fixed_version_result": "BLOCKED: datasource created with status=Error due to allowMultiQueries in illegalParameters.",
      "is_distinct_variant": false,
      "notes": "This is essentially the same MySQL attack surface reached through a different type alias. The fix covers it because all MySQL-compatible types share Mysql.class parsing."
    },
    {
      "variant_name": "double-URL-encoded allowMultiQueries",
      "description": "Bypasses the illegalParameters string-matching check by double-URL-encoding the parameter name (allow%254DultiQueries=true).",
      "vulnerable_version_result": "PARTIAL: datasource created with status=Success, but MySQL driver does not recognize the double-encoded parameter, so stacked SQL fails.",
      "fixed_version_result": "PARTIAL: datasource created with status=Success (validation bypassed), but exploit still fails due to driver limitation.",
      "is_distinct_variant": false,
      "notes": "A validation-logic bypass without full vulnerability exploitation. The URLDecoder.decode() in Mysql.java only decodes once, so %254D becomes %4D, which does not match allowmultiqueries. The driver also performs single-level decoding and does not recognize the parameter."
    },
    {
      "variant_name": "PostgreSQL time-based stacked query",
      "description": "Uses a PostgreSQL datasource (type=pg) and a stacked SQL payload with pg_sleep(5) to prove multi-statement execution through previewSql.",
      "vulnerable_version_result": "CONFIRMED: baseline 0.03s, exploit 5.04s with error Multiple ResultSets were returned by the query. The 5-second delay proves pg_sleep(5) executed as the second statement.",
      "fixed_version_result": "BLOCKED: exploit returned immediate PostgreSQL syntax error with no time delay (0.03s).",
      "is_distinct_variant": true,
      "notes": "This is a materially different trigger (different database type, different JDBC driver, no special parameter required) that reaches the same vulnerable sink. It confirms the root cause is the lack of single-statement validation in previewSql, not merely the allowMultiQueries parameter."
    }
  ],
  "evidence_files": [
    "logs/variant3_v2.10.20_baseline.json",
    "logs/variant3_v2.10.20_exploit.json",
    "logs/variant3_v2.10.21_exploit.json",
    "logs/variant1_v2.10.20_create.json",
    "logs/variant1_v2.10.20_exploit.json",
    "logs/variant1_v2.10.21_create.json",
    "logs/variant2_v2.10.20_create.json",
    "logs/variant2_v2.10.21_create.json",
    "logs/variant_run8.log"
  ],
  "recommendations_for_fix": [
    "Add server-side single-statement validation in DatasetDataManage.previewSql() before wrapping user SQL.",
    "Reject payloads containing statement terminators (;) or comment sequences that could swallow the wrapper suffix.",
    "Harden URL parameter validation to perform iterative decoding and NFKC normalization before blocklist matching.",
    "Consider restricting multi-statement execution at the JDBC connection level for all database types, not just MySQL."
  ]
}
