本文探讨了在使用 Python 3 的扫描器在 Docker 环境中运行,遇到中文 URL 编码错误的问题。尽管切换到了 Python 3,默认编码为 UTF-8,但在与操作系统底层交互时,仍会调用系统默认编码,导致 UTF-8 编码的中文 URL 解码失败。文章分析了该问题在 Mac 和 Docker 环境下的差异性,并提供了两种解决方案:一是在 Dockerfile 中指定系统编码,二是将 URL 编码为 bytes 格式传递给 subprocess,以绕过系统编码转换。
📦 **环境差异导致编码问题**:文章指出,在 Mac 和 Docker 环境下运行相同的 Python 3 代码,可能会遇到不同的编码问题。当扫描器处理包含中文的 URL 时,在 Docker 环境中出现了转码失败的错误,这与 Mac 环境下的表现不一致,凸显了环境配置对编码处理的重要性。
⚙️ **Python 3 编码机制与系统交互**:尽管 Python 3 将默认编码改为 UTF-8,但当使用 `subprocess.Popen` 等与操作系统底层进行交互时,仍会依赖系统的默认编码。当传入的中文 URL 采用 UTF-8 编码,而 Docker 环境的系统默认编码(如 ANSIX_X3.4-1968)与之不匹配时,就会发生解码错误。
💡 **解决方案提供**:文章提供了两种解决此类问题的有效途径。第一种是在编译 Docker 镜像时,通过修改 Dockerfile 来指定系统的默认编码为 UTF-8。第二种方法是,在将中文 URL 传递给 `subprocess` 前,先将其转换为 bytes 格式,从而绕过系统可能发生的编码转换,直接处理原始字节流。
Fr1day 2017-08-29 20:50
~\(≧▽≦)/~ 八哥你走开!

为了方便分布式,扫描器的运行环境用Dockerfile编译的。测试的时候是mac + python3.5.3,本地测试完成上线(docker ubuntu + python3.5.2)后,发现报错(下图为部分报错信息):

似乎是因为URL里有中文,才导致的转码失败。但老夫已经聊发少年狂,从Python2 切换到了 Python3,为何还会有这种错误?!
为了方便测试,把报错的代码单独拉出来,如下:

但在复现漏洞的时候,发现漏洞只能在docker的运行环境里复现,mac + python3.5.3 和 ubuntu + python 3.5.2都不存在问题。
一番搜索之后,找到了问题所在:

在mac下执行同样的命令:

Python 的编码问题一直饱受诟病。虽然在Python3的版本做了一些变动,默认编码形式由 ASCII 改为 utf-8。但在与操作系统底层进行交互(subprocess.Popen)的时候,还是会调用系统的编码。而我们传进去的中文是以 utf-8 进行编码的,在docker运行环境里,系统默认编码为 ANSIX_X3.4-1968,所以导致了解码错误。
解决方案:
1)从dockerfile编译镜像的时候指定系统编码

2)给subprocess传参的时候,先转码为bytes格式(绕过系统的编码转换过程)

参考资料:
https://www.binss.me/blog/solve-problem-of-python3-raise-unicodeencodeerror-when-print-utf8-string/
https://askubuntu.com/questions/581458/how-to-configure-locales-to-unicode-in-a-docker-ubuntu-14-04-container
http://www.jianshu.com/p/5682a0e0a9ba
阅读原文
跳转微信打开