
    >/ih                        S SK r S SKrS SKrS SKJr  S SKJr  \R                  " S5      rS r	S r
S r\R                  " S5      \R                  " S	5      \R                  " S
5      S 5       5       5       r\R                  " S5      \R                  " S	5      \R                  " S5      S 5       5       5       r\R                  " S5      \R                  " S	5      \R                  " S5      S 5       5       5       r\R                  " S5      \R                  " S	5      \R                  " S5      S 5       5       5       r\R                  " S5      \R                  " S	5      \R                  " S5      S 5       5       5       r\R                  " S5      \R                  " S	5      \R                  " S5      S 5       5       5       rg)    N)issue)test_propertiesz^(?:[A-Za-z](?=\:)|[\\\/\.])c                 "   [        U R                  R                  S   [        R                  5      =(       a1    [        U R                  R                  S   R
                  [        5      nU(       a  [        R                  $ [        R                  $ )Nr   )

isinstancenodeargsastConstantvaluestrbanditLOWHIGH)contextno_formattings     X/home/james-whalen/.local/lib/python3.13/site-packages/bandit/plugins/injection_shell.py_evaluate_shell_callr      sd    !cll 6
W\\&&q)//
5  zz{{    c                 (    U S:X  a  / SQ/ SQ/ SQS.$ g )Nshell_injection)zsubprocess.Popenzsubprocess.callzsubprocess.check_callzsubprocess.check_outputzsubprocess.run)z	os.systemzos.popenz	os.popen2z	os.popen3z	os.popen4zpopen2.popen2zpopen2.popen3zpopen2.popen4zpopen2.Popen3zpopen2.Popen4zcommands.getoutputzcommands.getstatusoutputzsubprocess.getoutputzsubprocess.getstatusoutput)zos.execlz	os.execlez	os.execlpz
os.execlpezos.execvz	os.execvez	os.execvpz
os.execvpez	os.spawnlz
os.spawnlez
os.spawnlpzos.spawnlpez	os.spawnvz
os.spawnvez
os.spawnvpzos.spawnvpezos.startfile)
subprocessshellno_shell )names    r   
gen_configr      s)      $;0
 0	
 !r   c                 r   U R                   R                  nSnSU R                  ;   Ga  U GH  nUR                  S:X  d  M  UR                  n[        U[        R                  5      (       at  [        UR                  [        5      (       d>  [        UR                  [        5      (       d  [        UR                  [        5      (       a  [        UR                  5      nM  [        U[        R                  5      (       a  [        UR                  5      nM  [        U[        R                  5      (       a  [        UR                  5      nGM"  [        U[        R                   5      (       a  UR"                  S;   a  SnGMV  [        U[        R                  5      (       a  UR                  nGM  SnGM     U$ )NFr   )FalseNoneT)r   keywordscall_keywordsargr   r   r	   r
   intfloatcomplexboolListeltsDictkeysNameid)r   r    resultkeyvals        r   	has_shellr0   Q   s   ||$$HF''''Cww'!iic3<<00syy#..!#))U33!#))W55!#))_FSXX..!#((^FSXX..!#((^FSXX..366=N3N"FS\\22 YYF!F% & Mr   r   CallB602c           	      >   U(       Ga  U R                   US   ;   Ga   [        U 5      (       a  [        U R                  5      S:  a  [	        U 5      nU[
        R                  :X  a[  [
        R                  " [
        R                  [
        R                  [        R                  R                  SU R                  S5      S9$ [
        R                  " [
        R                  [
        R                  [        R                  R                  SU R                  S5      S9$ gggg)at  **B602: Test for use of popen with shell equals true**

Python possesses many mechanisms to invoke an external executable. However,
doing so may present a security issue if appropriate care is not taken to
sanitize any user provided or variable input.

This plugin test is part of a family of tests built to check for process
spawning and warn appropriately. Specifically, this test looks for the
spawning of a subprocess using a command shell. This type of subprocess
invocation is dangerous as it is vulnerable to various shell injection
attacks. Great care should be taken to sanitize all input in order to
mitigate this risk. Calls of this type are identified by a parameter of
'shell=True' being given.

Additionally, this plugin scans the command string given and adjusts its
reported severity based on how it is presented. If the command string is a
simple static string containing no special shell characters, then the
resulting issue has low severity. If the string is static, but contains
shell formatting characters or wildcards, then the reported issue is
medium. Finally, if the string is computed using Python's string
manipulation or formatting operations, then the reported issue has high
severity. These severity levels reflect the likelihood that the code is
vulnerable to injection.

See also:

- :doc:`../plugins/linux_commands_wildcard_injection`
- :doc:`../plugins/subprocess_without_shell_equals_true`
- :doc:`../plugins/start_process_with_no_shell`
- :doc:`../plugins/start_process_with_a_shell`
- :doc:`../plugins/start_process_with_partial_path`

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

This plugin specifically scans for methods listed in `subprocess` section
that have shell=True specified.

.. code-block:: yaml

    shell_injection:

        # Start a process using the subprocess module, or one of its
        wrappers.
        subprocess:
            - subprocess.Popen
            - subprocess.call


:Example:

.. code-block:: none

    >> Issue: subprocess call with shell=True seems safe, but may be
    changed in the future, consider rewriting without shell
       Severity: Low   Confidence: High
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: ./examples/subprocess_shell.py:21
    20  subprocess.check_call(['/bin/ls', '-l'], shell=False)
    21  subprocess.check_call('/bin/ls -l', shell=True)
    22

    >> Issue: call with shell=True contains special shell characters,
    consider moving extra logic into Python code
       Severity: Medium   Confidence: High
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: ./examples/subprocess_shell.py:26
    25
    26  subprocess.Popen('/bin/ls *', shell=True)
    27  subprocess.Popen('/bin/ls %s' % ('something',), shell=True)

    >> Issue: subprocess call with shell=True identified, security issue.
       Severity: High   Confidence: High
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: ./examples/subprocess_shell.py:27
    26  subprocess.Popen('/bin/ls *', shell=True)
    27  subprocess.Popen('/bin/ls %s' % ('something',), shell=True)
    28  subprocess.Popen('/bin/ls {}'.format('something'), shell=True)

.. seealso::

 - https://security.openstack.org
 - https://docs.python.org/3/library/subprocess.html#frequently-used-arguments
 - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html
 - https://security.openstack.org/guidelines/dg_avoid-shell-true.html
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.9.0

.. versionchanged:: 1.7.3
    CWE information added

r   r   znsubprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shellr   severity
confidencecwetextlinenoz;subprocess call with shell=True identified, security issue.N)call_function_name_qualr0   len	call_argsr   r   r   Issuer   r   CweOS_COMMAND_INJECTIONget_lineno_for_call_argr   configsevs      r   'subprocess_popen_with_shell_equals_truerD   k   s    L '11VL5IIW7$$%)*73&**$!<<!'#);;!II::2  '>>wG  "<<!'#);;!II::*&>>wG  *  Jvr   B603c           	         U(       a  U R                   US   ;   al  [        U 5      (       d[  [        R                  " [        R                  [        R
                  [        R                  R                  SU R                  S5      S9$ ggg)a	  **B603: Test for use of subprocess without shell equals true**

Python possesses many mechanisms to invoke an external executable. However,
doing so may present a security issue if appropriate care is not taken to
sanitize any user provided or variable input.

This plugin test is part of a family of tests built to check for process
spawning and warn appropriately. Specifically, this test looks for the
spawning of a subprocess without the use of a command shell. This type of
subprocess invocation is not vulnerable to shell injection attacks, but
care should still be taken to ensure validity of input.

Because this is a lesser issue than that described in
`subprocess_popen_with_shell_equals_true` a LOW severity warning is
reported.

See also:

- :doc:`../plugins/linux_commands_wildcard_injection`
- :doc:`../plugins/subprocess_popen_with_shell_equals_true`
- :doc:`../plugins/start_process_with_no_shell`
- :doc:`../plugins/start_process_with_a_shell`
- :doc:`../plugins/start_process_with_partial_path`

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

This plugin specifically scans for methods listed in `subprocess` section
that have shell=False specified.

.. code-block:: yaml

    shell_injection:
        # Start a process using the subprocess module, or one of its
        wrappers.
        subprocess:
            - subprocess.Popen
            - subprocess.call

:Example:

.. code-block:: none

    >> Issue: subprocess call - check for execution of untrusted input.
       Severity: Low   Confidence: High
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: ./examples/subprocess_shell.py:23
    22
    23    subprocess.check_output(['/bin/ls', '-l'])
    24

.. seealso::

 - https://security.openstack.org
 - https://docs.python.org/3/library/subprocess.html#frequently-used-arguments
 - https://security.openstack.org/guidelines/dg_avoid-shell-true.html
 - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.9.0

.. versionchanged:: 1.7.3
    CWE information added

r   z9subprocess call - check for execution of untrusted input.r   r4   N)
r:   r0   r   r=   r   r   r   r>   r?   r@   r   rB   s     r   $subprocess_without_shell_equals_truerH      sq    T '11VL5II!!<<!;;II2266w?  " Jvr   B604c           	         U(       a  U R                   US   ;  al  [        U 5      (       a[  [        R                  " [        R                  [        R
                  [        R                  R                  SU R                  S5      S9$ ggg)a	  **B604: Test for any function with shell equals true**

Python possesses many mechanisms to invoke an external executable. However,
doing so may present a security issue if appropriate care is not taken to
sanitize any user provided or variable input.

This plugin test is part of a family of tests built to check for process
spawning and warn appropriately. Specifically, this plugin test
interrogates method calls for the presence of a keyword parameter `shell`
equalling true. It is related to detection of shell injection issues and is
intended to catch custom wrappers to vulnerable methods that may have been
created.

See also:

- :doc:`../plugins/linux_commands_wildcard_injection`
- :doc:`../plugins/subprocess_popen_with_shell_equals_true`
- :doc:`../plugins/subprocess_without_shell_equals_true`
- :doc:`../plugins/start_process_with_no_shell`
- :doc:`../plugins/start_process_with_a_shell`
- :doc:`../plugins/start_process_with_partial_path`

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

Specifically, this plugin excludes those functions listed under the
subprocess section, these methods are tested in a separate specific test
plugin and this exclusion prevents duplicate issue reporting.

.. code-block:: yaml

    shell_injection:
        # Start a process using the subprocess module, or one of its
        wrappers.
        subprocess: [subprocess.Popen, subprocess.call,
                     subprocess.check_call, subprocess.check_output
                     execute_with_timeout]


:Example:

.. code-block:: none

    >> Issue: Function call with shell=True parameter identified, possible
    security issue.
       Severity: Medium   Confidence: High
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: ./examples/subprocess_shell.py:9
    8 pop('/bin/gcc --version', shell=True)
    9 Popen('/bin/gcc --version', shell=True)
    10

.. seealso::

 - https://security.openstack.org/guidelines/dg_avoid-shell-true.html
 - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.9.0

.. versionchanged:: 1.7.3
    CWE information added

r   zLFunction call with shell=True parameter identified, possible security issue.r   r4   N)
r:   r0   r   r=   MEDIUMr   r   r>   r?   r@   rG   s     r   )any_other_function_with_shell_equals_truerL   @  sq    R '119MMW<<!::II22+66w?   Nvr   B605c                    U(       a  U R                   US   ;   a  [        U R                  5      S:  a  [        U 5      nU[        R
                  :X  aK  [        R                  " [        R
                  [        R                  [        R                  R                  SS9$ [        R                  " [        R                  [        R                  [        R                  R                  SS9$ ggg)aY
  **B605: Test for starting a process with a shell**

Python possesses many mechanisms to invoke an external executable. However,
doing so may present a security issue if appropriate care is not taken to
sanitize any user provided or variable input.

This plugin test is part of a family of tests built to check for process
spawning and warn appropriately. Specifically, this test looks for the
spawning of a subprocess using a command shell. This type of subprocess
invocation is dangerous as it is vulnerable to various shell injection
attacks. Great care should be taken to sanitize all input in order to
mitigate this risk. Calls of this type are identified by the use of certain
commands which are known to use shells. Bandit will report a LOW
severity warning.

See also:

- :doc:`../plugins/linux_commands_wildcard_injection`
- :doc:`../plugins/subprocess_without_shell_equals_true`
- :doc:`../plugins/start_process_with_no_shell`
- :doc:`../plugins/start_process_with_partial_path`
- :doc:`../plugins/subprocess_popen_with_shell_equals_true`

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

This plugin specifically scans for methods listed in `shell` section.

.. code-block:: yaml

    shell_injection:
        shell:
            - os.system
            - os.popen
            - os.popen2
            - os.popen3
            - os.popen4
            - popen2.popen2
            - popen2.popen3
            - popen2.popen4
            - popen2.Popen3
            - popen2.Popen4
            - commands.getoutput
            - commands.getstatusoutput
            - subprocess.getoutput
            - subprocess.getstatusoutput

:Example:

.. code-block:: none

    >> Issue: Starting a process with a shell: check for injection.
       Severity: Low   Confidence: Medium
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: examples/os_system.py:3
    2
    3   os.system('/bin/echo hi')

.. seealso::

 - https://security.openstack.org
 - https://docs.python.org/3/library/os.html#os.system
 - https://docs.python.org/3/library/subprocess.html#frequently-used-arguments
 - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.10.0

.. versionchanged:: 1.7.3
    CWE information added

r   r   zoStarting a process with a shell: Seems safe, but may be changed in the future, consider rewriting without shellr5   r6   r7   r8   zMStarting a process with a shell, possible injection detected, security issue.N)r:   r;   r<   r   r   r   r=   r   r   r>   r?   rA   s      r   start_process_with_a_shellrP     s    b '11VG_Dw  !A%&w/Cfjj ||#ZZ%{{		667	  ||#[[%{{		661	  & Evr   B606c                     U(       a_  U R                   US   ;   aK  [        R                  " [        R                  [        R                  [
        R                  R                  SS9$ gg)a@
  **B606: Test for starting a process with no shell**

Python possesses many mechanisms to invoke an external executable. However,
doing so may present a security issue if appropriate care is not taken to
sanitize any user provided or variable input.

This plugin test is part of a family of tests built to check for process
spawning and warn appropriately. Specifically, this test looks for the
spawning of a subprocess in a way that doesn't use a shell. Although this
is generally safe, it maybe useful for penetration testing workflows to
track where external system calls are used.  As such a LOW severity message
is generated.

See also:

- :doc:`../plugins/linux_commands_wildcard_injection`
- :doc:`../plugins/subprocess_without_shell_equals_true`
- :doc:`../plugins/start_process_with_a_shell`
- :doc:`../plugins/start_process_with_partial_path`
- :doc:`../plugins/subprocess_popen_with_shell_equals_true`

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

This plugin specifically scans for methods listed in `no_shell` section.

.. code-block:: yaml

    shell_injection:
        no_shell:
            - os.execl
            - os.execle
            - os.execlp
            - os.execlpe
            - os.execv
            - os.execve
            - os.execvp
            - os.execvpe
            - os.spawnl
            - os.spawnle
            - os.spawnlp
            - os.spawnlpe
            - os.spawnv
            - os.spawnve
            - os.spawnvp
            - os.spawnvpe
            - os.startfile

:Example:

.. code-block:: none

    >> Issue: [start_process_with_no_shell] Starting a process without a
       shell.
       Severity: Low   Confidence: Medium
       CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
       Location: examples/os-spawn.py:8
    7   os.spawnv(mode, path, args)
    8   os.spawnve(mode, path, args, env)
    9   os.spawnvp(mode, file, args)

.. seealso::

 - https://security.openstack.org
 - https://docs.python.org/3/library/os.html#os.system
 - https://docs.python.org/3/library/subprocess.html#frequently-used-arguments
 - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.10.0

.. versionchanged:: 1.7.3
    CWE information added

r   z#Starting a process without a shell.rO   N)r:   r   r=   r   rK   r   r>   r?   rG   s     r   start_process_with_no_shellrS     sQ    j '11VJ5GG||ZZ}}		..6	
 	
 Hvr   B607c                    U(       Ga_  [        U R                  5      (       GaC  U R                  US   ;   d'  U R                  US   ;   d  U R                  US   ;   Ga  U R                  R                  S   n[        U[        R                  5      (       a   UR                  (       a  UR                  S   n[        U[        R                  5      (       a  [        UR                  [        5      (       ap  [        R                  UR                  5      (       dK  [        R                  " [        R                   [        R"                  [$        R&                  R(                  SS9$ gggggg)a
  **B607: Test for starting a process with a partial path**

Python possesses many mechanisms to invoke an external executable. If the
desired executable path is not fully qualified relative to the filesystem
root then this may present a potential security risk.

In POSIX environments, the `PATH` environment variable is used to specify a
set of standard locations that will be searched for the first matching
named executable. While convenient, this behavior may allow a malicious
actor to exert control over a system. If they are able to adjust the
contents of the `PATH` variable, or manipulate the file system, then a
bogus executable may be discovered in place of the desired one. This
executable will be invoked with the user privileges of the Python process
that spawned it, potentially a highly privileged user.

This test will scan the parameters of all configured Python methods,
looking for paths that do not start at the filesystem root, that is, do not
have a leading '/' character.

**Config Options:**

This plugin test shares a configuration with others in the same family,
namely `shell_injection`. This configuration is divided up into three
sections, `subprocess`, `shell` and `no_shell`. They each list Python calls
that spawn subprocesses, invoke commands within a shell, or invoke commands
without a shell (by replacing the calling process) respectively.

This test will scan parameters of all methods in all sections. Note that
methods are fully qualified and de-aliased prior to checking.

.. code-block:: yaml

    shell_injection:
        # Start a process using the subprocess module, or one of its
        wrappers.
        subprocess:
            - subprocess.Popen
            - subprocess.call

        # Start a process with a function vulnerable to shell injection.
        shell:
            - os.system
            - os.popen
            - popen2.Popen3
            - popen2.Popen4
            - commands.getoutput
            - commands.getstatusoutput
        # Start a process with a function that is not vulnerable to shell
        injection.
        no_shell:
            - os.execl
            - os.execle


:Example:

.. code-block:: none

    >> Issue: Starting a process with a partial executable path
    Severity: Low   Confidence: High
    CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
    Location: ./examples/partial_path_process.py:3
    2    from subprocess import Popen as pop
    3    pop('gcc --version', shell=False)

.. seealso::

 - https://security.openstack.org
 - https://docs.python.org/3/library/os.html#process-management
 - https://cwe.mitre.org/data/definitions/78.html

.. versionadded:: 0.13.0

.. versionchanged:: 1.7.3
    CWE information added

r   r   r   r   z1Starting a process with a partial executable pathrO   N)r;   r<   r:   r   r   r   r	   r'   r(   r
   r   r   full_path_matchmatchr   r=   r   r   r   r>   r?   )r   rB   r   s      r   start_process_with_partial_pathrX   Z  s   d #g''((++vl/CC..&/A..&2DD<<$$Q'D$))diiyy| 4..tzz3//'--djj99||#ZZ%{{		66L	  : 0 / E	 )vr   )r	   rer   bandit.corer   r   testcompilerV   r   r   r0   takes_configcheckstest_idrD   rH   rL   rP   rS   rX   r   r   r   <module>r`      s  
  	   / **<=2
j4 $%Vfy   &yx $%VfP   &Pf $%VfO   &Od $%Vfa   &aH $%VfX
   &X
v $%Vfe   &er   