Tbalz
Tbalz

Reputation: 692

Python Error using subprocess without shell=false and variable from an array

I have the code snippet that works with shell=True which isn't secure and when i attempt to remove shell=True and include shell=False the program errors out

The code is below:

cmd = "git clone https://github.com/{} &"    
#define a worker function
def worker():
    while True:
        item = q.get()
        subprocess.Popen(cmd.format(item))
        q.task_done()

I get the error below:

File "rapid.py", line 56, in worker
    subprocess.Popen(cmd.format(item))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'git clone https://github.com/laramies/theHarvester.git &': 'git clone https://github.com/laramies/theHarvester.git &'

if i add shell = True to the subprocess line it runs just fine (see below) but then code factor flags it as insecure code. Any way to do this without shell = true?

cmd = "git clone https://github.com/{} &"    
#define a worker function
def worker():
    while True:
        item = q.get()
        subprocess.Popen(cmd.format(item), shell = True)
        q.task_done()

Upvotes: 2

Views: 870

Answers (1)

Aaron A
Aaron A

Reputation: 495

The command is being passed to subprocess.Popen as a string. This works when using shell=True because the shell can accept a command as a single string. But when shell=False, Popen expects the command as a list of arguments, the first one being the full path of the program to run. (This is assuming you're on a POSIX machine, not Windows.)

Essentially, the code says "Run a program called git clone https://github.com/laramies/theHarvester.git with no arguments" instead of "Run git with arguments clone and https://github.com/laramies/theHarvester.git".

The & should also be removed because that is a shell feature and with shell=False it would be passed to git as an argument it won't understand. You don't need it though, since the process will run in the background anyway.

Something like this should work:

subprocess.Popen(["/usr/bin/git", "clone", "https://github.com/{}".format(item)])

More info here: https://docs.python.org/3.7/library/subprocess.html#popen-constructor

Upvotes: 2

Related Questions