VYPR
Critical severityNVD Advisory· Published Jun 3, 2022· Updated Sep 17, 2024

Command Injection

CVE-2022-24065

Description

The package cookiecutter before 2.1.1 are vulnerable to Command Injection via hg argument injection. When calling the cookiecutter function from Python code with the checkout parameter, it is passed to the hg checkout command in a way that additional flags can be set. The additional flags can be used to perform a command injection.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Cookiecutter before 2.1.1 allows command injection via argument injection in the Mercurial (hg) checkout command.

Vulnerability

Overview

The cookiecutter library before version 2.1.1 is vulnerable to command injection when the checkout parameter is passed to the cookiecutter function. This issue arises because the checkout value is passed directly to the hg checkout command, allowing an attacker to inject additional flags. By crafting a malicious checkout value, an attacker can pass unintended arguments to hg, which can be leveraged to execute arbitrary commands on the system [1][2].

Attack

Vector & Prerequisites

To exploit this vulnerability, an attacker must be able to control the checkout parameter passed to the cookiecutter function. This could occur when a user or application programmatically calls cookiecutter with user-supplied input. The attack is network-based and requires no authentication if the vulnerable function is exposed to untrusted input [1][3]. The attack complexity is low, as the injection vector is straightforward [1].

Impact

Successful exploitation allows an attacker to inject and execute arbitrary commands with the privileges of the process running CookieCutter. This can lead to full system compromise, data exfiltration, or other malicious activities. The vulnerability was addressed in CookieCutter version 2.1.1, which sanitizes the checkout input before passing it to the hg command [2][4].

Remediation

Users should upgrade to CookieCutter version 2.1.1 or later to mitigate this vulnerability. If an immediate upgrade is not possible, ensure that the checkout parameter is never supplied with untrusted input [1][2].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
cookiecutterPyPI
< 2.1.12.1.1

Affected products

3

Patches

1
fdffddb31fd2

Merge pull request #1689 from cookiecutter/sanitize-mercurial-checkout

https://github.com/cookiecutter/cookiecutterJens W. KleinJun 1, 2022via ghsa
3 files changed · +24 10
  • cookiecutter/vcs.py+9 5 modified
    @@ -98,22 +98,26 @@ def clone(repo_url, checkout=None, clone_to_dir='.', no_input=False):
                     stderr=subprocess.STDOUT,
                 )
                 if checkout is not None:
    +                checkout_params = [checkout]
    +                # Avoid Mercurial "--config" and "--debugger" injection vulnerability
    +                if repo_type == "hg":
    +                    checkout_params.insert(0, "--")
                     subprocess.check_output(  # nosec
    -                    [repo_type, 'checkout', checkout],
    +                    [repo_type, 'checkout', *checkout_params],
                         cwd=repo_dir,
                         stderr=subprocess.STDOUT,
                     )
             except subprocess.CalledProcessError as clone_error:
                 output = clone_error.output.decode('utf-8')
                 if 'not found' in output.lower():
                     raise RepositoryNotFound(
    -                    'The repository {} could not be found, '
    -                    'have you made a typo?'.format(repo_url)
    +                    f'The repository {repo_url} could not be found, '
    +                    'have you made a typo?'
                     )
                 if any(error in output for error in BRANCH_ERRORS):
                     raise RepositoryCloneFailed(
    -                    'The {} branch of repository {} could not found, '
    -                    'have you made a typo?'.format(checkout, repo_url)
    +                    f'The {checkout} branch of repository '
    +                    f'{repo_url} could not found, have you made a typo?'
                     )
                 logger.error('git clone failed with error: %s', output)
                 raise
    
  • HISTORY.md+2 0 modified
    @@ -2,6 +2,8 @@
     
     History is important, but our current roadmap can be found [here](https://github.com/cookiecutter/cookiecutter/projects)
     
    +## 2.1.1 (unreleased)
    +
     ## 2.1.0 (2022-05-30)
     
     ### Changes
    
  • tests/vcs/test_clone.py+13 5 modified
    @@ -122,8 +122,16 @@ def test_clone_should_invoke_vcs_command(
         mock_subprocess.assert_any_call(
             [repo_type, 'clone', repo_url], cwd=str(clone_dir), stderr=subprocess.STDOUT
         )
    +
    +    branch_info = [branch]
    +    # We sanitize branch information for Mercurial
    +    if repo_type == "hg":
    +        branch_info.insert(0, "--")
    +
         mock_subprocess.assert_any_call(
    -        [repo_type, 'checkout', branch], cwd=expected_repo_dir, stderr=subprocess.STDOUT
    +        [repo_type, 'checkout', *branch_info],
    +        cwd=expected_repo_dir,
    +        stderr=subprocess.STDOUT,
         )
     
     
    @@ -151,8 +159,8 @@ def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
             vcs.clone(repository_url, clone_to_dir=str(clone_dir), no_input=True)
     
         assert str(err.value) == (
    -        'The repository {} could not be found, have you made a typo?'
    -    ).format(repository_url)
    +        f'The repository {repository_url} could not be found, have you made a typo?'
    +    )
     
     
     @pytest.mark.parametrize(
    @@ -182,8 +190,8 @@ def test_clone_handles_branch_typo(mocker, clone_dir, error_message):
     
         assert str(err.value) == (
             'The unknown_branch branch of repository '
    -        '{} could not found, have you made a typo?'
    -    ).format(repository_url)
    +        f'{repository_url} could not found, have you made a typo?'
    +    )
     
     
     def test_clone_unknown_subprocess_error(mocker, clone_dir):
    

Vulnerability mechanics

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

References

10

News mentions

0

No linked articles in our index yet.