hashlib默认不推荐md5()和sha1()因抗碰撞能力失效,密码哈希须用bcrypt/scrypt/argon2,非密码校验可用sha256()/sha3_256();secrets比random安全因读取系统熵源,适合密钥/Token生成;忽略ssl证书验证易致中间人攻击;subprocess启用shell=true且未过滤用户输入将引发命令注入。

为什么 hashlib 默认不推荐用 md5() 和 sha1()
因为它们已不具备抗碰撞能力,不能用于密码哈希或完整性校验等安全场景。比如用 hashlib.md5(b"password").hexdigest() 存用户密码,等于裸奔。
实操建议:
- 密码哈希必须用
bcrypt、scrypt或argon2(第三方库),标准库中仅hashlib.pbkdf2_hmac()可勉强用,但需足够迭代轮数(如iterations=600_000) -
sha256()和sha3_256()可用于非密码类校验(如文件摘要),但别混用:SHA-2 与 SHA-3 算法结构不同,互不兼容 - 注意 python 3.9+ 才默认启用
sha3_*系列;旧版本需确认 OpenSSL 是否支持
secrets 比 random 强在哪?什么情况下必须换
random 是伪随机,可被预测;secrets 读取操作系统熵源(如 /dev/urandom),适合生成密钥、token、验证码等。
常见错误现象:用 random.choice(String.ascii_letters) 拼 session ID,结果被批量猜解。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 生成密码重置 token:用
secrets.token_urlsafe(32),不是random.randint() - 选随机元素时,
secrets.choice()替代random.choice();生成随机字节用secrets.token_bytes(16) - 不要试图“增强”
random——比如加时间戳或 hash,这毫无意义,反而可能降低熵
用 ssl 做 https 请求时,忽略证书验证的代价
写 requests.get(url, verify=False) 或手动设 context.check_hostname = False,会绕过 TLS 证书链校验,中间人攻击立刻生效。
使用场景里唯一合理忽略证书的是本地开发连自签名测试服务,且必须限于 localhost 或明确可控网络。
实操建议:
- 生产环境永远保持
verify=True(requests 默认就是),不要全局设urllib3.disable_warnings() - 内网服务需自签证书时,把 CA 根证书路径传给
verify="/path/to/ca-bundle.crt",而不是关验证 - 检查证书是否过期、域名是否匹配,靠的是系统或 Python 自带的证书包(
certifi),定期更新它比手写验证逻辑更可靠
subprocess 调外部命令时,shell=True 是怎么埋雷的
shell=True 会让字符串经系统 shell 解析,一旦输入含 ;、$()、` 或未转义空格,就可能执行任意命令。比如用户提交的文件名是 "photo.jpg; rm -rf /",后果直接失控。
实操建议:
- 永远优先用列表形式调用:
subprocess.run(["convert", "-resize", "800x600", input_path, output_path]) - 真要拼接命令,用
shlex.quote()包裹每个参数,而不是自己 replace 或 split - 避免
os.system()和os.popen()—— 它们隐式启用 shell,且无超时、无 stderr 捕获能力
真正难的不是记住哪些函数危险,而是每次拼接命令前,下意识问一句:“这个变量有没有可能来自用户输入?”——没问过,基本就踩进去了。