python中的一些安全问题
字数 1409 2025-08-20 18:17:53
Python 安全编程指南
输入函数安全
Python2 中的 input() 危险
在 Python2 中,input() 函数会将输入内容作为 Python 代码执行,存在严重安全隐患:
>>> input()
dir() # 执行任意代码
['__builtins__', '__doc__', '__name__', '__package__']
>>> input()
__import__('sys').exit() # 可执行系统命令
解决方案:
- Python2 中使用
raw_input()替代 - Python3 中的
input()已修复此问题,等同于 Python2 的raw_input()
断言语句的误用
assert 语句不应用于安全控制,因为在优化模式下(python -O)会被忽略:
def foo(user):
assert user.is_admin, "user does not have access" # 优化模式下不执行
print("# 敏感代码...")
最佳实践:
- 仅将
assert用于测试目的 - 生产环境使用显式的权限检查
数值比较陷阱
整数重用问题(Python2)
Python2 中整数比较使用 is 运算符不可靠:
>>> 999+1 is 1000 # False
>>> 1+1 is 2 # True
解决方案:
- 始终使用
==进行值比较 is仅用于对象标识比较
浮点数精度问题
浮点数比较可能因精度问题产生意外结果:
>>> 2.2*3.0 == 3.3*2.0 # False
解决方案:
- 使用
decimal模块处理精确计算 - 或转换为整数运算
私有属性机制
Python 的双下划线名称改写机制:
class X:
def __init__(self):
self.__private = 1 # 实际存储为 _X__private
x = X()
hasattr(x, '__private') # False
hasattr(x, '_X__private') # True
风险:
- 通过字符串常量访问时名称不变
- 可被动态添加同名属性覆盖
模块导入安全
模块注入风险
Python 通过 sys.path 搜索模块,攻击者可注入恶意模块:
import sys
sys.path.append('/malicious/path') # 可能导入恶意代码
防护措施:
- 确保搜索路径目录不可被非特权用户写入
- 使用
-E选项忽略PYTHONPATH - 运行前显式设置安全的工作目录
导入时代码执行
导入模块时会执行其中的代码:
# malicious.py
import os
os.system('malicious_command')
防护:
- 仅导入可信来源的模块
- 审核第三方依赖
Monkey Patching 风险
运行时修改对象属性可能导致安全问题:
import builtins
def malicious_open(*args, **kwargs):
if 'w' in kwargs.get('mode', ''):
args = ('/dev/null',) + args[1:]
return original_open(*args, **kwargs)
original_open, builtins.open = builtins.open, malicious_open
其他攻击方式:
- 修改函数的
__code__属性 - 改变对象的
__class__属性
子进程调用安全
Shell 注入风险
使用 shell=True 时未过滤输入会导致命令注入:
from subprocess import call
user_input = '/bin/true; cat /etc/passwd'
call(user_input, shell=True) # 执行额外命令
安全实践:
- 避免使用
shell=True - 使用列表形式传递命令和参数:
call(['/bin/ls', '/safe/dir']) - 必须使用 shell 时,用
shlex.quote()过滤
临时文件安全
不安全创建临时文件的常见错误:
import tempfile
import os
# 不安全方式
tmp = tempfile.mktemp() # 已弃用
open(tmp, 'w')
# 安全方式
with tempfile.NamedTemporaryFile(delete=True) as f:
f.write(b'data')
最佳实践:
- 使用
tempfile.NamedTemporaryFile或tempfile.mkstemp - 避免
tempfile.mktemp - 注意
shutil.move跨文件系统时的降级风险
反序列化安全
Pickle 风险
Pickle 反序列化可执行任意代码:
import pickle
pickle.loads(b"cos\nsystem\n(S'rm /tmp/file'\ntR.") # 执行系统命令
YAML 风险
PyYAML 的 yaml.load 同样危险:
import yaml
yaml.load("""
some_option: !!python/object/apply:subprocess.call
args: [malicious command]
kwds: {shell: true}
""")
安全实践:
- 使用
yaml.safe_load - 避免反序列化不可信数据
- 考虑使用 JSON 等更安全的格式
模板引擎安全
XSS 风险
模板变量未转义可能导致 XSS:
from jinja2 import Environment
template = Environment().from_string('{{ variable }}')
template.render(variable='<script>alert(1)</script>') # 输出原始 HTML
防护措施:
- 启用自动转义:
Environment(autoescape=True) - 显式转义变量:
{{ variable | e }} - 白名单过滤危险 HTML
其他安全实践
-
敏感操作权限检查:
- 文件操作前验证路径
- 数据库操作前验证权限
-
密码处理:
- 使用
hashlib存储密码哈希 - 避免明文存储敏感信息
- 使用
-
HTTPS 验证:
import requests requests.get('https://example.com', verify=True) # 启用证书验证 -
内存安全:
- 及时清理敏感内存
- 使用
secure_delete等工具
-
日志安全:
- 避免记录敏感信息
- 设置适当的日志权限
通过遵循这些安全实践,可以显著降低 Python 应用程序的安全风险。