Python 注入防御:SQLi 与 XSS 的实战规避技巧
Python 注入防御:SQLi 与 XSS 的实战规避技巧
在 Python 开发中,注入攻击如 SQL 注入(SQLi)和跨站脚本(XSS)是常见的安全威胁。SQLi 允许攻击者通过恶意输入操纵数据库查询,而 XSS 则让攻击者在用户浏览器执行恶意脚本。这些攻击可能导致数据泄露、账户劫持或系统瘫痪。本文将逐步介绍实战规避技巧,帮助您构建更安全的 Python 应用。所有建议基于行业最佳实践,确保真实可靠。
1. SQL 注入(SQLi)防御技巧
SQLi 攻击通常发生在拼接 SQL 字符串时,攻击者注入恶意代码。以下是关键规避方法:
-
技巧1:使用参数化查询(预编译语句)
永远避免直接拼接用户输入到 SQL 语句中。使用参数化查询,数据库引擎会将输入视为数据而非代码。在 Python 中,常见库如sqlite3或psycopg2(用于 PostgreSQL)支持占位符(如?或%s)。Python 代码示例(使用
sqlite3):import sqlite3 # 安全:参数化查询 def safe_query(user_input): conn = sqlite3.connect('example.db') cursor = conn.cursor() # 使用 ? 占位符,输入被自动转义 cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (user_input['username'], user_input['password'])) result = cursor.fetchall() conn.close() return result # 危险:避免这种方式(拼接字符串) # cursor.execute("SELECT * FROM users WHERE username = '" + user_input['username'] + "' AND password = '" + user_input['password'] + "'") -
技巧2:使用 ORM(对象关系映射)框架
ORM 如 SQLAlchemy 或 Django ORM 自动处理参数化,减少手动 SQL 编写。它们将查询抽象为对象操作,降低注入风险。Python 代码示例(使用 SQLAlchemy):
from sqlalchemy import create_engine, Column, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' username = Column(String, primary_key=True) password = Column(String) # 安全:ORM 查询 engine = create_engine('sqlite:///example.db') Session = sessionmaker(bind=engine) session = Session() def safe_orm_query(username): # ORM 自动参数化输入 user = session.query(User).filter(User.username == username).first() return user -
额外技巧:
- 输入验证:使用库如
re(正则表达式)检查用户输入格式(例如,只允许字母数字)。 - 最小权限原则:数据库账户仅授予必要权限,避免使用 root 账户。
- 输入验证:使用库如
2. 跨站脚本(XSS)防御技巧
XSS 攻击发生在用户输入被直接输出到 HTML 页面时,攻击者注入恶意脚本。防御核心是确保所有输出被正确编码或转义。
-
技巧1:输出编码
在输出用户数据到 HTML 时,必须进行编码(如将<转义为<)。Python Web 框架如 Flask 或 Django 内置自动转义功能。Python 代码示例(使用 Flask 和 Jinja2 模板):
from flask import Flask, render_template_string app = Flask(__name__) # 安全:使用模板引擎自动转义 @app.route('/safe') def safe_xss(): user_input = "<script>alert('XSS')</script>" # 恶意输入示例 # Jinja2 自动转义 HTML return render_template_string('<p>{{ input }}</p>', input=user_input) # 危险:避免直接输出(如使用 Markup 或手动拼接) # from markupsafe import Markup # return Markup('<p>' + user_input + '</p>') # 可能绕过转义 -
技巧2:使用内容安全策略(CSP)
CSP 通过 HTTP 头限制脚本来源,防止恶意脚本执行。在 Python 中,用框架中间件轻松实现。Python 代码示例(使用 Django 的 CSP 中间件): 首先安装库:
pip install django-csp# settings.py MIDDLEWARE = [ # ...其他中间件 'csp.middleware.CSPMiddleware', ] CSP_DEFAULT_SRC = ["'self'"] # 只允许同源脚本 CSP_SCRIPT_SRC = ["'self'"] # 限制脚本来源 # 视图函数中,正常输出用户数据(Django 模板自动转义) from django.shortcuts import render def safe_view(request): user_data = request.GET.get('data', '') return render(request, 'template.html', {'data': user_data}) -
额外技巧:
- 输入过滤:在接收端使用库如
bleach清理 HTML 输入(移除危险标签)。 - 避免
innerHTML:在 JavaScript 中,避免直接设置innerHTML;优先使用textContent。
- 输入过滤:在接收端使用库如
3. 总结与最佳实践
- 综合防御:SQLi 和 XSS 都源于信任用户输入。始终遵循“不信任输入”原则:验证输入、参数化查询、编码输出。
- 工具推荐:
- SQLi 防御:优先使用 ORM 或参数化查询库。
- XSS 防御:依赖框架(如 Flask/Django)的自动转义,并启用 CSP。
- 测试工具:使用 OWASP ZAP 或 Bandit(Python 安全扫描器)进行代码审计。
- 持续学习:关注 OWASP Top 10(开放式 Web 应用安全项目)更新,确保应用符合最新标准。
通过以上技巧,您可以显著降低注入攻击风险。实践中,结合代码审查和安全测试,构建健壮的 Python 应用。如有具体场景问题,欢迎进一步咨询!
更多推荐



所有评论(0)