-
Notifications
You must be signed in to change notification settings - Fork 0
π‘οΈ Sentinel: [CRITICAL] Fix command injection risks #569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3934ec8
8d55e66
ea78d1f
ec155e5
13a70ac
065edc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,7 @@ | |
| def run_command(command): | ||
| """Run a shell command and return the output.""" | ||
| try: | ||
| result = subprocess.run(command, shell=True, capture_output=True, text=True, check=True) | ||
| result = subprocess.run(command, capture_output=True, text=True, check=True) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. Source: opengrep |
||
| return result.stdout.strip() | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Error running command: {command}") | ||
|
|
@@ -26,7 +26,7 @@ def run_command(command): | |
|
|
||
| def get_local_branches(): | ||
| """Get list of local branches.""" | ||
| output = run_command("git branch") | ||
| output = run_command(["git", "branch"]) | ||
| if output is None: | ||
| return [] | ||
|
|
||
|
|
@@ -39,7 +39,7 @@ def get_local_branches(): | |
|
|
||
| def get_remote_branches(): | ||
| """Get list of remote branches.""" | ||
| output = run_command("git branch -r") | ||
| output = run_command(["git", "branch", "-r"]) | ||
| if output is None: | ||
| return [] | ||
|
|
||
|
|
@@ -140,19 +140,19 @@ def suggest_new_name(branch_name): | |
| def rename_local_branch(old_name, new_name): | ||
| """Rename a local branch.""" | ||
| print(f"Renaming local branch '{old_name}' to '{new_name}'") | ||
| result = run_command(f"git branch -m {old_name} {new_name}") | ||
| result = run_command(["git", "branch", "-m", old_name, new_name]) | ||
| return result is not None | ||
|
|
||
| def delete_remote_branch(branch_name): | ||
| """Delete a remote branch.""" | ||
| print(f"Deleting remote branch '{branch_name}'") | ||
| result = run_command(f"git push origin --delete {branch_name.replace('origin/', '')}") | ||
| result = run_command(["git", "push", "origin", "--delete", branch_name.replace('origin/', '')]) | ||
| return result is not None | ||
|
|
||
| def push_new_branch(branch_name): | ||
| """Push a new branch to remote.""" | ||
| print(f"Pushing new branch '{branch_name}'") | ||
| result = run_command(f"git push -u origin {branch_name}") | ||
| result = run_command(["git", "push", "-u", "origin", branch_name]) | ||
| return result is not None | ||
|
|
||
| def main(): | ||
|
|
@@ -214,7 +214,7 @@ def main(): | |
| # Delete local branches marked for deletion | ||
| for branch in branches_to_delete: | ||
| print(f"Deleting local branch '{branch}'") | ||
| result = run_command(f"git branch -d {branch}") | ||
| result = run_command(["git", "branch", "-d", branch]) | ||
| if result is not None: | ||
| print(f"β Deleted local branch '{branch}'") | ||
| else: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,7 +114,8 @@ def check_worktree_status(self): | |
| self.print_status("Checking worktree status") | ||
|
|
||
| print("\nWorktrees found:") | ||
| os.system("git worktree list") | ||
| import subprocess | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this correctly fixes the security vulnerability, for better code style and adherence to PEP 8 guidelines, imports should be placed at the top of the file. Please move References
|
||
| subprocess.run(["git", "worktree", "list"]) | ||
|
|
||
| print("\nWorktree documentation status:") | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Normalize and log commands consistently now that
shell=Trueis removedWith
shell=Trueremoved and most callers now passing a list,commandwill often be a sequence, so the error message will log a Python list repr, which is noisy and harder to reuse. Consider normalizingcommandtoList[str]and logging' '.join(command), and tightening the type ofcommandto discourage string inputs that rely on shell parsing.Suggested implementation:
If this file (or project) targets Python versions earlier than 3.10, you should replace the
str | Noneandlist[str]annotations withOptional[str]andList[str]and import them fromtyping. Also ensure there isnβt already an import namedSequencefrom a different module to avoid conflicts with the newly addedfrom collections.abc import Sequence.