VYPR
Low severityNVD Advisory· Published Apr 29, 2025· Updated Apr 29, 2025

YesWiki Vulnerable to Stored XSS in Comments

CVE-2025-46346

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.

PackageAffected versionsPatched versions
yeswiki/yeswikiPackagist
< 4.5.44.5.4

Affected products

1

Patches

1
0d4efc880a72

fix(api): acls cannot be public and admins a the same time

https://github.com/YesWiki/yeswikiFlorian SchmittApr 16, 2025via ghsa
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

News mentions

0

No linked articles in our index yet.