Repository: PyCQA/bandit (python)

Issue:
Add sample, randrange, and getrandbits to B311 random module check?
**Is your feature request related to a problem? Please describe.**
I noticed that `random.choice` raises a B311 warning [here](https://github.com/PyCQA/bandit/blob/e4da0b351f89a82b5de8dd791cbdd963476b5a11/bandit/blacklists/calls.py#L513). I assume this is to try to stop someone from using it with a `range()` in security-related code. I noticed some other `random` functions that could be used in a similar way but are not currently checked: [`sample`](https://docs.python.org/3/library/random.html#random.sample), [`randrange` and `getrandbits`](https://docs.python.org/3/library/random.html#functions-for-integers).

**Describe the solution you'd like**
Add `random.sample`, `random.randrange`, and `random.getrandbits` to B311 check

**Describe alternatives you've considered**
None 

**Additional context**
N/A

Love this idea? Give it a 👍. We prioritize fulfilling features with the most 👍.


Pull request description:
Add more random functions to B311 check
Fixes #1215.

Patch:
diff --git a/bandit/blacklists/calls.py b/bandit/blacklists/calls.py
index 86f08a6..024e873 100644
--- a/bandit/blacklists/calls.py
+++ b/bandit/blacklists/calls.py
@@ -205,6 +205,9 @@ https://docs.python.org/library/secrets.html
 |      |                     | - random.uniform                   |           |
 |      |                     | - random.triangular                |           |
 |      |                     | - random.randbytes                 |           |
+|      |                     | - random.randrange                 |           |
+|      |                     | - random.sample                    |           |
+|      |                     | - random.getrandbits               |           |
 +------+---------------------+------------------------------------+-----------+
 
 B312: telnetlib
@@ -515,6 +518,9 @@ def gen_blacklist():
                 "random.uniform",
                 "random.triangular",
                 "random.randbytes",
+                "random.sample",
+                "random.randrange",
+                "random.getrandbits",
             ],
             "Standard pseudo-random generators are not suitable for "
             "security/cryptographic purposes.",
diff --git a/examples/random_module.py b/examples/random_module.py
index 224f251..f0b6d01 100644
--- a/examples/random_module.py
+++ b/examples/random_module.py
@@ -11,6 +11,9 @@ bad = random.choices()
 bad = random.uniform()
 bad = random.triangular()
 bad = random.randbytes()
+bad = random.sample()
+bad = random.randrange()
+bad = random.getrandbits()
 
 good = os.urandom()
 good = random.SystemRandom()


Test patch:
diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py
index 660b65f..eaaa064 100644
--- a/tests/functional/test_functional.py
+++ b/tests/functional/test_functional.py
@@ -365,8 +365,8 @@ class FunctionalTests(testtools.TestCase):
     def test_random_module(self):
         """Test for the `random` module."""
         expect = {
-            "SEVERITY": {"UNDEFINED": 0, "LOW": 9, "MEDIUM": 0, "HIGH": 0},
-            "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 9},
+            "SEVERITY": {"UNDEFINED": 0, "LOW": 12, "MEDIUM": 0, "HIGH": 0},
+            "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 12},
         }
         self.check_example("random_module.py", expect)