YesWiki Vulnerable to Stored XSS in Comments
Description
YesWiki is a wiki system written in PHP. Prior to version 4.5.4, a stored cross-site scripting (XSS) vulnerability was discovered in the application’s comments feature. This issue allows a malicious actor to inject JavaScript payloads that are stored and later executed in the browser of any user viewing the affected comment. The XSS occurs because the application fails to properly sanitize or encode user input submitted to the comments. Notably, the application sanitizes or does not allow execution of <script> tags, but does not account for payloads obfuscated using JavaScript block comments like /* JavaScriptPayload */. This issue has been patched in version 4.5.4.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
yeswiki/yeswikiPackagist | < 4.5.4 | 4.5.4 |
Affected products
1Patches
10d4efc880a72fix(api): acls cannot be public and admins a the same time
4 files changed · +28 −29
docs/en/dev.md+1 −1 modified@@ -575,7 +575,7 @@ to ```php /** - * @Route("/api/myroute",options={"acl":{"public","@mygroup"}}) + * @Route("/api/myroute",options={"acl":{"@mygroup"}}) */ ```
includes/controllers/ApiController.php+25 −25 modified@@ -133,7 +133,7 @@ public function getUser($userId) } /** - * @Route("/api/users/{userId}/delete",methods={"POST"}, options={"acl":{"public","@admins"}}) + * @Route("/api/users/{userId}/delete",methods={"POST"}, options={"acl":{"@admins"}}) */ public function deleteUser($userId) { @@ -183,7 +183,7 @@ public function deleteUser($userId) } /** - * @Route("/api/users",methods={"POST"}, options={"acl":{"public","@admins"}}) + * @Route("/api/users",methods={"POST"}, options={"acl":{"@admins"}}) */ public function createUser() { @@ -276,7 +276,7 @@ public function getAllUsers($userFields = ['name', 'email', 'signuptime']) } /** - * @Route("api/groups/{group_name}/delete",methods={"POST"},options={"acl":{"public","@admins"}}) + * @Route("api/groups/{group_name}/delete",methods={"POST"},options={"acl":{"@admins"}}) */ public function deleteGroup(string $group_name) { @@ -451,7 +451,7 @@ public function getAllComments($tag = '') } /** - * @Route("/api/comments",methods={"POST"}, options={"acl":{"public","+"}}) + * @Route("/api/comments",methods={"POST"}, options={"acl":{"+"}}) */ public function postComment() { @@ -462,7 +462,7 @@ public function postComment() } /** - * @Route("/api/comments/{tag}",methods={"POST"}, options={"acl":{"public","+"}}) + * @Route("/api/comments/{tag}",methods={"POST"}, options={"acl":{"+"}}) */ public function editComment($tag) { @@ -473,7 +473,7 @@ public function editComment($tag) } /** - * @Route("/api/comments/{tag}",methods={"DELETE"}, options={"acl":{"public","+"}}) + * @Route("/api/comments/{tag}",methods={"DELETE"}, options={"acl":{"+"}}) */ public function deleteComment($tag) { @@ -488,7 +488,7 @@ public function deleteComment($tag) } /** - * @Route("/api/comments/{tag}/delete",methods={"POST"}, options={"acl":{"public","+"}}) + * @Route("/api/comments/{tag}/delete",methods={"POST"}, options={"acl":{"+"}}) */ public function deleteCommentViaPostMethod($tag) { @@ -563,7 +563,7 @@ public function getPage(Request $request, $tag) } /** - * @Route("/api/pages/{tag}/duplicate",methods={"POST"},options={"acl":{"public","@admins"}}) + * @Route("/api/pages/{tag}/duplicate",methods={"POST"},options={"acl":{"@admins"}}) */ public function duplicatePage(Request $request, $tag) { @@ -579,7 +579,7 @@ public function duplicatePage(Request $request, $tag) } /** - * @Route("/api/pages/{tag}",methods={"DELETE"},options={"acl":{"public","+"}}) + * @Route("/api/pages/{tag}",methods={"DELETE"},options={"acl":{"+"}}) */ public function deletePage($tag) { @@ -635,7 +635,7 @@ public function deletePage($tag) } /** - * @Route("/api/pages/{tag}/delete",methods={"POST"},options={"acl":{"public","+"}}) + * @Route("/api/pages/{tag}/delete",methods={"POST"},options={"acl":{"+"}}) */ public function deletePageByGetMethod($tag) { @@ -700,7 +700,7 @@ public function getReactionsFromUser($userId, $id) } /** - * @Route("/api/reactions/{idreaction}/{id}/{page}/{username}", methods={"DELETE"}, options={"acl":{"public", "+"}}) + * @Route("/api/reactions/{idreaction}/{id}/{page}/{username}", methods={"DELETE"}, options={"acl":{"+"}}) */ public function deleteReaction($idreaction, $id, $page, $username) { @@ -738,15 +738,15 @@ public function deleteReaction($idreaction, $id, $page, $username) } /** - * @Route("/api/reactions/{idreaction}/{id}/{page}/{username}/delete",methods={"GET"},options={"acl":{"public","+"}}) + * @Route("/api/reactions/{idreaction}/{id}/{page}/{username}/delete",methods={"GET"},options={"acl":{"+"}}) */ public function deleteReactionByGetMethod($idreaction, $id, $page, $username) { return $this->deleteReaction($idreaction, $id, $page, $username); } /** - * @Route("/api/reactions", methods={"POST"}, options={"acl":{"public", "+"}}) + * @Route("/api/reactions", methods={"POST"}, options={"acl":{"+"}}) */ public function addReactionFromUser() { @@ -823,7 +823,7 @@ public function addReactionFromUser() } /** - * @Route("/api/triples", methods={"GET"}, options={"acl":{"public", "+"}}) + * @Route("/api/triples", methods={"GET"}, options={"acl":{"+"}}) */ public function ByResource() { @@ -848,7 +848,7 @@ public function ByResource() } /** - * @Route("/api/triples/{resource}", methods={"GET"}, options={"acl":{"public", "+"}}) + * @Route("/api/triples/{resource}", methods={"GET"}, options={"acl":{"+"}}) */ public function getTriplesByResource($resource) { @@ -873,7 +873,7 @@ public function getTriplesByResource($resource) } /** - * @Route("/api/triples/{resource}", methods={"POST"}, options={"acl":{"public", "+"}}) + * @Route("/api/triples/{resource}", methods={"POST"}, options={"acl":{"+"}}) */ public function setTriple($resource) { @@ -920,7 +920,7 @@ public function setTriple($resource) } /** - * @Route("/api/triples/{resource}/delete", methods={"POST"}, options={"acl":{"public", "+"}}) + * @Route("/api/triples/{resource}/delete", methods={"POST"}, options={"acl":{"+"}}) */ public function deleteTriples($resource) { @@ -1045,15 +1045,15 @@ private function extractTriplesParams(string $method, $resource): array } /** - * @Route("/api/archives/{id}", methods={"GET"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/{id}", methods={"GET"}, options={"acl":{"@admins"}}) */ public function getArchive($id) { return $this->getService(ArchiveController::class)->getArchive($id); } /** - * @Route("/api/archives/uidstatus/{uid}", methods={"GET"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/uidstatus/{uid}", methods={"GET"}, options={"acl":{"@admins"}}) */ public function getArchiveStatus($uid) { @@ -1064,7 +1064,7 @@ public function getArchiveStatus($uid) } /** - * @Route("/api/archives/archivingStatus/", methods={"GET"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/archivingStatus/", methods={"GET"}, options={"acl":{"@admins"}}) */ public function getArchivingStatus() { @@ -1075,7 +1075,7 @@ public function getArchivingStatus() } /** - * @Route("/api/archives/forcedUpdateToken/", methods={"GET"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/forcedUpdateToken/", methods={"GET"}, options={"acl":{"@admins"}}) */ public function getForcedUpdateToken() { @@ -1088,8 +1088,8 @@ public function getForcedUpdateToken() } /** - * @Route("/api/archives/", methods={"GET"}, options={"acl":{"public", "@admins"}}) - * @Route("/api/archives", methods={"GET"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/", methods={"GET"}, options={"acl":{"@admins"}}) + * @Route("/api/archives", methods={"GET"}, options={"acl":{"@admins"}}) */ public function getArchives() { @@ -1102,15 +1102,15 @@ public function getArchives() } /** - * @Route("/api/archives/{id}", methods={"POST"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives/{id}", methods={"POST"}, options={"acl":{"@admins"}}) */ public function archiveAction($id) { return $this->getService(ArchiveController::class)->manageArchiveAction($id); } /** - * @Route("/api/archives", methods={"POST"}, options={"acl":{"public", "@admins"}}) + * @Route("/api/archives", methods={"POST"}, options={"acl":{"@admins"}}) */ public function archivesAction() {
includes/YesWikiInit.php+0 −1 modified@@ -339,7 +339,6 @@ public function initRoutes($wiki) new AnnotationReader() ) ); - // Core controllers $routes->addCollection($loader->load('includes/controllers'));
tools/templates/controllers/ApiController.php+2 −2 modified@@ -10,7 +10,7 @@ class ApiController extends YesWikiController { /** - * @Route("/api/templates/custom-presets/{presetFilename}", methods={"DELETE"},options={"acl":{"public","@admins"}}) + * @Route("/api/templates/custom-presets/{presetFilename}", methods={"DELETE"},options={"acl":{"@admins"}}) */ public function deleteCustomCSSPreset($presetFilename) { @@ -23,7 +23,7 @@ public function deleteCustomCSSPreset($presetFilename) } /** - * @Route("/api/templates/custom-presets/{presetFilename}", methods={"POST"},options={"acl":{"public","+"}}) + * @Route("/api/templates/custom-presets/{presetFilename}", methods={"POST"},options={"acl":{"+"}}) */ public function addCustomCSSPreset($presetFilename) {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-59x8-cvxh-3mm4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-46346ghsaADVISORY
- github.com/YesWiki/yeswiki/commit/0d4efc880a727599fa4f6d7a64cc967afe475530ghsax_refsource_MISCWEB
- github.com/YesWiki/yeswiki/security/advisories/GHSA-59x8-cvxh-3mm4ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.