PyCQA / PyCQA/bandit

#nosec not working for multi-line strings in python 3.8

Open
#658 14 comments 30 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
8.3k
Forks
835
Avg merge
5d 3h
Merged PRs (30d)
1

Description

The Problem

Starting python3.8 adding #nosec after a multi-line string has no effect. This was not the case in python 3.6 (and I think also 3.7)

How to Reproduce

Prepare two sample python source files

success.py:

table = "my_table"
query = f"SELECT * FROM {table}"  # nosec

fail.py

table = "my_table"
query = f"""
SELECT *
FROM {table}
"""  # nosec

Set up python3.6 and python3.8 environments

$ python3.6 -m venv venv36
$ python3.8 -m venv venv38

Run bandit using python3.6

$ source ./venv36/bin/activate
$ pip install bandit==1.6.3

Run bandit on success.py -- no issues.

$ bandit success.py
[main]  INFO    profile include tests: None
[main]  INFO    profile exclude tests: None
[main]  INFO    cli include tests: None
[main]  INFO    cli exclude tests: None
[main]  INFO    running on Python 3.6.12
[node_visitor]  INFO    Unable to find qualified name for module: success.py
Run started:2020-12-07 14:35:50.699373

Test results:
        No issues identified.

Code scanned:
        Total lines of code: 2
        Total lines skipped (#nosec): 1

Run metrics:
        Total issues (by severity):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
        Total issues (by confidence):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
Files skipped (0):

Run bandit on fail.py -- no issues either.

$ bandit fail.py
[main]  INFO    profile include tests: None
[main]  INFO    profile exclude tests: None
[main]  INFO    cli include tests: None
[main]  INFO    cli exclude tests: None
[main]  INFO    running on Python 3.6.12
[node_visitor]  INFO    Unable to find qualified name for module: fail.py
Run started:2020-12-07 14:25:36.277457

Test results:
        No issues identified.

Code scanned:
        Total lines of code: 5
        Total lines skipped (#nosec): 1

Run metrics:
        Total issues (by severity):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
        Total issues (by confidence):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
Files skipped (0):
$ deactivate

Run bandit in python3.8

$ source ./venv38/bin/activate
$ pip install bandit==1.6.3

Run bandit on success.py -- no issues.

$ bandit success.py 
[main]  INFO    profile include tests: None
[main]  INFO    profile exclude tests: None
[main]  INFO    cli include tests: None
[main]  INFO    cli exclude tests: None
[main]  INFO    running on Python 3.8.6
[node_visitor]  INFO    Unable to find qualified name for module: success.py
Run started:2020-12-07 14:37:02.909155

Test results:
        No issues identified.

Code scanned:
        Total lines of code: 2
        Total lines skipped (#nosec): 1

Run metrics:
        Total issues (by severity):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
        Total issues (by confidence):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
Files skipped (0):

Run bandit on fail.py -- one issue is reported.

$ bandit fail.py           
[main]  INFO    profile include tests: None
[main]  INFO    profile exclude tests: None
[main]  INFO    cli include tests: None
[main]  INFO    cli exclude tests: None
[main]  INFO    running on Python 3.8.6
[node_visitor]  INFO    Unable to find qualified name for module: fail.py
Run started:2020-12-07 14:26:41.664117

Test results:
>> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection vector through string-based query construction.
   Severity: Medium   Confidence: Low
   Location: fail.py:2
   More Info: https://bandit.readthedocs.io/en/latest/plugins/b608_hardcoded_sql_expressions.html
1       table = "my_table"
2       query = f"""
3       SELECT *
4       FROM {table}
5       """  # nosec

--------------------------------------------------

Code scanned:
        Total lines of code: 5
        Total lines skipped (#nosec): 0

Run metrics:
        Total issues (by severity):
                Undefined: 0.0
                Low: 0.0
                Medium: 1.0
                High: 0.0
        Total issues (by confidence):
                Undefined: 0.0
                Low: 1.0
                Medium: 0.0
                High: 0.0
Files skipped (0):
$ deactivate

Expected Behaviour

The #nosec clause should work both in python3.6 and python3.8. In this concrete example bandit fail.py should not fail in python3.8.

Bandit Version

On python3.6:

$ bandit --version
bandit 1.6.3
  python version = 3.6.12 (default, Nov  6 2020, 13:08:49) [GCC Apple LLVM 12.0.0 (clang-1200.0.32.21)]

On python3.8

$ bandit --version
bandit 1.6.3
  python version = 3.8.6 (default, Nov  6 2020, 13:26:24) [Clang 12.0.0 (clang-1200.0.32.21)]

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied success.py and fail.py examples and reproduce the difference under Python 3.6 and 3.8 using bandit 1.6.3. Trace how Bandit handles the trailing #nosec comment for a multi-line f-string, then add coverage for the failing case and confirm that bandit fail.py reports no issue when the expected suppression is restored.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
security, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.