代码审计:python代码审计汇总(持续更新中)
字数 1588 2025-08-20 18:18:23

Python代码审计与安全开发指南

1. 命令注入漏洞

危险函数列表

  • os.system()
  • os.popen()
  • subprocess.Popen()
  • platform.popen()
  • commands模块方法
  • pty.spawn()
  • importlib.import_module()

典型漏洞示例

def myserve(request, fullname):
    os.system("sudo rm -f %s" % fullname)  # 用户可控的fullname可导致命令注入

防御措施

  1. 避免使用shell=True参数
  2. 使用转义函数:
    • Python 2.x: pipes.quote()
    • Python 3.3+: shlex.quote()

2. 代码注入漏洞

危险函数

  • eval()
  • exec()
  • execfile()
  • compile()
  • timeit.timeit()
  • timeit.repeat()

漏洞示例

def eval_test(request, login):
    login = eval(login)  # 用户可控的login可导致代码执行

防御措施

  1. 使用ast.literal_eval()替代eval()
  2. 限制可执行代码范围
  3. 使用类型转换函数如int(), float()

3. 不安全的反序列化

危险模块

  • marshal
  • PyYAMLyaml.load()
  • pickle/cPickle
  • shelve
  • PIL
  • Unzip

漏洞示例

import pickle
pickle.loads("cos\nsystem\n(S'uname -a'\ntR.")  # 可执行任意命令

防御措施

  1. 使用yaml.safe_load()替代yaml.load()
  2. 避免反序列化不可信数据
  3. 使用JSON等更安全的序列化格式

4. SQL注入

错误用法

def getUsers(user_id):
    sql = 'select * from auth_user where id =%s' % user_id
    res = cur.execute(sql)  # 直接拼接SQL语句

正确用法

args = (id, type)
cur.execute('select id,name from user_table where id = %s and name = %s', args)

防御措施

  1. 使用参数化查询
  2. 使用ORM框架
  3. 避免直接拼接SQL语句

5. 任意文件下载/操作漏洞

危险函数

  • file()
  • file.save()
  • open()
  • codecs.open()

漏洞示例

def export_task(request, filename):
    return HttpResponse(fullname)  # 未验证的文件路径可导致任意文件下载

防御措施

  1. 验证文件路径
  2. 限制访问目录
  3. 检查文件类型

6. XXE漏洞

危险模块

  • xml.dom.*
  • xml.etree.ElementTree
  • xml.sax.*

防御措施

  1. 禁用外部实体解析
  2. 使用更安全的XML解析器
  3. 验证XML输入

7. SSRF漏洞

危险函数

  • requests.get()
  • urllib.urlopen()
  • urllib2.urlopen()

漏洞示例

url = request.GET['url']
handle = urllib.urlopen(url)  # 用户可控的URL可导致SSRF

防御措施

  1. 验证URL
  2. 限制访问内网
  3. 使用白名单机制

8. XSS漏洞

漏洞示例

return HttpResponse('hello %s' % (name))  # 未转义的输出可导致XSS

安全写法

return render_to_response('hello.html', {'name': name})

防御措施

  1. 对所有输出进行HTML转义
  2. 使用模板引擎的自动转义功能
  3. 设置Content Security Policy

9. 直接重定向漏洞

漏洞示例

strDest = request.field("dest")
redirect(strDest)  # 未验证的重定向目标

防御措施

  1. 验证重定向URL
  2. 使用白名单机制
  3. 避免使用用户提供的重定向目标

10. 日志伪造漏洞

关注点

  • logging()函数
  • LOGGER关键字
  • 敏感信息输出

防御措施

  1. 避免记录敏感信息
  2. 对日志内容进行过滤
  3. 使用安全的日志框架

11. 模板注入(SSTI)

危险函数

  • render_template_string

漏洞示例

@app.route('/')
def index():
    name = request.args.get('name', 'Guest')
    return render_template_string('Hello, {{ name }}!', name=name)

攻击示例

http://your-app.com/?name={{ config.__class__.__init__.__globals__['os'].popen('whoami').read() }}

防御策略

  1. 使用render_template替代render_template_string
  2. 验证和过滤输入
  3. 使用ORM框架
  4. 保持框架和库更新

12. 不安全的随机数

不安全用法

random.randint(0, 100)  # 不适用于安全加密用途

安全用法

  • Linux/Unix: 使用/dev/random
  • Windows: 使用random.SystemRandom

13. 格式化字符串漏洞

漏洞示例

"My name is %s" % ('jayway', )
"My name is {}".format('jayway')
"My name is %(name)%" % {'name': 'jayway'}

防御措施

  1. 避免使用用户控制的格式化字符串
  2. 对输出进行转义

14. 代码审计工具 - Bandit

安装与使用

pip install bandit
bandit -r /path/to/code/ -f html -o report.html

参数说明

  • -r: 扫描的源码目录
  • -f: 报告格式(html, csv, json等)
  • -o: 输出文件名

总结

Python代码安全审计需要关注多个方面,从命令注入到模板注入,每种漏洞都有其特定的防御策略。开发者应当:

  1. 了解各种危险函数和模块
  2. 遵循安全编码实践
  3. 使用安全工具进行代码审计
  4. 保持框架和库的更新
  5. 对所有用户输入进行验证和过滤

通过全面的安全意识和实践,可以显著降低Python应用程序的安全风险。

Python代码审计与安全开发指南 1. 命令注入漏洞 危险函数列表 os.system() os.popen() subprocess.Popen() platform.popen() commands 模块方法 pty.spawn() importlib.import_module() 典型漏洞示例 防御措施 避免使用 shell=True 参数 使用转义函数: Python 2.x: pipes.quote() Python 3.3+: shlex.quote() 2. 代码注入漏洞 危险函数 eval() exec() execfile() compile() timeit.timeit() timeit.repeat() 漏洞示例 防御措施 使用 ast.literal_eval() 替代 eval() 限制可执行代码范围 使用类型转换函数如 int() , float() 3. 不安全的反序列化 危险模块 marshal PyYAML 的 yaml.load() pickle / cPickle shelve PIL Unzip 漏洞示例 防御措施 使用 yaml.safe_load() 替代 yaml.load() 避免反序列化不可信数据 使用JSON等更安全的序列化格式 4. SQL注入 错误用法 正确用法 防御措施 使用参数化查询 使用ORM框架 避免直接拼接SQL语句 5. 任意文件下载/操作漏洞 危险函数 file() file.save() open() codecs.open() 漏洞示例 防御措施 验证文件路径 限制访问目录 检查文件类型 6. XXE漏洞 危险模块 xml.dom.* xml.etree.ElementTree xml.sax.* 防御措施 禁用外部实体解析 使用更安全的XML解析器 验证XML输入 7. SSRF漏洞 危险函数 requests.get() urllib.urlopen() urllib2.urlopen() 漏洞示例 防御措施 验证URL 限制访问内网 使用白名单机制 8. XSS漏洞 漏洞示例 安全写法 防御措施 对所有输出进行HTML转义 使用模板引擎的自动转义功能 设置Content Security Policy 9. 直接重定向漏洞 漏洞示例 防御措施 验证重定向URL 使用白名单机制 避免使用用户提供的重定向目标 10. 日志伪造漏洞 关注点 logging() 函数 LOGGER 关键字 敏感信息输出 防御措施 避免记录敏感信息 对日志内容进行过滤 使用安全的日志框架 11. 模板注入(SSTI) 危险函数 render_template_string 漏洞示例 攻击示例 防御策略 使用 render_template 替代 render_template_string 验证和过滤输入 使用ORM框架 保持框架和库更新 12. 不安全的随机数 不安全用法 安全用法 Linux/Unix: 使用 /dev/random Windows: 使用 random.SystemRandom 13. 格式化字符串漏洞 漏洞示例 防御措施 避免使用用户控制的格式化字符串 对输出进行转义 14. 代码审计工具 - Bandit 安装与使用 参数说明 -r : 扫描的源码目录 -f : 报告格式(html, csv, json等) -o : 输出文件名 总结 Python代码安全审计需要关注多个方面,从命令注入到模板注入,每种漏洞都有其特定的防御策略。开发者应当: 了解各种危险函数和模块 遵循安全编码实践 使用安全工具进行代码审计 保持框架和库的更新 对所有用户输入进行验证和过滤 通过全面的安全意识和实践,可以显著降低Python应用程序的安全风险。