{"schema":"threatline.record/2","record":{"id":"GHSA-mvr9-2h5x-w6cq","aliases":["GHSA-mvr9-2h5x-w6cq"],"summary":"Quote-only escaping of inline literals on MySQL and MariaDB","details":"### Impact\nA few paths still write values into SQL as quoted literals, escaping only single quotes (`'` -> `''`):\n- queries run with `parameterize=false` (opt-in), including its IN-list handling;\n- literals in a developer-written `where=` string in positions the WHERE parser does not bind, such as `BETWEEN ... AND ...`, function arguments and `LIKE ... ESCAPE '...'`.\n\nOn MySQL and MariaDB with the default `sql_mode` (no `NO_BACKSLASH_ESCAPES`), a backslash is an escape character inside a string literal, so doubling quotes alone does not contain every value. If an application puts request data into one of these paths, the value can change the query. PostgreSQL (with the default `standard_conforming_strings`), SQL Server, SQLite, Oracle, H2 and CockroachDB treat a backslash literally and are not affected.\n\nThe bound paths (dynamic finders, the query builder, key lookups, and `=`/`<>`/`<`/`>`/`LIKE`/`IN` comparisons in `where=` strings) are not affected; 4.1.2 also binds `whereBetween()`.\n\n### Patches\nFixed in 4.2.0. On MySQL and MariaDB, a string value that Wheels writes into the SQL text instead of binding it (every value with `parameterize=false`, and literals that a `where` string leaves in place) is now written as a hex literal when it contains a backslash, so it reads the same whatever the `sql_mode`. The query-builder guide now lists which `where` values are bound.\n\n### Workarounds\nPass request data only through bound APIs (`where(property, value)`, dynamic finders, `whereIn`, `whereBetween` in 4.1.2+), don't use `parameterize=false` with request data, or set `NO_BACKSLASH_ESCAPES` in the MySQL `sql_mode`.\n","categories":["Unclassified"],"product":"wheels","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-mvr9-2h5x-w6cq","source_modified_at":"2026-10-12T00:02:30Z","fetched_at":"2026-10-23T21:10:45.942435Z","package":{"ecosystem":"other","name":"wheels"},"range":"<= 4.1.2"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-mvr9-2h5x-w6cq","source_modified_at":"2026-10-12T00:02:30Z","fetched_at":"2026-10-23T21:10:45.942435Z","package":{"ecosystem":"other","name":"wheels"},"version":"4.2.0"}],"cvss":9.8,"severity":"Critical","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-12T00:02:30Z","modified_at":"2026-10-12T00:02:30Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-mvr9-2h5x-w6cq","fetched_at":"2026-10-23T21:10:45.942435Z","source_modified_at":"2026-10-12T00:02:30Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-12T00:02:30Z","content_hash":"87dc975be3a0d9a575946ae0a8db2ceb8a6f74fe4daf904b3e04cedda32c6385"}}
