怎样在FastAPI中结合SQLAlchemy安全防御SQL注入?

老婷姑娘_4740

老婷姑娘_4740

2026-10-22

359人浏览

原创

sqlalchemy 默认防sql注入,因所有查询接口强制参数化绑定;危险在于字符串拼接,尤其动态字段名、表名、排序方向等结构信息须白名单校验。

怎样在fastapi中结合sqlalchemy安全防御sql注入?

SQLAlchemy 本身就能防 SQL 注入,前提是别绕过它去拼接 SQL 字符串。只要你用 session.execute() + 参数化查询,或 ORM 的 filter() / where() 方法传参,就基本安全。真正危险的是手动拼接 str.format()、% 或 f-string 构造查询语句。

为什么 ORM 查询默认安全?

SQLAlchemy(包括异步版)所有公开的查询接口都强制使用参数化绑定。比如:

await session.execute(select(User).where(User.email == email))

这里的 email 不会进 SQL 字符串,而是作为独立参数交给数据库驱动(如 asyncpg 或 aiomysql)处理,底层走的是预编译语句(prepared statement)路径。

常见错误现象:sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "admin@example.com" —— 这往往说明你用了字符串拼接,而不是参数传递。

  • ORM 层的 filter()、where()、order_by() 等方法只接受表达式对象,不接受原始字符串
  • 原生 SQL 查询必须用 text() 包裹,并显式传参:session.execute(text("SELECT * FROM user WHERE email = :email"), {"email": email})
  • 绝对不要写:text(f"SELECT * FROM user WHERE email = '{email}'") 或 text("SELECT * FROM user WHERE email = '" + email + "'")

哪些地方容易漏掉防护?

最常被忽略的是动态字段名、表名、排序方向这类“元信息”。SQLAlchemy 不允许把这些当参数传,因为它们不属于值(value),而是结构(structure)。

例如想根据前端传来的 sort_field 和 sort_dir 动态排序:

FastAPI Flask Proxy
FastAPI Flask Proxy

FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。

下载
query = select(User).order_by(text(f"{sort_field} {sort_dir}"))

这就开了后门。攻击者传 sort_field=id; DROP TABLE user; -- 就可能触发注入。

  • 解决方案:白名单校验字段和方向:if sort_field not in ["id", "email", "created_at"]: 直接 raise HTTPException(400)
  • 排序方向只允许 "asc" 或 "desc",其他一律拒绝
  • 表名、字段名永远不能来自用户输入;必须硬编码或从预定义映射中取

异步模式下有没有额外风险?

没有本质区别,但要注意会话生命周期管理不当可能间接放大问题。比如在依赖中未正确 await 关闭 AsyncSession,导致连接复用混乱,掩盖了本该报错的非法查询。

典型错误写法:

@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
    result = await db.execute("SELECT * FROM user WHERE email = '" + email + "'")  # ❌ 拼接
    return result.scalars().all()

这段代码即使用了 AsyncSession,也完全失去防护能力。

  • 务必确认 get_db 依赖返回的是 AsyncSession 实例,且你在 execute() 前没做任何字符串拼接
  • 异步驱动(如 asyncpg)对参数绑定的要求更严格,错误拼接更容易直接报错,反而暴露问题
  • 生产环境建议开启 echo=True(仅开发)观察生成的 SQL,确认参数是否以 $1、:email 形式出现,而非明文嵌入

真正的难点不在“怎么写安全”,而在于“什么时候不该交由用户控制结构”。字段名、操作符、JOIN 表顺序这些,从来就不该是 API 的自由输入项。

大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

sql注入 fastapi

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4423

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

931

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1169

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6361

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3163

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6320

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8621

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1170

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1032

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP开发基础之数据库篇(PDO)
PHP开发基础之数据库篇(PDO)

共10课时 | 2.3万人学习

FastAPI SQL数据库实战文档
FastAPI SQL数据库实战文档

共0课时 | 0人学习