2016-05-31 8 views
0

Ich habe Python-Skript, das Code hat.Sanitized Eingabe für Subprozess mit Shell = True in Python

... 
... 
p = subprocess.Popen(cmd, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE, 
        shell=True) 
output, error = p.communicate() 
... 
... 

Wenn ich bandit laufen lasse, gibt es einen Fehler.

>> Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified, security issue. 
    Severity: High Confidence: High 
    Location: mypackage/myfile.py:123 
123           stderr=subprocess.PIPE, 
124           shell=True) 
125      output, error = p.communicate() 

Dann mache ich etwas google, und stellte fest, dass ich meine Eingabe zu hygienisiert und mit shlex.split und shlex.quote Ich kann es sanieren.

Ich habe meinen Code geändert.

... 
... 
p = subprocess.Popen(shlex.split(shlex.quote(cmd)), 
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE, 
        shell=True) 
output, error = p.communicate() 
... 
... 

Aber ich immer noch denselben Fehler, gibt es eine Möglichkeit, diesen Fehler zu entfernen, wenn bandit -r mypackage/myfile.py laufen

+2

'bandit' kann nicht feststellen, ob das Befehlsargument ausreichend bereinigt ist; es kann nur erkennen, dass Sie 'Popen' in einer Weise verwenden, die ein Sicherheitsproblem darstellen könnte. Es ist wahrscheinlich besser, "shell = False" zu lassen und 'cmd' selbst so zu präparieren, dass es direkt von' exec' verwendet werden kann. – chepner

+0

Ein Analysator kann nicht feststellen, ob ein Befehl, den Sie ausführen, ein Befehl ist, den Sie * ausführen wollen. Abhängig von dem, was Sie tun, Sandboxing der Interpreter (zum Beispiel mit [codejail] (https://github.com/edx/codejail)) möglicherweise angemessen oder notwendig. Dies beinhaltet eine Kombination aus Eingabe-Sanitisierung und streng kontrollierten Betriebssystemberechtigungen. – gecko

+0

@chepner, 'exec' bedeutet,' subprocess.exec'? – Nilesh

Antwort

2

So geben Sie einen Benutzerbefehl, den er

Wenn der Benutzer ausgeführt werden soll kann bereits einen Befehl ausführen, einschließlich bash, dann ist die bandit Warnung über shell=True nicht anwendbar.

Die Warnung wäre sinnvoll, wenn der Benutzer nur erlaubt, wurden beispielsweise eine Suchabfrage für einen grep Befehl einige Parameter für einen bestimmten Befehl zu wählen:

rc = call(['grep', '-e', query, path]) 

unabhängig vom Benutzer angegebenen query wird; es wird nicht dazu führen, dass ein anderer Befehl ausgeführt wird (nur grep wird ausgeführt).

Vergleichen Sie es mit shell=True:

rc = call("grep -e '%s' '%s'" % (query, path), shell=True) #XXX don't do it 

Ein Benutzer query = "a' /dev/null; rm -rf '" passieren könnte, die grep -e 'a' /dev/null; rm -rf '' 'path' Befehl erzeugen würde.

shell=True ermöglicht es einem Benutzer, in diesem Fall einen beliebigen Befehl auszuführen, auch wenn dies nicht beabsichtigt ist. Es wird Shell-Injektion genannt.

Sie könnten pipes.quote(query) aufrufen, um naive Angriffe zu vermeiden, aber es kann im allgemeinen Fall fehlschlagen, weshalb shell=True vermieden werden sollte, wenn die Eingabe nicht von einer vertrauenswürdigen Quelle stammt.

+0

Danke Sebastian, ich werde versuchen etwas herauszufinden, um 'shell = True' zu entfernen, aber nachdem 'shell = False' gemacht wurde, wird immer noch' bandit' angezeigt. Es ändert "Schweregrad" von "Höhe" zu "Niedrig", es gibt keine Möglichkeit, dies auch zu entfernen? – Nilesh

+0

@Lafada 1- Der Punkt meiner Antwort ist, dass es wahrscheinlich sinnlos ist, 'shell = True' in deinem Fall zu entfernen - es wird deinen Code nicht sicherer machen. 2- wie man die Warnung des Banditen deaktiviert, ist eine gültige aber unterschiedliche Frage. Sie sollten es als separate Frage stellen. – jfs

+0

hier meine neue Frage http://StackOverflow.com/questions/37661695/remove-bandit-notify-for-paramiko-und-subprocess-popen :) – Nilesh