python - 在 python 的请求库中禁用 SSL 证书验证是否安全?

标签 python python-requests pyopenssl

我很清楚,一般来说,事实并非如此。但在我的特殊情况下,我正在编写一个简单的 python web-scraper,它将每小时作为 cron 作业运行,我想确保通过设置 来忽略验证 SSL 证书不会有风险将 验证为 False

附言 我设置禁用此功能的原因是因为在尝试发出请求时 response = requests.get('url') 它引发了 SSLError 而我不看看如何处理。

编辑:

好的,在 sigmavirus24 和其他人的帮助下,我终于设法解决了这个问题。这是我如何做到的解释:

  • 我在 https://ssllabs.com/ 进行了测试根据 SSLLabs 提供的报告,由于“不完整的证书链”问题,会引发 SSL 错误(有关证书验证如何工作的更多详细信息,请阅读 sigmaviruses24 的回答)。

在我的例子中,其中一个中间人不见了。

  • 我使用谷歌搜索了它的指纹并以 .pem 格式下载了它。
  • 然后我使用“certifi”(它是一个用于提供 Mozilla 的 CA Bundle 的 python 包。如果您没有,可以使用 sudo pip install certifi 安装它)来查找根证书(再次通过其指纹)。这可以按如下方式完成:

    $ ipython
    In [1]: import certifi
    In [2]: certifi.where()
    Out[2]: /usr/lib/python3.6/site-packages/certifi/cacert.pem
    In [3]: quit
    
    $ emacs -nw /usr/lib/python3.6/site-packages/certifi/cacert.pem
    

或者在 bash 中,您可以发出 $ emacs -nw $(python -m certifi) 来打开 cacert.pem 文件。

  • 将两个证书合并到一个文件中,然后将其路径提供给验证参数。

另一种(更简单但并非总是可行)的方法是从 SSLLabs 下载整个链,就在“附加证书(如果提供)”部分前面有“下载服务器链”按钮。单击它,将链保存在.pem 文件中,并在调用请求的 get 方法时,将文件路径提供给验证参数。

最佳答案

这里的正确答案是“视情况而定”。

您给我们提供的信息很少,所以我将做出一些假设并在下面列出(如果其中任何一个不匹配,那么您应该重新考虑您的选择):

  1. 您在 CRON 作业中不断连接到同一个网站
  2. 您非常了解该网站并且确定与证书相关的错误是良性的
  3. 您没有向网站发送敏感数据以抓取它(例如登录名和用户名)

如果是这种情况(我猜是这样),那么它通常应该是无害的。也就是说,它是否“安全”取决于您在两台计算机通过互联网相互交谈的上下文中对该词的定义。

正如其他人所说,Requests 不会尝试呈现 HTML、解析 XML 或执行 JavaScript。因为它只是在检索您的数据,所以您面临的最大风险是没有收到可以验证的数据,这些数据来自您认为它来自的服务器。但是,如果您将请求与执行上述操作的东西结合使用,则中间的恶意人员可能会利用无数潜在攻击来对付您。

还有一些选项意味着您不必放弃验证。例如,如果服务器使用自签名证书,您可以获取 PEM 格式的证书,将其保存到文件中,并将该文件的路径提供给 verify 参数。然后请求将能够为您验证证书。

所以,正如我所说,这取决于情况。


根据 Albert 的回复更新

所以似乎正在发生的事情是,有问题的网站只发送有效的叶证书。该网站依赖于当前工作方式如下的浏览器行为:

浏览器连接到网站并注意到该网站没有发送完整的证书链。然后它去检索中介,验证它们,并完成连接。但是,请求使用 OpenSSL 进行验证,而 OpenSSL 不包含任何此类行为。由于验证逻辑几乎完全在 OpenSSL 中,因此在这种情况下 Requests 无法模拟浏览器。

此外,安全工具(例如 SSLLabs)已开始根据网站的安全排名计算此配置。越来越多的人认为网站应该发送整个链条。如果您遇到一个没有的网站,联系他们并告知他们这是最好的前进方向。

如果网站拒绝更新他们的证书链,那么 Requests 的用户可以检索 PEM 编码的中间证书并将它们粘贴到 .pem 文件中,然后他们将其提供给 verify 参数。 Requests 目前仅在其信任库中包含 Root 证书(就像每个浏览器一样)。它永远不会发送中间证书,因为中间证书太多了。因此,将中介机构与根证书捆绑在一起将使您能够验证网站的证书。 OpenSSL 将有一个 PEM 编码文件,其中包含链中的每个链接,并且能够验证直至根证书。

关于python - 在 python 的请求库中禁用 SSL 证书验证是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41740361/

相关文章:

Python SSLError,sslv3 警报握手失败,用于 wallhaven.cc

Python 多处理负载均衡器

python - 构建Python : how to disable Py_LIMITED_API?

python - 在 IPython Notebook 中自动运行 %matplotlib inline

python - Pandas - 应用于 lambda 函数的列中位数

python - 将curl转换为python : usernames and passwords

python - 如何从 requests.exceptions.RequestException 获取异常字符串

Python:Beautifulsoup 返回 None 或 [ ]

python - 在 Windows 的 virtualenv 中安装 scrapy/pyopenssl

python - 属性错误 : 'Context' object has no attribute 'wrap_socket'