Search code examples
pythonshellsubprocesscode-injection

* not expanded in subprocess.Popen (security implications)


this works but shell injection is a security risk

p = subprocess.Popen(['mv ./*.pdf ./target.pdf'], shell=True)

this doesn't work as * won't glob

p = subprocess.Popen(['mv', './*.pdf', './target.pdf'])

I'm watching a directory. How can I rename an arriving pdf to target.pdf without compromising security?


Solution

  • You can use the glob command from the glob module to get shell like path extensions:

    glob.glob(pathname, *, recursive=False)

    Return a possibly-empty list of path names that match pathname, which must be a string containing a path specification. pathname can be either absolute (like /usr/src/Python-1.5/Makefile) or relative (like ../../Tools/*/*.gif), and can contain shell-style wildcards. Broken symlinks are included in the results (as in the shell).

    If recursive is true, the pattern ** will match any files and zero or more directories and subdirectories. If the pattern is followed by an os.sep, only directories and subdirectories match.

    (taken from the docs)

    In your case it could look like this:

    import shutil
    import glob
    
    sources = glob.glob('*.pdf')
    destination = "target.pdf"
    for file in sources:
        shutil.move(file, destination)