CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-8f2v-2qhj-gfwg: YesWiki: Second-Order SQL Injection in Page Delete API via Unescaped Page Tag (`ApiController::deletePage`)

highCVSS 8.3CVE-2026-52771
Summary ApiController::deletePage() interpolates a page tag retrieved from the database into a DELETE FROM …_links WHERE to_tag = '$tag' query without escaping. The page tag is attacker-controlled — the POST /api/pages/{tag} API accepts arbitrary URL-encoded values, including single quotes, and stores them. A low-privilege authenticated user can therefore create a page whose tag is a SQL fragment, make the page non-orphaned via the standard {{include page="…"}} link mechanism, and then invoke the delete endpoint to execute arbitrary SQL inside the wiki database - including time-based blind data exfiltration from any table. This is a classic second-order SQL injection: the INSERT correctly escapes the value, so the malicious tag is stored intact and the input passes every "is this value safe to put in the database?" check; the sink is the *read-back-and-reuse* path, where escaping is omitted. Details Affected component - File: includes/controllers/ApiController.php - Method: ApiController::deletePage($tag) - Route: @Route("/api/pages/{tag}", methods={"DELETE"}, options={"acl":{"+"}}) — acl:"+" means *any authenticated user*. - Sink: line 626 // includes/controllers/ApiController.php (v4.6.5 = origin/doryphore-dev HEAD, // lines 607–631) public function deletePage($tag) { $pageManager = $this->getService(PageManager::class); $pageController = $this->getService(PageController::class); $dbService = $this->getService(DbService::class); ... try { $page = $pageManager->getOne($tag, null, false); // (a) safe SELECT if (empty($page)) { ... } else { $tag = isset($page['tag']) ? $page['tag'] : $tag;// ^ raw tag from DB $result['notDeleted'] = [$tag]; if ($this->wiki->UserIsOwner($tag) || $this->wiki->UserIsAdmin()) { if (!$pageManager->isOrphaned($tag)) { $dbService->query( "DELETE FROM {$dbService->prefixTable('links')} WHERE to_tag = '$tag'"); // (b) SINK — unescaped } ... The same anti-pattern shows up in two adjacent files; both were noted in the original submission a

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 8.3
Published
2026-07-09
Last updated
2026-07-09
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-8f2v-2qhj-gfwg

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-52771coverage & exploitation statusNVD · CVE.org

More from GitHub Security Advisories