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.NamedTemporaryFiletempfile.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

其他安全实践

  1. 敏感操作权限检查

    • 文件操作前验证路径
    • 数据库操作前验证权限
  2. 密码处理

    • 使用 hashlib 存储密码哈希
    • 避免明文存储敏感信息
  3. HTTPS 验证

    import requests
    requests.get('https://example.com', verify=True)  # 启用证书验证
    
  4. 内存安全

    • 及时清理敏感内存
    • 使用 secure_delete 等工具
  5. 日志安全

    • 避免记录敏感信息
    • 设置适当的日志权限

通过遵循这些安全实践,可以显著降低 Python 应用程序的安全风险。

Python 安全编程指南 输入函数安全 Python2 中的 input() 危险 在 Python2 中, input() 函数会将输入内容作为 Python 代码执行,存在严重安全隐患: 解决方案 : Python2 中使用 raw_input() 替代 Python3 中的 input() 已修复此问题,等同于 Python2 的 raw_input() 断言语句的误用 assert 语句不应用于安全控制,因为在优化模式下( python -O )会被忽略: 最佳实践 : 仅将 assert 用于测试目的 生产环境使用显式的权限检查 数值比较陷阱 整数重用问题(Python2) Python2 中整数比较使用 is 运算符不可靠: 解决方案 : 始终使用 == 进行值比较 is 仅用于对象标识比较 浮点数精度问题 浮点数比较可能因精度问题产生意外结果: 解决方案 : 使用 decimal 模块处理精确计算 或转换为整数运算 私有属性机制 Python 的双下划线名称改写机制: 风险 : 通过字符串常量访问时名称不变 可被动态添加同名属性覆盖 模块导入安全 模块注入风险 Python 通过 sys.path 搜索模块,攻击者可注入恶意模块: 防护措施 : 确保搜索路径目录不可被非特权用户写入 使用 -E 选项忽略 PYTHONPATH 运行前显式设置安全的工作目录 导入时代码执行 导入模块时会执行其中的代码: 防护 : 仅导入可信来源的模块 审核第三方依赖 Monkey Patching 风险 运行时修改对象属性可能导致安全问题: 其他攻击方式 : 修改函数的 __code__ 属性 改变对象的 __class__ 属性 子进程调用安全 Shell 注入风险 使用 shell=True 时未过滤输入会导致命令注入: 安全实践 : 避免使用 shell=True 使用列表形式传递命令和参数: 必须使用 shell 时,用 shlex.quote() 过滤 临时文件安全 不安全创建临时文件的常见错误: 最佳实践 : 使用 tempfile.NamedTemporaryFile 或 tempfile.mkstemp 避免 tempfile.mktemp 注意 shutil.move 跨文件系统时的降级风险 反序列化安全 Pickle 风险 Pickle 反序列化可执行任意代码: YAML 风险 PyYAML 的 yaml.load 同样危险: 安全实践 : 使用 yaml.safe_load 避免反序列化不可信数据 考虑使用 JSON 等更安全的格式 模板引擎安全 XSS 风险 模板变量未转义可能导致 XSS: 防护措施 : 启用自动转义: 显式转义变量: {{ variable | e }} 白名单过滤危险 HTML 其他安全实践 敏感操作权限检查 : 文件操作前验证路径 数据库操作前验证权限 密码处理 : 使用 hashlib 存储密码哈希 避免明文存储敏感信息 HTTPS 验证 : 内存安全 : 及时清理敏感内存 使用 secure_delete 等工具 日志安全 : 避免记录敏感信息 设置适当的日志权限 通过遵循这些安全实践,可以显著降低 Python 应用程序的安全风险。