CVE-2026-27194: Critical Remote Code Execution Flaw in D-Tale Exposes Servers to Full Takeover

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.system
  • subprocess
  • open()
  • 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:

  1. Identification of a reachable D-Tale instance (commonly running on port 40000 or a custom Flask port).
  2. Sending a crafted POST request to the filter-related endpoint (commonly /save-column-filter).
  3. Injecting malicious Python expression payload inside filter parameters.
  4. Triggering execution within DataFrame.query().
  5. 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/sh
    • bash
    • curl
    • wget
  • 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

TacticTechnique
Initial AccessExploit Public-Facing Application (T1190)
ExecutionCommand and Scripting Interpreter (T1059)
PersistenceCreate or Modify System Process (T1543)
Privilege EscalationExploitation for Privilege Escalation (T1068)
Defense EvasionObfuscated/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.


Aegiron

Backed by 11+ years in cybersecurity and incident response, we decode the latest threats shaping today’s digital battlefield. This blog cuts through the noise with clear insights on vulnerabilities, emerging exploits, and the cyber news defenders can’t afford to miss.