Skip to main content
Vulnerability Database/CVE-2026-93349

CVE-2026-93349: Frictionless OS Command Injection RCE Vulnerability

CVE-2026-93349 is an OS command injection flaw in Frictionless that enables remote code execution through crafted Data Package descriptors. This post explains the technical details, affected versions, and mitigation steps.

Published:

CVE-2026-93349 Overview

CVE-2026-93349 is an operating system command injection vulnerability [CWE-78] in Frictionless, a Python library for working with tabular data packages. The flaw affects versions through 5.20.0rc1 and resides in the explore console command. An attacker who crafts a malicious Data Package descriptor can execute arbitrary shell commands as the user who runs frictionless explore against the package. Resource path values inside datapackage.json are passed unsanitized to os.system through a shell, allowing embedded shell metacharacters to break out of the intended command. Exploitation runs in the victim's security context on their local system.

Critical Impact

A crafted datapackage.json descriptor executes arbitrary OS commands under the invoking user's account when the explore command is run against an untrusted package.

Affected Products

  • Frictionless (frictionless-py) versions through 5.20.0rc1
  • Command-line explore console command
  • Any environment where users run frictionless explore against third-party Data Packages

Discovery Timeline

  • 2026-09-23 - CVE-2026-93349 published to the National Vulnerability Database
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-93349

Vulnerability Analysis

Frictionless processes Data Package descriptors, JSON documents that describe tabular data resources and their file paths. The explore console command reads a datapackage.json file and launches an exploration interface for the referenced resources. During this workflow, resource path values are concatenated into a shell command string and passed to os.system, which invokes /bin/sh -c on Unix and cmd.exe /c on Windows.

Because the resource path is interpolated into the shell command without escaping or quoting, any shell metacharacter in the path is interpreted by the shell rather than treated as a filename. Characters such as ;, |, &, backticks, and $() allow an attacker to append or substitute arbitrary commands. The injected commands execute with the same privileges as the user who invoked frictionless explore.

Root Cause

The root cause is the use of os.system with an unsanitized, attacker-controlled string. The Frictionless code path treats resource.path values from the descriptor as trusted local filenames and interpolates them into a shell command. No allow-listing, escaping, or use of a safer API such as subprocess.run with an argument list is applied before invocation.

Attack Vector

Exploitation requires user interaction: the victim must download or receive a malicious Data Package and run the frictionless explore command against it. The attacker distributes a datapackage.json in which a resource path field contains shell metacharacters and appended commands. When the victim executes the explore subcommand, the shell parses the crafted path and runs the injected commands. No authentication or network access to a Frictionless service is required; the attack model is a malicious data artifact processed by a local tool.

A proof-of-concept demonstrating the injection is published at the GitHub PoC for CVE-2026-93349.

Detection Methods for CVE-2026-93349

Indicators of Compromise

  • Presence of shell metacharacters (;, |, &, `, $(), >, <) inside path fields of any datapackage.json descriptor.
  • frictionless process spawning unexpected child processes such as sh, bash, cmd.exe, powershell.exe, curl, wget, or python with attacker-controlled arguments.
  • Outbound network connections initiated by processes whose parent is a Python interpreter running the Frictionless CLI.
  • New scheduled tasks, cron entries, or shell profile modifications created shortly after an explore command execution.

Detection Strategies

  • Inspect all incoming datapackage.json files with a linter that flags non-filesystem characters in path values before analysts open them.
  • Enable process-lineage telemetry to detect Python or Frictionless CLI processes spawning shell interpreters or network utilities.
  • Correlate execution of frictionless explore with subsequent process creation, file writes to sensitive directories, and outbound connections.

Monitoring Recommendations

  • Log command-line arguments for all frictionless invocations on analyst workstations and data-engineering hosts.
  • Alert on any use of os.system-style shell invocations from Python interpreters that include user data directories in their arguments.
  • Track installations of frictionless-py across the environment and flag versions at or below 5.20.0rc1.

How to Mitigate CVE-2026-93349

Immediate Actions Required

  • Upgrade frictionless-py to a version that includes the fix from GitHub Pull Request #1820.
  • Do not run frictionless explore against Data Packages sourced from untrusted parties until the upgrade is applied.
  • Inventory analyst and data-engineering workstations for vulnerable Frictionless installations and prioritize patching.
  • Review recent explore command history on shared systems for signs of exploitation.

Patch Information

The fix is tracked in GitHub Pull Request #1820 in the frictionlessdata/frictionless-py repository. The VulnCheck advisory for Frictionless OS command injection provides additional context on affected versions and remediation guidance.

Workarounds

  • Avoid the explore subcommand entirely on untrusted Data Packages until patched.
  • Manually inspect datapackage.json descriptors and reject any where path values contain characters outside [A-Za-z0-9._/-].
  • Run Frictionless inside a sandboxed container or unprivileged user account with no network egress when processing third-party data.
  • Use file-integrity monitoring on user profile directories to detect persistence attempts after any exploratory command.
bash
# Configuration example: upgrade Frictionless and validate descriptor paths
pip install --upgrade frictionless

# Reject descriptors containing shell metacharacters in resource paths
python - <<'PY'
import json, re, sys
desc = json.load(open('datapackage.json'))
for r in desc.get('resources', []):
    p = r.get('path', '')
    if isinstance(p, str) and not re.fullmatch(r'[A-Za-z0-9._/-]+', p):
        sys.exit(f'Unsafe path detected: {p!r}')
print('Descriptor paths validated.')
PY

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.