惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
H
Heimdal Security Blog
K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Schneier on Security
G
GRAHAM CLULEY
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
C
Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Jina AI
Jina AI
P
Proofpoint News Feed
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
S
Security Affairs
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
N
News | PayPal Newsroom
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU

张戈博客

FastTTS:支持私有化部署和源阅读无缝对接的语音合成服务张戈博客 | 张戈博客 gRPC开发过程中遇到的问题记录张戈博客 | 张戈博客 Flyer:基于FastAPI的轻量级API开发框架张戈博客 | 张戈博客 APISIX高级路由之301/302跳转配置张戈博客 | 张戈博客 解决paramiko使用invoke_shell交互式命令超时问题张戈博客 | 张戈博客 分享一个APISIX网关返回502的典型案例张戈博客 | 张戈博客 解决百度搜索出现安全中心提醒张戈博客 | 张戈博客 APISIX运维优化之解决长尾请求(耗时抖动)问题张戈博客 | 张戈博客 APISIX运维优化之配置文件自动化生成方案张戈博客 | 张戈博客
SQLAlchemy因密码含有@符号连接MySQL失败张戈博客 | 张戈博客
张戈博客 · 2022-08-03 · via 张戈博客

Jager · 8月3日 · 2022年 3191次已读

最近新来的实习生小伙子在重构一个我入职时开发的老系统,这个系统之前用的是 Python twisted 框架开发的,这次重构希望可以换到 FastAPI,也就是我上一篇文章分享的Flyer 开发框架

小伙子很给力,花了几天自学了下 FastAPI 和 Flyer 就开始开发了,结果用 Flyer 框架的时候,连接 MySQL 报错如下:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'xxxx@x.x.x.x' ([Errno -2] Name or service not known

这个报错他一看也就明白,是因为密码里面有一个@符号,导致@符号之后的内容被识别为数据库的连接主机了,小伙子很快就基于 urllib.parse.quote_plus 对密码转义一下就解决了,特意跟我说了下这个问题。

因为我之前有个基于 Flyer 框架的项目也复用了这个数据库用的是同样的账号和密码,没出现过这个问题,所以很奇怪,比较笃定的说肯定是 sqlalchemy 版本问题。

结果一看,他的开发环境的 sqlalchemy 版本是 1.4.39 而我的开发环境还是 1.3.19,让他回退版本测试了下,果然就修复了,看来是 1.3.19 后面的版本引入的‘特性’。

出于对开源社区的反哺,我到 sqlalchemy 的社区提了一个 issue:

can not connect to mysql when has special chars '@' in passwords · Issue #8327 · sqlalchemy/sqlalchemy (github.com)

结果社区大佬响应挺快,说这个是预期的,需要我们将密码做一下 url 转义。

好吧,这个 url 转义肯定是可以做的,也算合理,只是我比较疑惑的是主机里面并没有@符号啊,为啥密码里面不能用@符号呢?特意翻看了下版本发布记录,最终发现这个特性的修改是在 1.4.16 版本:

accommodate for @ in database portion even if user:pass is present · Issue #6482 · sqlalchemy/sqlalchemy (github.com)

[engine] [bug] Fixed issue where an @ sign in the database portion of a URL would not
be interpreted correctly if the URL also had a username:password section.

为了修复 db 实例名称里面可能会有@符号,导致@符号之前的字符都归为密码,说白了和这篇文章说的问题差不多,就是参数提取越界的问题,只是我没想到 db 实例里面还可能会有@符号...

好奇看了下两个版本的差异:

https://github.com/sqlalchemy/sqlalchemy/blob/8a9a2e384db2d4b9fedf8d3b62dbf8937b7ba2b8/lib/sqlalchemy/engine/url.py#L722

https://github.com/sqlalchemy/sqlalchemy/blob/627135e4239c5f1a073b7c21e4958087c4b0e0a0/lib/sqlalchemy/engine/url.py#L705

# 1.4.15
(?::(?P<password>.*))
# 1.4.16
(?::(?P<password>[^@]*))

发现其实就是改了提取密码这个正则表达式,将@符号从密码里面排除了,即密码里面不能有@符号,如果有请自行转义。

从这个小 case 我们可以总结两点经验:

1、使用 url 形式来连接各类服务时(MySQL、pgSQL、MongoDB 等),密码要做好 url 转义以提高程序健壮性;

2、Python 环境中安装和使用开源插件,最好指定实际测试过的版本号,且不要随意修改,防止各种 break 特性的引入。