CVE-2026-23946 Overview
CVE-2026-23946 is an insecure deserialization vulnerability affecting Tendenci, an open source content management system designed for non-profits, associations, and cause-based sites. The vulnerability exists in the Helpdesk module's run_report() function, which improperly uses Python's unsafe pickle.loads() method to deserialize user-controlled data. This flaw allows authenticated users with staff security level to achieve Remote Code Execution (RCE) on vulnerable systems.
This vulnerability represents an incomplete patch of the earlier CVE-2020-14942. While the original fix addressed the ticket_list() function by implementing safe JSON deserialization, the run_report() function in /reports/ was overlooked and continued to use the dangerous pickle deserialization method.
Critical Impact
Authenticated staff users can execute arbitrary code on the server through unsafe pickle deserialization in the Helpdesk reports functionality, potentially leading to full system compromise within the context of the web application user.
Affected Products
- Tendenci CMS versions 15.3.11 and below
- Tendenci installations with the Helpdesk module enabled
- Self-hosted Tendenci deployments running vulnerable versions
Discovery Timeline
- January 22, 2026 - CVE-2026-23946 published to NVD
- January 22, 2026 - Last updated in NVD database
Technical Details for CVE-2026-23946
Vulnerability Analysis
This vulnerability stems from the insecure use of Python's pickle module for deserializing data in the Helpdesk reporting functionality. Python's pickle module is inherently unsafe when processing untrusted data because it can execute arbitrary code during the deserialization process. An attacker can craft a malicious serialized object that, when unpickled, executes arbitrary Python code on the server.
The vulnerability is particularly notable because it represents a regression from an earlier security fix. When CVE-2020-14942 was addressed, developers patched the ticket_list() function to use safe JSON deserialization, but the run_report() function was missed, leaving the same class of vulnerability exposed through a different code path. The impact is limited to the permissions of the user running the application, typically www-data, which generally lacks write permissions (except for upload directories) and execute permissions.
Root Cause
The root cause is the use of pickle.loads() to deserialize base64-encoded query parameters stored in saved queries. The vulnerable code path exists in tendenci/apps/helpdesk/views/staff.py within the report generation functionality. When a saved query is loaded for report execution, the serialized query parameters are decoded and unpickled without any validation or sanitization, allowing arbitrary Python objects to be instantiated and their methods executed.
Attack Vector
The attack requires authentication with staff-level privileges in the Tendenci CMS. An attacker must create or modify a saved query containing a malicious pickled payload encoded in base64. When the run_report() function processes this query, it deserializes the payload using pickle.loads(), triggering code execution. The attack is delivered over the network through the web interface at the /helpdesk/reports/ endpoint.
The following patches demonstrate the fix that replaces unsafe pickle deserialization with JSON:
# Before (vulnerable):
import pickle
from base64 import b64decode
query_params = pickle.loads(b64decode(str(saved_query.query).encode()))
# After (fixed):
#import pickle
from base64 import b64decode
#query_params = pickle.loads(b64decode(str(saved_query.query).encode()))
query_params = simplejson.loads(b64decode(str(saved_query.query).encode()))
Source: Tendenci Commit Refactor
Detection Methods for CVE-2026-23946
Indicators of Compromise
- Unusual HTTP requests to /helpdesk/reports/ endpoints with encoded payloads
- Unexpected processes spawned by the www-data user or web server process
- Modified or newly created saved queries in the Helpdesk module with suspicious base64-encoded content
- Web server logs showing unusual POST requests to report-related URLs
Detection Strategies
- Monitor web application logs for access to /helpdesk/reports/ endpoints by staff users
- Implement file integrity monitoring on Tendenci application directories
- Deploy web application firewall rules to detect serialized Python objects in HTTP parameters
- Review audit logs for unexpected saved query creation or modification events
Monitoring Recommendations
- Enable verbose logging for the Helpdesk module to capture all report generation requests
- Set up alerts for any subprocess execution originating from the web application process
- Monitor for outbound network connections from the web server that may indicate reverse shell attempts
- Regularly audit staff user accounts and their associated saved queries
How to Mitigate CVE-2026-23946
Immediate Actions Required
- Upgrade Tendenci to version 15.3.12 or later immediately
- If upgrade is not immediately possible, disable the Helpdesk module until patching is complete
- Audit all staff-level user accounts for unauthorized access
- Review existing saved queries in the Helpdesk module for suspicious content
Patch Information
The vulnerability has been addressed in Tendenci version 15.3.12. The fix replaces the unsafe pickle.loads() calls with secure simplejson.loads() deserialization across multiple files including tendenci/apps/helpdesk/views/staff.py and tendenci/apps/imports/views.py. Organizations should upgrade to version 15.3.12 or later as documented in the Tendenci Release v15.3.12.
Additional details are available in the Tendenci Security Advisory GHSA-339m-4qw5-j2g3 and the GitHub Security Advisory GHSA-jqmc-fxxp-r589.
Workarounds
- Disable the Helpdesk module by removing it from INSTALLED_APPS in your Tendenci configuration
- Restrict staff-level access to only trusted administrators until the patch is applied
- Implement network-level access controls to limit access to the /helpdesk/reports/ endpoint
- Consider deploying a web application firewall to filter potentially malicious serialized payloads
# Configuration example - Disable Helpdesk module in settings.py
# Remove or comment out 'tendenci.apps.helpdesk' from INSTALLED_APPS
# Then restart the application server
# Using nginx to block access to the vulnerable endpoint
location /helpdesk/reports/ {
deny all;
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

