D-Tale Remote Code Execution (RCE)
CVE ID: CVE-2026-27194
Product: D-Tale (Flask-based pandas DataFrame visualization tool)
Vulnerability Type: Remote Code Execution (Improper Input Neutralization)
CWE: CWE-74 – Injection
CVSS v4.0 (Base Score): 8.1 (High)
Attack Vector: Network
Attack Complexity: Low
Privileges Required: None (in typical exposed deployments)
User Interaction: None
Impact: Full server-side code execution with the privileges of the D-Tale process
Exploit Availability: No large-scale public exploit kit observed at disclosure time; technically straightforward to weaponize
Affected Versions: All versions prior to 3.20.0
Patched Version: 3.20.0
Overview
A remote code execution vulnerability was identified in D-Tale due to improper validation of user-supplied filter expressions. D-Tale allows users to interactively filter pandas DataFrames via a web interface. Internally, user-supplied filter values are passed to pandas.DataFrame.query() for evaluation.
In vulnerable versions, insufficient sanitization allowed crafted input to inject malicious Python expressions. Because DataFrame.query() can evaluate expressions within the Python execution context, it became possible for arbitrary code to be executed on the server hosting D-Tale.
If the service was exposed to untrusted networks, an attacker could remotely execute system commands without authentication.
Technical Root Cause
The vulnerability originated from how filter parameters were processed and forwarded into pandas’ query engine.
Key technical issues included:
- Direct interpolation of user-controlled input into query expressions.
- Lack of strict token validation prior to execution.
- Inadequate filtering of Python built-in functions and dangerous object references.
- Failure to restrict special method (dunder) access patterns.
The query evaluation context allowed expressions that could reference:
__import__eval()exec()os.systemsubprocessopen()- object traversal via
__class__,__globals__, etc.
This allowed attackers to break out of expected filtering logic and execute arbitrary commands.
The patch introduced:
- Strict pattern validation
- Blocking of dangerous tokens
- Final defensive validation before invoking
DataFrame.query() - Additional hardening around expression parsing
Exploitation Scenario
A typical attack flow would involve:
- Identification of a reachable D-Tale instance (commonly running on port 40000 or a custom Flask port).
- Sending a crafted POST request to the filter-related endpoint (commonly
/save-column-filter). - Injecting malicious Python expression payload inside filter parameters.
- Triggering execution within
DataFrame.query(). - Gaining remote shell command execution under the D-Tale process user.
If the D-Tale service was running as root or had access to sensitive data, full system compromise was possible.
Example Educational PoC Payloads
For defensive research and lab validation only. Do not test against systems without authorization.
Example payload patterns that demonstrate exploit mechanics:
__import__('os').system('id')
__import__('subprocess').check_output(['whoami'])
().__class__.__bases__[0].__subclasses__()
These payloads attempt:
- Importing system modules
- Executing OS commands
- Traversing object hierarchy to escape sandbox assumptions
If successful, the HTTP response may contain command output or the server may exhibit behavioral anomalies (new processes, outbound connections, etc.).
Indicators of Compromise (IoCs)
HTTP-Level Indicators
- POST requests to
/save-column-filter - Filter values containing:
__import__exec(eval(os.subprocess__class____globals__compile(open(
System-Level Indicators
- Python process spawning:
/bin/shbashcurlwget
- Unexpected outbound network connections
- Reverse shell behavior
- New cron entries
- Unauthorized SSH key modifications
Application Logs
- Tracebacks referencing
DataFrame.query - Unexpected evaluation errors
- Suspicious filter expressions logged
Detection Guidance
Log Sources to Monitor
- Web server access logs (Nginx, Apache)
- Flask application logs
- Reverse proxy logs
- WAF logs
- EDR / XDR telemetry
- Linux audit logs (
auditd) - Container runtime logs (Docker, Kubernetes)
Splunk Detection Queries
1. Suspicious Filter Injection Attempt
index=web_logs
(uri_path="/save-column-filter" OR uri_path="/save_column_filter")
http_method=POST
| search "__import__" OR "exec(" OR "eval(" OR "os." OR "subprocess" OR "__class__"
| table _time, client_ip, uri_path, request_body
2. Abnormal Process Spawn from Python
index=endpoint_logs
parent_process_name="python"
| search process_name="bash" OR process_name="sh" OR process_name="curl" OR process_name="wget"
| table _time, host, parent_process_name, process_name, command_line
3. Outbound Connection After Web Request
index=network_logs
| stats count by src_ip, dest_ip, dest_port
| where dest_port IN (4444, 1337, 8081)
Elastic (KQL) Detection Queries
Suspicious HTTP Payload
url.path : "/save-column-filter" and
(http.request.body.content : "__import__" or
http.request.body.content : "exec(" or
http.request.body.content : "eval(" or
http.request.body.content : "os." or
http.request.body.content : "subprocess")
Python Spawning Shell
process.parent.name : "python" and
(process.name : "bash" or process.name : "sh" or process.name : "curl")
Suricata IDS Rule Example
alert http any any -> $HOME_NET any (
msg:"Possible D-Tale RCE Attempt";
flow:established,to_server;
content:"/save-column-filter"; http_uri;
pcre:"/(__import__|exec\s*\(|eval\s*\(|os\.|subprocess)/i";
classtype:web-application-attack;
sid:900001;
rev:1;
)
MITRE ATT&CK Mapping
| Tactic | Technique |
|---|---|
| Initial Access | Exploit Public-Facing Application (T1190) |
| Execution | Command and Scripting Interpreter (T1059) |
| Persistence | Create or Modify System Process (T1543) |
| Privilege Escalation | Exploitation for Privilege Escalation (T1068) |
| Defense Evasion | Obfuscated/Compressed Files or Information (T1027) |
Risk Assessment
If D-Tale was:
- Exposed to the internet
- Running without authentication
- Running as a privileged user
- Deployed inside production environments
Then impact could include:
- Data exfiltration
- Credential theft
- Lateral movement
- Ransomware staging
- Full server compromise
The vulnerability required no authentication in typical default deployments, making it particularly dangerous for publicly accessible instances.
Mitigation and Hardening
Immediate Actions
- Upgrade to version 3.20.0 or later
- Restart D-Tale service after upgrade
- Restrict network exposure
- Place behind VPN or reverse proxy with authentication
- Disable custom filters if not required
Security Hardening
- Run D-Tale as non-root user
- Use container isolation with seccomp profiles
- Enforce outbound firewall rules
- Implement WAF inspection
- Enable auditd for process tracking
- Monitor DNS and egress traffic
Official Patch
Upgrade to:
D-Tale 3.20.0 or later
Official package source:
https://pypi.org/project/dtale/
Upgrade command:
pip install --upgrade dtale
Final Assessment
CVE-2026-27194 represents a classic injection flaw resulting in remote code execution through unsafe query evaluation. The vulnerability is straightforward to exploit in exposed deployments and carries high impact.
Immediate patching is strongly recommended. Environments where D-Tale was publicly reachable should be treated as potentially compromised until verified clean.
