19

我在 Python 中使用这个语句

 jsonreq = json.dumps({'jsonrpc': '2.0', 'id': 'qwer', 'method': 'aria2.pauseAll'})
 jsonreq = jsonreq.encode('ascii')
 c = urllib.request.urlopen('http://localhost:6800/jsonrpc', jsonreq)

在此我在执行代码质量测试时收到此警告/错误

审核 url 为允许的方案打开。允许使用“file:”或自定义方案通常是出乎意料的。

4

3 回答 3

20

因为我偶然发现了这个问题并且接受的答案对我不起作用,所以我自己研究了这个:

为什么 urllib 存在安全风险

urllib 不仅打开 http:// 或 https:// URL,还打开 ftp:// 和 file://。这样就可以在执行机器上打开本地文件,如果要打开的 URL 可以被外部用户操作,这可能会带来安全风险。

如何解决这个问题

您自己负责在使用 urllib 打开 URL 之前对其进行验证。例如

if url.lower().startswith('http'):
  req = urllib.request.Request(url)
else:
  raise ValueError from None

with urllib.request.urlopen(req) as resp:
  [...]

如何解决这个问题,以便 linter(例如bandit)不再抱怨

至少 bandit 有一个简单的函数调用黑名单。只要你使用 urllib,linter 就会发出警告。即使您确实验证了您的输入,如上所示。(或者甚至使用硬编码的 URL)。

在该行添加#nosec注释以抑制来自 bandit 的警告,或查找 linter/code-checker 的抑制关键字。最好的做法是还添加额外的评论,说明为什么您认为这在您的情况下不值得警告。

于 2018-10-29T07:17:22.120 回答
6

我认为这就是你需要的

import urllib.request

req = urllib.request.Request('http://www.example.com')
with urllib.request.urlopen(req) as response:
    the_page = response.read()
于 2018-02-14T06:21:10.927 回答
3

对于无法通过上述答案解决的人。您可以改用requestslibrary,它不在 bandit 的黑名单中。

https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b310-urllib-urlopen

import requests

url = 'http://www.example.com'
the_page = requests.get(url)

print(the_page.json()) # if the response is json
print(the_page.text) # if the response is some text

于 2020-08-14T11:01:27.920 回答