-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bf7d7cb
commit 458500f
Showing
7 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from core_codemods.subprocess_shell_false import SubprocessShellFalse | ||
from integration_tests.base_test import ( | ||
BaseIntegrationTest, | ||
original_and_expected_from_code_path, | ||
) | ||
|
||
|
||
class TestSubprocessShellFalse(BaseIntegrationTest): | ||
codemod = SubprocessShellFalse | ||
code_path = "tests/samples/subprocess_run.py" | ||
original_code, expected_new_code = original_and_expected_from_code_path( | ||
code_path, [(1, "subprocess.run(\"echo 'hi'\", shell=False)\n")] | ||
) | ||
expected_diff = "--- \n+++ \n@@ -1,2 +1,2 @@\n import subprocess\n-subprocess.run(\"echo 'hi'\", shell=True)\n+subprocess.run(\"echo 'hi'\", shell=False)\n" | ||
expected_line_change = "2" | ||
change_description = SubprocessShellFalse.CHANGE_DESCRIPTION | ||
# expected because output code points to fake file | ||
allowed_exceptions = (FileNotFoundError,) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/core_codemods/docs/pixee_python_subprocess-shell-false.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
This codemod sets the `shell` keyword argument to `False` in `subprocess` module function calls that have set it to `True`. | ||
|
||
Setting `shell=True` will execute the provided command through the system shell which can lead to shell injection vulnerabilities. | ||
|
||
The changes from this codemod look like this: | ||
|
||
```diff | ||
import subprocess | ||
- subprocess.run("echo 'hi'", shell=True) | ||
+ subprocess.run("echo 'hi'", shell=False) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import libcst as cst | ||
from libcst import matchers | ||
from codemodder.codemods.api import BaseCodemod, ReviewGuidance | ||
from codemodder.codemods.utils_mixin import NameResolutionMixin | ||
from codemodder.codemods.api.helpers import NewArg | ||
|
||
|
||
class SubprocessShellFalse(BaseCodemod, NameResolutionMixin): | ||
NAME = "subprocess-shell-false" | ||
SUMMARY = "Use `shell=False` in `subprocess` Function Calls" | ||
REVIEW_GUIDANCE = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW | ||
DESCRIPTION = "Set `shell` keyword argument to `False`" | ||
REFERENCES: list = [] | ||
SUBPROCESS_FUNCS = [ | ||
f"subprocess.{func}" | ||
for func in {"run", "call", "check_output", "check_call", "Popen"} | ||
] | ||
|
||
def leave_Call(self, original_node: cst.Call, updated_node: cst.Call): | ||
if self.find_base_name(original_node.func) in self.SUBPROCESS_FUNCS: | ||
for arg in original_node.args: | ||
if matchers.matches( | ||
arg.keyword, matchers.Name("shell") | ||
) and matchers.matches(arg.value, matchers.Name("True")): | ||
self.report_change(original_node) | ||
new_args = self.replace_args( | ||
original_node, | ||
[NewArg(name="shell", value="False", add_if_missing=False)], | ||
) | ||
return self.update_arg_target(updated_node, new_args) | ||
return original_node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import pytest | ||
from core_codemods.subprocess_shell_false import SubprocessShellFalse | ||
from tests.codemods.base_codemod_test import BaseCodemodTest | ||
|
||
each_func = pytest.mark.parametrize( | ||
"func", ["check_output", "check_call", "run", "call", "Popen"] | ||
) | ||
|
||
|
||
class TestSubprocessShellFalse(BaseCodemodTest): | ||
codemod = SubprocessShellFalse | ||
|
||
def test_name(self): | ||
assert self.codemod.name() == "subprocess-shell-false" | ||
|
||
@each_func | ||
def test_import(self, tmpdir, func): | ||
input_code = f"""import subprocess | ||
subprocess.{func}(args, shell=True) | ||
""" | ||
expexted_output = f"""import subprocess | ||
subprocess.{func}(args, shell=False) | ||
""" | ||
|
||
self.run_and_assert(tmpdir, input_code, expexted_output) | ||
assert len(self.file_context.codemod_changes) == 1 | ||
|
||
@each_func | ||
def test_from_import(self, tmpdir, func): | ||
input_code = f"""from subprocess import {func} | ||
{func}(args, shell=True) | ||
""" | ||
expexted_output = f"""from subprocess import {func} | ||
{func}(args, shell=False) | ||
""" | ||
|
||
self.run_and_assert(tmpdir, input_code, expexted_output) | ||
assert len(self.file_context.codemod_changes) == 1 | ||
|
||
@each_func | ||
def test_no_shell(self, tmpdir, func): | ||
input_code = f"""import subprocess | ||
subprocess.{func}(args, timeout=1) | ||
""" | ||
self.run_and_assert(tmpdir, input_code, input_code) | ||
assert len(self.file_context.codemod_changes) == 0 | ||
|
||
@each_func | ||
def test_shell_False(self, tmpdir, func): | ||
input_code = f"""import subprocess | ||
subprocess.{func}(args, shell=False) | ||
""" | ||
self.run_and_assert(tmpdir, input_code, input_code) | ||
assert len(self.file_context.codemod_changes) == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import subprocess | ||
subprocess.run("echo 'hi'", shell=True) |