Skip to content

Commit

Permalink
No need to check httpx client without timeout defined
Browse files Browse the repository at this point in the history
Unlike python-requests, the httpx client has a default
timeout of 5 seconds on its class and functions. As such,
there is no need for Bandit to check for an undefined
timeout. However, explicitly setting the timeout to None
is still a potential problem as that would create a
situtation where the client would block forever.

Fixes: PyCQA#1175

Signed-off-by: Eric Brown <[email protected]>
  • Loading branch information
ericwb committed Sep 27, 2024
1 parent 36fd650 commit c5f25c8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
26 changes: 15 additions & 11 deletions bandit/plugins/request_without_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@
More Info: https://bandit.readthedocs.io/en/latest/plugins/b113_request_without_timeout.html
Location: examples/requests-missing-timeout.py:3:0
2
3 requests.get('https://gmail.com')
4 requests.get('https://gmail.com', timeout=None)
3 requests.get('https://gmail.com')
4 requests.get('https://gmail.com', timeout=None)
--------------------------------------------------
>> Issue: [B113:request_without_timeout] Call to requests with timeout set to None
Severity: Medium Confidence: Low
CWE: CWE-400 (https://cwe.mitre.org/data/definitions/400.html)
More Info: https://bandit.readthedocs.io/en/latest/plugins/b113_request_without_timeout.html
Location: examples/requests-missing-timeout.py:4:0
3 requests.get('https://gmail.com')
4 requests.get('https://gmail.com', timeout=None)
5 requests.get('https://gmail.com', timeout=5)
3 requests.get('https://gmail.com')
4 requests.get('https://gmail.com', timeout=None)
5 requests.get('https://gmail.com', timeout=5)
.. seealso::
Expand All @@ -59,12 +59,7 @@ def request_without_timeout(context):
HTTPX_ATTRS = {"request", "stream", "Client", "AsyncClient"} | HTTP_VERBS
qualname = context.call_function_name_qual.split(".")[0]

if (
qualname == "requests"
and context.call_function_name in HTTP_VERBS
or qualname == "httpx"
and context.call_function_name in HTTPX_ATTRS
):
if qualname == "requests" and context.call_function_name in HTTP_VERBS:
# check for missing timeout
if context.check_call_arg_value("timeout") is None:
return bandit.Issue(
Expand All @@ -81,3 +76,12 @@ def request_without_timeout(context):
cwe=issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION,
text=f"Call to {qualname} with timeout set to None",
)
if qualname == "httpx" and context.call_function_name in HTTPX_ATTRS:
# check for timeout=None
if context.check_call_arg_value("timeout", "None"):
return bandit.Issue(
severity=bandit.MEDIUM,
confidence=bandit.LOW,
cwe=issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION,
text=f"Call to {qualname} with timeout set to None",
)
4 changes: 2 additions & 2 deletions tests/functional/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,8 @@ def test_requests_ssl_verify_disabled(self):
def test_requests_without_timeout(self):
"""Test for the `requests` library missing timeouts."""
expect = {
"SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 36, "HIGH": 0},
"CONFIDENCE": {"UNDEFINED": 0, "LOW": 36, "MEDIUM": 0, "HIGH": 0},
"SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 25, "HIGH": 0},
"CONFIDENCE": {"UNDEFINED": 0, "LOW": 25, "MEDIUM": 0, "HIGH": 0},
}
self.check_example("requests-missing-timeout.py", expect)

Expand Down

0 comments on commit c5f25c8

Please sign in to comment.