== How to fix it in Paramiko

=== Code examples

include::../../common/fix/code-rationale.adoc[]

In the following example, if the *host* request parameter contains system
shell control characters, the expected `ping` command behavior will be changed.

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
from flask import Flask, request
from paramiko.client import SSHClient

app = Flask(__name__)

@app.route('/example')
def example():
    client = SSHClient()
    client.connect("example.org", username=USER, password=PASS)

    client.exec_command(request.args.get("cmd")) # Noncompliant
----

==== Compliant solution

[source,python,diff-id=1,diff-type=compliant]
----
from flask import Flask, request
from paramiko.client import SSHClient

app = Flask(__name__)

@app.route('/example')
def example():
    client = SSHClient()
    client.connect("example.org", username=USER, password=PASS)

    DIAG_CMD=["/bin/ping -c 1 -- %s", "/bin/host -- %s"]
    cmd = DIAG_CMD[int(request.args.get('cmdId'))]
    cmd = cmd % shlex.quote(request.args.get('host'))
    client.exec_command(cmd)
----

=== How does this work?

include::../../common/fix/introduction.adoc[]

include::../../common/fix/pre-approved-list.adoc[]

:sanitizationLib: shlex

include::../../common/fix/sanitize-meta-characters.adoc[]

In the example compliant code, the `quote` function from the `shlex` is used to
encode the user-controlled command argument. It escapes argument delimiters
and shell control characters.
