What is the way to ignore/skip some issues from python bandit security issues report?
Asked Answered
P

5

54

I've got a bunch of django_mark_safe errors

>> Issue: [B703:django_mark_safe] Potential XSS on mark_safe function.
   Severity: Medium   Confidence: High
   Location: ...
   More Info: https://bandit.readthedocs.io/en/latest/plugins/b703_django_mark_safe.html
54 return mark_safe(f'<a href="{url}" target="_blank">{title}</a>')

>> Issue: [B308:blacklist] Use of mark_safe() may expose cross-site scripting vulnerabilities and should be reviewed.
   Severity: Medium   Confidence: High
   Location: ...
   More Info: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b308-mark-safe
54 return mark_safe(f'<a href="{url}" target="_blank">{title}</a>')

And I'm curious if there is a way to skip or ignore such lines? I understand that using mark_safe could be dangerous, but what if I want to take the risk? For example this method is the only way to display custom link in Django admin, so I don't know any other option how to do it without mark_safe

Proteiform answered 1/10, 2018 at 18:9 Comment(0)
P
75

I've got an answer here:

Two ways:

  1. You can skip the B703 and B308 using the --skip argument to the command line.
  2. Or you can affix a comment # nosec on the line to skip.

https://bandit.readthedocs.io/en/latest/config.html#exclusions

Proteiform answered 2/10, 2018 at 15:26 Comment(0)
A
19

Heads up for annotating multilines with # nosec:

given:

li_without_nosec = [
    "select * from %s where 1 = 1 "
    % "foo"
]

li_nosec_at_start_works = [  # nosec - ✅ and you can put a comment
    "select * from %s where 1 = 1 "
    % "foo"
]  

# nosec - there's an enhancement request to marker above line
li_nosec_on_top_doesntwork = [  
    "select * from %s where 1 = 1 "
    % "foo"
]  

li_nosec_at_end_doesntwork = [
    "select * from %s where 1 = 1 "
    % "foo"
]  # nosec 

output:

>> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection vector through string-based query construction.
   Severity: Medium   Confidence: Low
   Location: test.py:3
   More Info: https://bandit.readthedocs.io/en/latest/plugins/b608_hardcoded_sql_expressions.html
2   li_without_nosec = [
3       "select * from %s where 1 = 1 "
4       % "foo"
5   ]

--------------------------------------------------
>> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection vector through string-based query construction.
   Severity: Medium   Confidence: Low
   Location: test.py:15
   More Info: https://bandit.readthedocs.io/en/latest/plugins/b608_hardcoded_sql_expressions.html
14  li_nosec_on_top_doesntwork = [
15      "select * from %s where 1 = 1 "
16      % "foo"
17  ]

--------------------------------------------------
>> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection vector through string-based query construction.
   Severity: Medium   Confidence: Low
   Location: test.py:21
   More Info: https://bandit.readthedocs.io/en/latest/plugins/b608_hardcoded_sql_expressions.html
20  li_nosec_at_end_doesntwork = [
21      "select * from %s where 1 = 1 "
22      % "foo"
23  ]  # nosec

Black

Here's hoping that black won't get involved and restructure the lines, moving the # nosec around.

so much for hope... black does move things around, just like it does with pylint directives, whenever the line length becomes too long. At which point # nosec ends up at the end.

You can either proactively break up the line and position # nosec at the first one. Or you can just wait out black and adjust if needed.

Affective answered 26/4, 2020 at 20:19 Comment(2)
Suppose I have a multi-line like this: assert(10<20,"a very long multiline message with \ for better readability....") then where do I place the #nosec?Surakarta
@Surakarta not sure. You could enter a new question outright, with your actual sample code, tag it bandit and link to this question (ping/DM me in a comment if you do that) and we can look for an answer. Unfortunately, until bandit allows top-of-code annotation comments, like pylint, the answer may be tightly coupled to your particular code's format so it is hard to reason about without seeing your code. Also, FWIW, if you use mypy, I think mypy # type: ignore are also operating with the same constraints as bandit so you could check what people are up to there.Affective
D
11

If you want to apply the rule in a local piece of your code you can do something like the following:

# this is my very basic python script

def foo():
   do_something_unsecure()  # nosec B703, B308

In that way you will skip those validations just in that line. In real work it can be probably the most appropriated way to skip some rules.

Dialect answered 8/7, 2022 at 4:57 Comment(0)
J
9

Just to complete the topic - in my case I had to rid of B322: input rule, and didn't wanted to write # nosec each time I found this problem in the code, or to always execute Bandit with a --skip flag.

So if you want to omit a certain rule for whole solution, you can create a .bandit file in the root of your project. Then you can write which rules should be skipped every time, for example:

[bandit]
skips: B322

And then Bandit will skip this check by default without need to give additional comments in the code.

Jonathonjonati answered 9/5, 2020 at 21:41 Comment(0)
R
3

You can config Bandit with .bandit INI file (only if it is invoked with -r option):

[bandit]
tests = B101,B102,B301

Or with pyproject.toml file:

[tool.bandit]
tests = ["B201", "B301"]
skips = ["B101", "B601"]

Or with yaml file:

skips: ['B101', 'B601']
assert_used:
  skips: ["*/test_*.py", "*/test_*.py"]

See https://bandit.readthedocs.io/en/latest/config.html

Rainer answered 22/6, 2022 at 13:14 Comment(1)
I was confused how you can use assert_used as a key in the config file -- it's not a listed in the main config.html -- This will configure each plugin based on the plugin name, see i.e. bandit.readthedocs.io/en/1.7.5/plugins/b101_assert_used.htmlOzonize

© 2022 - 2024 — McMap. All rights reserved.