Skip to content
YesWiki 9.1 — A Backtick, a String Escaper, and a Public API ThreatAft — Cybersecurity Intelligence / 4h 2026 has produced at least seven YesWiki SQL injection CVEs and advisories, five of them unauthenticated, in the Bazar filters, the ACL read-filter builder, the action, form import, entry save and this search API. Volerion's advisory documents the reproduction as an unauthenticated GET request to the public Bazar entries search API carrying a crafted parameter that contains a backtick and an

YesWiki 9.1 — A Backtick, a String Escaper, and a Public API ThreatAft — Cybersecurity Intelligence / 4h 2026 has produced at least seven YesWiki SQL injection CVEs and advisories, five of them unauthenticated, in the Bazar filters, the ACL read-filter builder, the action, form import, entry save and this search API. Volerion's advisory documents the reproduction as an unauthenticated GET request to the public Bazar entries search API carrying a crafted parameter that contains a backtick and an

threataft.com • October 26, 2026

CVE-2026-116207 is a textbook category error, and the category error is the interesting part. YesWiki takes a field name from an unauthenticated HTTP parameter, wraps it in backticks to use it as a SQL identifier, and then escapes the contents with mysqli_real_escape_string — a function whose entire job is to escape characters inside string literals .

That function escapes quotes, backslashes, newlines and NUL. It does not escape backticks, because backticks have no special meaning inside a quoted string. So an attacker supplies a backtick, closes the identifier, writes SQL, and opens a new identifier for the parser to close. The escape function ran. It just answered a different question than the one being asked.

📌 TL;DR — YesWiki CVE-2026-116207

What: unauthenticated SQL injection (CWE-89) in YesWiki, SearchManager::prepareSearchRequest() , reached through the public Bazar entries API. Who's affected: YesWiki 4.6.0 before 4.7.0 and 5.0.0-alpha1 before 5.0.0-alpha4 . No account required. The bug: field names from query and searchfields are placed in a backtick-quoted alias and escaped with mysqli_real_escape_string , which does not escape backticks. A supplied backtick breaks out of the identifier and injects subqueries. The score, honestly: 9.1 on CVSS 3.1 and 8.8 on CVSS 4.0 , both from the CNA, VulnCheck. NVD marked the record Not Scheduled for enrichment, so there is no NVD assessment to compare against. What the vector actually says: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H — Integrity None . This is a read and denial-of-service flaw. It cannot modify data. Extraction is in-band: injected results return in the JSON response, so no blind oracle is needed to pull yeswiki_users password hashes. Fixed: 4.7.0 and 5.0.0-alpha4 . An upstream GitHub advisory covering the flaw was public on 9 October 2026 , sixteen days before the CVE. Status: not in CISA KEV, no public PoC, no reported exploitation, no EPSS score. None of those is a reason to wait. Context: at least seven YesWiki SQL injection CVEs and advisories in 2026. 4.7.0 closes the whole set.

The escape function is correct; its use is not. mysqli_real_escape_string is not broken and it is not a weak escape. It is a string-literal escaper applied to an identifier context. SQL has two escaping domains and YesWiki used the wrong one. A defender reading 'escaped with mysqli_real_escape_string' could reasonably conclude the parameter was handled; it was not, and the distinction is worth knowing because the same mistake appears across a great deal of PHP.

Integrity is None, and that changes what happened and what to look for. The CVSS 3.1 vector carries I:N . This bug cannot rewrite a page, create an entry, or alter a user record. It reads, and it can hold database threads open with SLEEP() . Anyone triaging this as a classic 9.x write-everything SQLi is looking for the wrong artefacts — there are no modified rows to find.

The read primitive still ends in account takeover, through the front door. yeswiki_users.password hashes are readable. YesWiki is PHP, so those are likely bcrypt or similar, but a hash is a credential the moment it is out of the database, and every cracked one is a legitimate login rather than an injection. The bug supplies no write; it supplies the material to obtain write legitimately.

9.1 and 8.8 are the same flaw scored twice, and the gap is instructive. The CNA scored 9.1 under CVSS 3.1 and 8.8 under CVSS 4.0. The difference is not a disagreement the bug — it is the two formulas weighting a read-only injection with a DoS tail differently. NVD has not enriched the record, so there is no third opinion. Quote the framework you mean.

The advisory was public sixteen days before the CVE. A GitHub advisory describing the same flaw, with the same fix, was published on 9 October 2026; the CVE record appeared on 25 October. This is the third time in this series that a fix and a public write-up preceded the identifier. A process that only starts its clock at CVE publication was blind for over two weeks on an unauthenticated public-API flaw.

This is not a one-off, it is the seventh of the year. 2026 has produced at least seven YesWiki SQL injection CVEs and advisories, five of them unauthenticated, in the Bazar filters, the ACL read-filter builder, the newtextsearch action, form import, entry save and this API. That is a codebase pattern — concatenated SQL across a broad attack surface — not a single regression, and it is the argument for treating YesWiki's release notes as a standing subscription rather than a quarterly read.

Range note: the CVE record states 4.6.0 as the lower bound, while the upstream GitHub advisory published on 9 October lists >= 4.6.7 . Both agree that 4.6.7 through 4.6.x is affected. The narrower advisory bound most likely reflects where the vulnerable code path was introduced or changed; the CVE range is the conservative reading and is the one to act on. Fixed in 4.7.0.

SQL has two places where untrusted text can end up, and they need different treatment. A value goes inside quotes and is escaped for string metacharacters. An identifier — a table name, a column name, an alias — is not quoted as a string at all; in MySQL it is wrapped in backticks, and the correct way to neutralise a backtick inside one is to double it.

VulDB's analysis of the root cause is precise what YesWiki did instead. Field names from the query and searchfields parameters are interpolated into the SELECT statement as backtick-quoted aliases, and the only sanitisation applied is mysqli_real_escape_string . That function escapes NUL, newline, carriage return, backslash, single quote, double quote and Control-Z. Backtick is not on the list, because a backtick inside a quoted string has no special meaning.

The sanitization function used is mysqli_real_escape_string , which is primarily designed to escape special characters within string literals rather than identifier names like column or table names. This mismatch creates a significant security gap because mysqli_real_escape_string does not adequately neutralize backticks themselves when they are part of an identifier context that is already wrapped in backticks.

The sanitization function used is mysqli_real_escape_string , which is primarily designed to escape special characters within string literals rather than identifier names like column or table names. This mismatch creates a significant security gap because mysqli_real_escape_string does not adequately neutralize backticks themselves when they are part of an identifier context that is already wrapped in backticks.

The resulting payload shape is simple. Supply a value that closes the identifier with a backtick, appends SQL syntax, and reopens a backtick so the remainder of the original query still parses. The query executed by the backend is now structurally different from the one the developer wrote, and the injected subquery runs in the application's database user context.

What the correct fix looks like, and what it does not. Escaping harder is not the answer — no amount of string escaping makes a backtick safe in an identifier slot. The two workable approaches are to double any backtick in the value before wrapping it, or, better, to validate the supplied field name against an allow-list of columns the API is permitted to . The second is the only one that also constrains which data an attacker can ask for once the injection is closed. It is also the fix a codebase needs when the same parameter pattern appears in more than one place, which — as the section shows — is exactly the situation here.

Volerion's advisory documents the reproduction as an unauthenticated GET request to the public Bazar entries API carrying a crafted query parameter that contains a backtick and an injected subquery. Two details in that sentence matter more than the mechanics.

First, the API is public by design. The Bazar entries endpoint exists so that visitors can query and retrieve data from the application's database without authenticating. It is not an administrative route that was accidentally exposed; it is a documented public interface, which is why the flaw has no authentication precondition at all rather than a low-privilege one. GitHub's advisory names the route family as the /api/entries/bazarlist path reached through the forms API.

Second, extraction is in-band. Volerion notes that the injection is executed in the database context and the results are returned in the JSON response. That is a materially different proposition from a blind injection. A blind SQLi requires an oracle — you infer one bit per request from timing or from a conditional difference in the response, and exfiltrating a password hash is slow and noisy. An in-band injection returns the data you asked for in the body of the , so a single well-formed request can yield a result set.

What that means for the data. The CVE text names user password hashes as the headline target, and the yeswiki_users table is where they live. Bazar entry data sits alongside it — the structured content that forms and lists are built from, which on many wikis includes personal details that were never intended to be public. The impact depends on the privileges of the database account YesWiki uses, which in a typical PHP deployment is the account that owns the schema rather than a restricted reader.

And the availability tail. The same injection point accepts SLEEP() . A time-based payload that holds a connection open for tens of seconds, repeated across enough requests, consumes the database's worker threads and produces service degradation or unavailability for legitimate users. VulDB maps this to ATT&CK T1496, resource hijacking, which is the correct framing: the goal is not to crash the database but to occupy it.

What 9.1 Actually Says

The score in circulation is 9.1. That is the CVSS 3.1 score. The CNA also published a CVSS 4.0 score of 8.8, and the two vectors describe the same flaw with different emphasis.

Integrity is None in both frameworks. I:N on v3.1 and VI:N on v4.0. This vulnerability cannot modify, insert or delete data. It reads, and it can deny service. That is worth stating plainly because a 9.x SQL injection is usually assumed to be a write primitive, and the assumption changes what an incident responder looks for.

The 9.1 comes from the combination of confidentiality and availability. C:H reflects that password hashes and Bazar content are readable. A:H reflects that SLEEP() can exhaust the database's threads. Two High impacts with no scope change produces 9.1 on v3.1. It is not 9.8 because 9.8 requires all three impacts at High, and this flaw cannot alter data.

Why v4.0 lands at 8.8. The v4.0 formula does not produce 9.x from a read-plus-DoS combination as readily as v3.1 does; the explicit SC:N/SI:N/SA:N declarations confirm no subsequent-system impact, and with integrity at None the total settles below the critical band. Both scores are defensible. The practical instruction is to name the framework whenever the number is quoted, because a reader who sees only 9.1 will assume a write primitive that the vector explicitly excludes.

The NVD status is its own fact. The record is marked Not Scheduled, meaning NVD is not prioritising it for enrichment and has published no vector. The CNA scores are therefore the only official ones, and there will be no NVD-authored second opinion to defer to. That is a reason to read the CNA vectors directly rather than a reason to distrust the score.

Sixteen Days Before the CVE

The disclosure timeline repeats a pattern this series has now documented three times.

The practical consequence is not subtle. The window during which an unauthenticated public-API SQL injection was publicly described but not assigned a CVE is exactly the window in which an attacker reading the same advisory had a head start over defenders reading a feed. Sixteen days is enough time to write a payload, and the payload here is short.

YesWiki's 2026 SQL Injection Pattern

This CVE is not an isolated regression. YesWiki has produced a steady sequence of SQL injection findings through 2026, and the variety of the injection points is more revealing than the count.

Two things stand out. The first is the number of unauthenticated entries: five of the seven listed. YesWiki's Bazar tooling exposes , filtering and import paths to anonymous visitors, and each of those paths has at some point concatenated user input into SQL. The second is the spread of mechanisms — a stored second-order injection through an ACL filter, a blind injection through a action, an INSERT injection through form import, and an identifier injection through a alias. These are not variants of one bug. They are four different ways of getting input into a query without parameterisation, in four different parts of the same codebase.

There are further findings not in the table. An authenticated injection through ReactionManager::deleteUserReaction() via the {idreaction} and {id} URL path parameters, an injection through the recentchanges action, and SQL injection through numeric query / queries filters in Bazar entry-listing APIs have all been reported in the same period. The list above is representative rather than exhaustive, and that is itself the finding: this is a codebase-wide pattern rather than a set of unrelated bugs.

What the pattern implies for patching. The 2 October batch was fixed in 4.6.7. The 25 October pair is fixed in 4.7.0. A site that jumps directly from anything below 4.6.7 to 4.7.0 closes every entry in this table. A site that patches individual CVEs one at a time will keep arriving late to a moving target, because the one in the pattern has not been written yet.

Read-Only, and Why That Still Ends in Takeover

I:N is the most important letter in this CVE and the easiest to misread. The flaw cannot write. So the question a defender should ask is not what did they change but what did they take, and what does it unlock.

What the read actually unlocks. The injection reads yeswiki_users.password hashes. Those are credentials in a form that can be attacked offline, at whatever rate the attacker's hardware permits, without touching the wiki again and without generating another log entry. Any hash that falls yields a legitimate account — and a legitimate login is not an injection, it is the application working as designed. From there the attacker's capabilities are whatever that account's role permits, obtained through the front door rather than through the bug.

Why this matters for triage. If you are looking for evidence of this vulnerability in your logs, the absence of modified rows, new pages or changed user records proves nothing — the flaw cannot produce them. The evidence is on the read side: an unusual query against the API, a response larger than the request warranted, a burst of requests to the same endpoint from one source, or SLEEP() visible as slow queries and held threads.

And why it changes the remediation. Patching the injection stops future reads. It does not un-read the hashes that were already taken. If the API was reachable from untrusted networks during the affected window, the correct follow-on is a password reset for the accounts whose hashes were in reach — which, on a YesWiki install, is every account — and a review for logins that used credentials the user did not type. That second check is the one most likely to find an intrusion, because a cracked hash produces a completely ordinary successful authentication.

Detection: Nothing Changes, So Nothing Alerts

An injection that only reads leaves no integrity trace. There is no file on disk, no modified option, no new administrator account created by the exploit itself. What remains is the request and the response, and possibly the database's own slowness.

Web server and reverse-proxy logs.

Backticks in the Bazar parameters. access logs for requests to the Bazar entries route where query or searchfields contains a literal backtick ( %60 when URL-encoded). Legitimate field names do not contain backticks, so this is a high-signal rule with almost no false positives.

SQL syntax in a field name. The same parameters carrying UNION , SELECT , CASE , IF( , SLEEP , information_schema , or yeswiki_users . Any of those inside a parameter that is supposed to name a column is not a , it is an attempt.

Response size on the endpoint. In-band extraction returns more data than the query should have produced. A response body significantly larger than the site's normal baseline for that endpoint, or a response containing a result set the visitor had no way to request, is a lead worth following.

Request volume from a single source. The flaw is in-band, so a serious extraction may be one request rather than thousands — but an attacker enumerating tables or testing payloads will still produce a cluster from one address.

Database-side signals.

Slow query log entries for SLEEP() . A query that runs for ten, thirty or sixty seconds against the wiki schema, originating from the web tier, is the availability half of this vulnerability in operation.

Held connections and thread exhaustion. SHOW PROCESSLIST showing multiple sleeping threads attributed to the application's database user, particularly during periods when the site is otherwise quiet, is consistent with resource-hijack payloads.

Queries selecting from yeswiki_users outside the login path. A SELECT against the users table that is not the authentication query is worth explaining. If your database audit logging is not enabled, this check is unavailable to you, and enabling it is the durable fix for the one of these.

The honest limitation. YesWiki is a self-hosted PHP application frequently run without a reverse proxy, without a WAF, and without database audit logging — VulDB notes that the flaw is particularly dangerous where the Bazar API faces external traffic without a protective layer that would catch malformed SQL patterns. On such a deployment the only record is the web server's own access log, and only if it is retained. The absence of an alert on a system with no telemetry is not evidence that nothing happened.

Upgrade to YesWiki 4.7.0 or later, or 5.0.0-alpha4 or later on the 5.x line. Do not stop at the CVE record's lower bound of 4.6.0 and do not rely on the upstream advisory's narrower >= 4.6.7 range — both agree that 4.6.7 through 4.6.x is vulnerable, and 4.6.0 through 4.6.6 should be treated as affected.

Upgrade to YesWiki 4.7.0 or later, or 5.0.0-alpha4 or later on the 5.x line. Do not stop at the CVE record's lower bound of 4.6.0 and do not rely on the upstream advisory's narrower >= 4.6.7 range — both agree that 4.6.7 through 4.6.x is vulnerable, and 4.6.0 through 4.6.6 should be treated as affected.

If 4.7.0 is not immediately possible, restrict the Bazar API to authenticated users. The vulnerability is unauthenticated by construction; requiring a session removes the attacker's ability to reach the injection point at all. This is a real mitigation rather than a cosmetic one, but it changes site behaviour and needs to be a deliberate decision.

If 4.7.0 is not immediately possible, restrict the Bazar API to authenticated users. The vulnerability is unauthenticated by construction; requiring a session removes the attacker's ability to reach the injection point at all. This is a real mitigation rather than a cosmetic one, but it changes site behaviour and needs to be a deliberate decision.

Add a WAF or reverse-proxy rule for backticks in query and searchfields . Reject requests where either parameter contains %60 or a raw backtick. This is narrow enough to carry almost no false positives and it closes the specific bypass, though not the underlying concatenation.

Add a WAF or reverse-proxy rule for backticks in query and searchfields . Reject requests where either parameter contains %60 or a raw backtick. This is narrow enough to carry almost no false positives and it closes the specific bypass, though not the underlying concatenation.

Verify the fix took effect. After upgrading, send a request carrying a backtick in a field name and confirm it is rejected or neutralised rather than reflected into a query. A version string proves a package was installed; a rejected payload proves the identifier handling changed.

Verify the fix took effect. After upgrading, send a request carrying a backtick in a field name and confirm it is rejected or neutralised rather than reflected into a query. A version string proves a package was installed; a rejected payload proves the identifier handling changed.

Assume the hashes were readable and force a password reset. This is the step most often skipped on a read-only SQL injection. Every account's hash was in reach during the exposed window. Rotating them closes the offline-cracking path, and it is the only control that addresses what the vulnerability actually leaked.

Assume the hashes were readable and force a password reset. This is the step most often skipped on a read-only SQL injection. Every account's hash was in reach during the exposed window. Rotating them closes the offline-cracking path, and it is the only control that addresses what the vulnerability actually leaked.

Hunt for logins with credentials users did not type. A cracked hash produces a valid successful authentication. Review authentication events for accounts whose owners report no login, for logins from unfamiliar address ranges, and for administrative actions taken shortly after a first-ever login from a new location.

Hunt for logins with credentials users did not type. A cracked hash produces a valid successful authentication. Review authentication events for accounts whose owners report no login, for logins from unfamiliar address ranges, and for administrative actions taken shortly after a first-ever login from a new location.

Review the rest of the 2026 set. Confirm the deployment is at or above 4.7.0, which closes every entry in the pattern table above. If the site is pinned below 4.6.7 for compatibility reasons, it is exposed to at least four further SQL injection findings beyond this one.

Review the rest of the 2026 set. Confirm the deployment is at or above 4.7.0, which closes every entry in the pattern table above. If the site is pinned below 4.6.7 for compatibility reasons, it is exposed to at least four further SQL injection findings beyond this one.

Compensating Controls

Give YesWiki a least-privilege database account. The injection executes as the account in the application's configuration. An account limited to the tables and operations the application actually needs does not stop the injection, but it constrains what an injected subquery can reach — and the CVE's stated impact, reading yeswiki_users , assumes an account that can read it.

Enable database audit logging for the wiki schema. A read-only injection produces no application-side artefact. Query-level logging is the only place the read exists after the fact, and it is what makes the CVE in this pattern detectable rather than merely patchable.

Do not expose the Bazar API beyond the audience that needs it. If the wiki is internal, restrict the API at the network layer. If it is public, accept that the endpoint is an unauthenticated interface to your database and treat every future advisory against it as urgent by default.

Watch YesWiki's advisories rather than waiting for CVEs. The sixteen-day gap in this case, and the earlier gaps documented in this series, mean a CVE-feed-driven process is structurally late. The upstream repository advisory is where the fix is announced first.

Treat repeated SQL injection in one codebase as a structural finding. Seven findings in a year across , filters, ACLs, import and save paths is not a run of bad luck. It is an argument for parameterised queries as a codebase policy, and for a security review of every remaining hand-built query if the deployment is customised.

CVE.org — CVE-2026-116207 record; assigner VulnCheck; published 25 October 2026 13:20 UTC

NIST NVD — CVE-2026-116207 (record marked Not Scheduled; CNA CVSS 4.0 vector reproduced)

CIRCL Vulnerability-Lookup — CVE-2026-116207 / GCVE-0-2026-116207, including affected ranges, public date and CNA metadata

VulDB — CVE-2026-116207 , root-cause analysis of backtick-quoted alias escaping and identifier-versus-string escaping distinction

Volerion Advisory — CVE-2026-116207 YesWiki SQL Injection Vulnerability in Bazar Entries API, including in-band extraction description and remediation

GitHub Security Advisory — Unauthenticated SQL injection in YesWiki Bazar entries API via unescaped backtick in query field name, published 9 October 2026

YesWiki — 4.7.0 release and 5.0.0-alpha4 release notes

Rapid7 Vulnerability Database — CVE-2026-116207 , CVSS 3.1 and 4.0 vectors

Glexia Threat Intelligence — CVE-2026-116207 profile, KEV status and CVSS 3.1 vector

Strix — CVE-2026-116207 analysis (CVSS 9.1)

East Bay Cyber — CVE-2026-116207 explainer and runbook, KEV and exploitation status

Feedly CVE — CVE-2026-116207 , both vectors, exploitation evidence and mitigation guidance

CVE.org and VulDB — CVE-2026-116211 (Bazar entry create, date_maj_fiche )

CVE.org and VulDB — CVE-2026-104456 , CVE-2026-104457 , CVE-2026-104460 (October 2 YesWiki SQL injection batch)

CIRCL Vulnerability-Lookup — GHSA-jwvv-qr7q-cv8j and GHSA-f58v-p6j9-24c2, earlier 2026 YesWiki SQL injection advisories

GitLab Advisory Database — YesWiki advisories including recentchanges action and numeric query / queries filters

TheHackerWire — CVE-2026-116207 analysis, CISA KEV status

YesWiki used a string escaper on an identifier slot, and a backtick walked straight through it. That is the whole vulnerability, and it is worth understanding precisely because the code looked defended: a sanitiser was called, the value was quoted, and neither measure was the right one for the context. The injection is unauthenticated, the API is public, and the results come back in the JSON body — so reading yeswiki_users password hashes does not require a blind oracle, just a request.

The score needs one correction before anyone acts on it. This is 9.1 on CVSS 3.1 and 8.8 on CVSS 4.0, and the vector says integrity none. It reads and it can hold database threads open; it cannot change a row. That does not make it minor — a hash out of the database is a credential, and every cracked one is a legitimate login — but it does change what you hunt for. There is no modified data to find. The evidence is a request with a backtick in it, a response that returned too much, and slow queries if SLEEP() was used.

Three things decide the outcome. Whether you are on 4.7.0 or 5.0.0-alpha4, and whether you treated 4.6.0 through 4.6.6 as affected despite the upstream advisory's narrower bound. Whether you forced a password reset, because patching stops future reads and does nothing the hashes already taken. And whether you have accepted that this is the seventh SQL injection finding in YesWiki this year — which makes it a codebase pattern, a standing subscription to the project's advisories, and a reason to look at every remaining hand-built query rather than just this one.

Upgrade to 4.7.0 or 5.0.0-alpha4. Block backticks in query and searchfields until you do. Force a password reset and review logins for credentials users did not type. Then read YesWiki's advisories directly, because the fix lands there before the identifier does.

— The ThreatAft Security Team

ThreatAft is an independent security publication. This analysis is based on the CVE.org record, NVD, CIRCL Vulnerability-Lookup, VulDB, Volerion, the upstream GitHub advisory, YesWiki release notes, Rapid7, Glexia, Strix, East Bay Cyber and Feedly as of 25 October 2026. No public exploit code and no confirmed in-the-wild exploitation were identified at the time of writing; the record carried no EPSS score and was not in CISA KEV. Exploitation status and fixed-version availability are time-sensitive and should be rechecked against vendor advisories before production changes.

Extracted Entities