CVE-2026-52773: Yeswiki/yeswiki Cross-Site Scripting Vulnerability
MODERATECVE-2026-52773 is a MODERATE (CVSS 6.1) cross-site scripting vulnerability (CWE-80: Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)) affecting Yeswiki/yeswiki libraries in the Packagist ecosystem. The issue involves yeswiki vulnerable to reflected xss via unescaped archived-revision `time` parameter in `handlers/page/show.php`. Remediation is available by upgrading affected packages to version 4.6.6.
CVE-2026-52773 at a Glance
Security Impact
CVSS: 6.1
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N).
How to Fix CVE-2026-52773
To remediate this vulnerability, upgrade all affected Yeswiki/yeswiki dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade yeswiki/yeswiki to 4.6.6
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for yeswiki/yeswiki
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-52773, inspect your project dependencies for Yeswiki/yeswiki:
inspect dependencies for yeswiki/yeswiki
Analyze the terminal output to locate any version of Yeswiki/yeswiki in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.6.6), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-80: Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS), where the product receives input from an upstream component, but it does not neutralize or incorrectly neutralizes special characters such as "<", ">", and "&" that could be interpreted as web-scripting elements when they are sent to a downstream component that processes web pages. In Yeswiki/yeswiki, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-52773 Affected Yeswiki/yeswiki Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
yeswiki/yeswiki
|
Packagist |
≥ 4.1.0
< 4.6.6
|
4.6.6
|
References
Frequently Asked Questions
What is CVE-2026-52773?
Which Yeswiki/yeswiki versions are affected?
What version fixes CVE-2026-52773?
Is yeswiki/yeswiki affected?
What is the CVSS score of CVE-2026-52773?
What CWE is associated with CVE-2026-52773?
How can I check Packagist dependencies for CVE-2026-52773?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-35f3-pg38-486f",
"modified" : "2026-07-09T21:00:55Z",
"published" : "2026-07-09T21:00:55Z",
"aliases" : [ "CVE-2026-52773" ],
"summary" : "YesWiki Vulnerable to Reflected XSS via Unescaped Archived-Revision `time` Parameter in `handlers/page/show.php`",
"details" : "### Summary\nYesWiki's archived-revision view reflects the `time` `GET` parameter into a hidden HTML input in `handlers/page/show.php` without escaping. Because MySQL coerces malformed `DATETIME` strings, an attacker can append HTML or JavaScript to a valid archived revision timestamp, still load that archived revision, and execute arbitrary JavaScript in the victim's browser.\n\nThe vulnerable form is only rendered when the victim can both read and edit the target page. In restricted deployments this requires a victim with `read` and `write` access to that page. On a default `doryphore 4.6.5` install, public pages such as `PagePrincipale` were editable anonymously during validation, so the issue can also affect unauthenticated visitors in that configuration.\n\n### Details\nThe request routing path uses the user-controlled `time` parameter to load a specific page revision. In `includes/YesWiki.php` around `Run()` line `1223`, the request is routed through:\n\n```php\n$this->SetPage($this->LoadPage($tag, isset($_REQUEST['time']) ? $_REQUEST['time'] : ''));\n```\n\n`LoadPage()` delegates to `PageManager::getOne()` in `includes/services/PageManager.php` around line `75`, which builds a SQL predicate directly from the supplied revision time:\n\n```php\n$timeQuery = $time ? \"time = '{$this->dbService->escape($time)}'\" : \"latest = 'Y'\";\n```\n\nIf the loaded page is an archived revision (`latest == 'N'`) and the current user has `write` access, `handlers/page/show.php` around lines `43-49` renders an edit form for that archived revision and copies `$_GET['time']` into a hidden input without `htmlspecialchars()`:\n\n```php\n$time = isset($_GET['time']) ? $_GET['time'] : '';\necho $this->FormOpen(testUrlInIframe() ? 'editiframe' : 'edit', '', 'get');\n<input type=\"hidden\" name=\"time\" value=\"<?php echo $time; ?>\" />\n```\n\nThat sink is reachable only when all of the following are true:\n\n1. The target page has at least one archived revision.\n2. The victim can `read` the target page.\n3. The victim can `write` the target page, because the archived revision edit form is rendered only inside the `if ($this->HasAccess('write'))` branch.\n\nIn practice, the payload must begin with a real archived revision timestamp. A completely invalid `time` value does not reach the archived branch because YesWiki only updates the current page object when the revision lookup returns a non-empty row.\n\nDuring local validation on the official `doryphore 4.6.5` package, the exploit worked because MySQL accepted a malformed timestamp string as matching an existing archived revision row. For example, the following expression was coerced to the stored revision time:\n\n```sql\nCAST(CONCAT('2026-05-24 04:30:00', CHAR(34), CHAR(62), CHAR(60), 'script', CHAR(62), 'alert(1)', CHAR(60), '/script', CHAR(62)) AS DATETIME)\n```\n\nand the corresponding query predicate still matched the archived row:\n\n```sql\nWHERE time = '2026-05-24 04:30:00\"><script>alert(1)</script>'\n```\n\nThis means a payload can begin with a valid archived revision timestamp, still resolve to the archived revision, and then be reflected unescaped into the hidden HTML field.\n\nFor comparison, `tools/bazar/handlers/page/show__.php` around lines `13-14` escapes the same `time` value with `htmlspecialchars()`, which shows that the core handler's behavior is inconsistent and unsafe.\n\nThis issue maps to **CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')**.\n\n### PoC\n1. Set up a vulnerable YesWiki instance. This was validated locally on the official `doryphore 4.6.5` release.\n2. Use a target page that has at least one archived revision. Any page with revision history is sufficient.\n3. Confirm the victim has the rights needed to reach the vulnerable sink:\n - The victim must have `read` access to the page.\n - The victim must have `write` access to the page.\n - On the default validation install, these rights were available anonymously on public pages such as `PagePrincipale`, so no login was required in that configuration.\n4. Identify the timestamp of an archived revision. In the validated setup, an archived `PagePrincipale` revision existed at `2026-05-24 04:30:00`.\n5. Send the victim a crafted URL that starts with that valid archived revision timestamp and then appends an attribute-breaking payload:\n\n```text\nhttp://127.0.0.1:8085/PagePrincipale?time=2026-05-24%2004:30:00%22%3E%3Cscript%3Ealert(1)%3C/script%3E%3Cinput%20value=%22\n```\n\n6. Open the URL in a browser as a victim who has the required `read` and `write` rights.\n7. Observe that YesWiki still loads the archived revision view and displays the archived-revision warning block, proving the malformed `time` value matched the stored archived revision.\n8. Inspect the returned HTML. The response contains the injected payload inside the hidden form field:\n\n```html\n<input type=\"hidden\" name=\"time\" value=\"2026-05-24 04:30:00\"><script>alert(1)</script><input value=\"\" />\n```\n\n9. The browser executes the injected JavaScript in the YesWiki origin. A simple payload such as `alert(1)` demonstrates code execution; a real payload could read browser-accessible data or perform actions in the victim's session.\n\n<img width=\"1600\" height=\"829\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d0b85a7c-2213-4459-908c-969934f06358\" />\n\n### Impact\nThis is a **reflected XSS** vulnerability in the archived-revision workflow.\n\nThe practical access model is:\n\n- The attacker only needs to send a crafted link.\n- The victim must have `read` and `write` access to the target page.\n- The target page must have at least one archived revision.\n- On deployments where anonymous visitors can edit public pages, the issue can be exploited against unauthenticated visitors as well.\n\nAn attacker may be able to:\n\n- Execute arbitrary JavaScript in the victim's browser.\n- Steal browser-accessible sensitive data.\n- Perform actions as the victim inside YesWiki.\n- Abuse the trusted YesWiki origin for phishing, UI redressing, or follow-on attacks.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "yeswiki/yeswiki"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "4.1.0"
}, {
"fixed" : "4.6.6"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-35f3-pg38-486f"
}, {
"type" : "WEB",
"url" : "https://github.com/YesWiki/yeswiki/commit/35ad9c2bb6cd338198b37c1f745e24bc302a3560"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/YesWiki/yeswiki"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-80" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-07-09T21:00:55Z",
"nvd_published_at" : null
}
}