VYPR
High severityNVD Advisory· Published Mar 24, 2026· Updated Mar 24, 2026

Intake has a Command Injection via shell() Expansion in Parameter Defaults

CVE-2026-33310

Description

Intake is a package for finding, investigating, loading and disseminating data. Prior to version 2.0.9, the shell() syntax within parameter default values appears to be automatically expanded during the catalog parsing process. If a catalog contains a parameter default such as shell(<command>), the command may be executed when the catalog source is accessed. This means that if a user loads a malicious catalog YAML, embedded commands could execute on the host system. Version 2.0.9 mitigates the issue by making getshell False by default everywhere.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
intakePyPI
<= 2.0.9

Affected products

1

Patches

1
d0c0b6b57c1c

Make getshell False by default everywhere

https://github.com/intake/intakeMartin DurantMar 9, 2026via ghsa
5 files changed · +14 9
  • intake/catalog/base.py+1 1 modified
    @@ -53,7 +53,7 @@ def __init__(
             metadata=None,
             ttl=60,
             getenv=True,
    -        getshell=True,
    +        getshell=False,
             persist_mode="default",
             storage_options=None,
             user_parameters=None,
    
  • intake/catalog/entry.py+1 1 modified
    @@ -15,7 +15,7 @@ class CatalogEntry(DictSerialiseMixin):
         and by remote entries (read from a server).
         """
     
    -    def __init__(self, getenv=True, getshell=True):
    +    def __init__(self, getenv=True, getshell=False):
             self._default_source = None
             self.getenv = getenv
             self.getshell = getshell
    
  • intake/catalog/local.py+3 3 modified
    @@ -102,7 +102,7 @@ def describe(self):
                     desc[attr] = v
             return desc
     
    -    def expand_defaults(self, client=False, getenv=True, getshell=True):
    +    def expand_defaults(self, client=False, getenv=True, getshell=False):
             """Compile env, client_env, shell and client_shell commands"""
             if not isinstance(self._default, str):
                 self.expanded_default = self._default
    @@ -150,7 +150,7 @@ def __init__(
             metadata={},
             catalog_dir="",
             getenv=True,
    -        getshell=True,
    +        getshell=False,
             catalog=None,
         ):
             """
    @@ -333,7 +333,7 @@ def clear_cached_default_source(self):
     class CatalogParser(object):
         """Loads entries from a YAML spec"""
     
    -    def __init__(self, data, getenv=True, getshell=True, context=None):
    +    def __init__(self, data, getenv=True, getshell=False, context=None):
             self._context = context if context else {}
             self._errors = []
             self._warnings = []
    
  • intake/catalog/utils.py+8 3 modified
    @@ -13,6 +13,7 @@
     import shlex
     import subprocess
     import sys
    +import warnings
     
     
     def flatten(iterable):
    @@ -112,7 +113,7 @@ def _expand(p, context, all_vars, client, getenv, getshell):
             return p
     
     
    -def expand_templates(pars, context, return_left=False, client=False, getenv=True, getshell=True):
    +def expand_templates(pars, context, return_left=False, client=False, getenv=True, getshell=False):
         """
         Render variables in context into the set of parameters with jinja2.
     
    @@ -140,7 +141,7 @@ def expand_templates(pars, context, return_left=False, client=False, getenv=True
         return out
     
     
    -def expand_defaults(default, client=False, getenv=True, getshell=True):
    +def expand_defaults(default, client=False, getenv=True, getshell=False):
         """Compile env, client_env, shell and client_shell commands
     
         Execution rules:
    @@ -168,17 +169,21 @@ def expand_defaults(default, client=False, getenv=True, getshell=True):
                 default = subprocess.check_output(cmd).rstrip().decode("utf8")
             except (subprocess.CalledProcessError, OSError):
                 default = ""
    +    else:
    +        warnings.warn("Shell command not executed due to getshell=False")
         r = re.match(r"client_shell\((.*)\)", default)
         if r and client and getshell:
             try:
                 cmd = shlex.split(r.groups()[0])
                 default = subprocess.check_output(cmd).rstrip().decode("utf8")
             except (subprocess.CalledProcessError, OSError):
                 default = ""
    +    else:
    +        warnings.warn("Shell command not executed due to getshell=False")
         return default
     
     
    -def merge_pars(params, user_inputs, spec_pars, client=False, getenv=True, getshell=True):
    +def merge_pars(params, user_inputs, spec_pars, client=False, getenv=True, getshell=False):
         """Produce open arguments by merging various inputs
     
         This function is called in the context of a catalog entry, when finalising
    
  • .pre-commit-config.yaml+1 1 modified
    @@ -1,7 +1,7 @@
     # This is the configuration for pre-commit, a local framework for managing pre-commit hooks
     #   Check out the docs at: https://pre-commit.com/
     
    -default_stages: [commit]
    +default_stages: [pre-commit]
     repos:
     -   repo: https://github.com/pre-commit/pre-commit-hooks
         rev: v4.4.0
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

3