YesWiki Vulnerable to Unauthenticated Site Backup Creation and Download
Description
YesWiki is a wiki system written in PHP. Prior to version 4.5.4, the request to commence a site backup can be performed and downloaded without authentication. The archives are created with a predictable filename, so a malicious user could create and download an archive without being authenticated. This could result in a malicious attacker making numerous requests to create archives and fill up the file system, or by downloading the archive which contains sensitive site information. 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-wc9g-6j9w-hr95ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-46348ghsaADVISORY
- github.com/YesWiki/yeswiki/commit/0d4efc880a727599fa4f6d7a64cc967afe475530ghsax_refsource_MISCWEB
- github.com/YesWiki/yeswiki/security/advisories/GHSA-wc9g-6j9w-hr95ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.