讲师中心 微信公众号
AI工具推荐 视频效率加速

如何防止多租户系统发生SQL注入越权

星强君_4588

星强君_4588

发布时间:2026-08-09 13:09:24

|

166人浏览过

|

来源于php中文网

原创

租户上下文与SQL结构必须强绑定,tenant_id须硬编码进所有业务SQL或由框架/中间件强制注入,严禁开发自觉添加;漏写条件、误用CURRENT_USER、未校验动态Schema名、绕过视图直查基表等均会导致越权与注入风险叠加。

如何防止多租户系统发生sql注入越权

多租户系统里,SQL注入和越权不是两个独立问题,而是一体两面:注入一旦成功,往往直接绕过租户隔离逻辑,查到其他租户数据。核心防线不在“防注入”或“防越权”单点,而在**租户上下文与SQL结构的强绑定**。

tenant_id 必须作为查询条件硬编码进所有业务SQL

行级隔离方案下,tenant_id 不能靠应用层“自觉加”,必须由框架或中间件强制注入。常见错误是开发在DAO里写 SELECT * FROM orders WHERE id = ?,漏掉 tenant_id = ? 条件。

  • MyBatis 用拦截器,在 Executor.update 和 query 前自动追加 AND tenant_id = #{tenantId},且对 INSERT 语句自动补全 tenant_id 字段值
  • ShardingSphere 配置 tenant_id 为分片键,所有路由、改写、归并逻辑都基于它,但注意:它不拦截 SELECT * FROM orders 这类无条件查询——得配合 sqlHint 或自定义 SQLRewriteRule
  • PostgreSQL 的 RLS(行级安全策略)要求每个用户连接对应租户角色,策略中写 USING (tenant_id = current_setting('app.tenant_id')),但前提是应用每次连接前执行 SET app.tenant_id = '123',且该 setting 不被用户输入污染

动态表名/Schema 名必须走白名单映射

Schema 级隔离时,SET search_path TO tenant_abc 的 tenant_abc 若来自用户输入(如 URL path 中的 /api/tenant_abc/orders),就等于把租户名当 SQL 结构暴露出去——参数化查询对它完全无效。

  • 维护一个只读配置数组:$valid_tenants = ['tenant_abc' => 'tenant_abc', 'tenant_xyz' => 'tenant_xyz'],用 in_array($input, $valid_tenants, true) 校验,不接受任何正则过滤或转义
  • PostgreSQL 中禁止在视图里用 CURRENT_USER 动态过滤租户数据(如 CREATE VIEW my_data AS SELECT * FROM orders WHERE tenant_id = CURRENT_USER),因为 CURRENT_USER 是数据库角色名,不是业务租户ID,且无法与 JWT 中的 tenant_id 对齐
  • 连接池层(如 PgBouncer)不支持 per-connection 的 search_path 设置,所以必须在应用获取连接后立刻执行 SET search_path,不能依赖连接初始化脚本

敏感字段脱敏必须固化在数据库视图里

应用层做手机号掩码(如 substr(phone, 0, 3) . '****' . substr(phone, -4))不可靠:任意一个开发漏写,或 ORM 自动生成的 SELECT * 就会把原始字段吐出去。

  • 建 user_safe_view 视图,里面用 REGEXP_REPLACE(phone, '(\d{3})\d{4}(\d{4})', '\1****\2')(PostgreSQL)或 CONCAT(LEFT(phone,3), '****', RIGHT(phone,4))(MySQL 5.7)直接输出脱敏结果
  • 应用账号只授予该视图的 SELECT 权限,不给底层 users 表权限;即使攻击者通过注入拿到视图名,也只能看到已脱敏字段
  • 视图里不能带 WHERE tenant_id = ? 这种参数化条件——视图定义是静态的,运行时变量不生效;租户隔离仍需靠上层 RLS 或连接级 search_path

数据库账号权限必须按租户粒度隔离

哪怕用了 RLS 或 Schema 隔离,如果应用统一用一个高权限账号连接数据库,攻击者注入成功后就能 UNION SELECT 其他租户表,或直接 SELECT * FROM pg_tables 枚举结构。

  • 为每个租户创建独立数据库用户(如 tenant_123_app),只授予其对应 Schema 的 USAGE 和 SELECT/INSERT/UPDATE 权限,禁用 CREATE、DROP、pg_read_all_data
  • Schema 级隔离时,禁止跨 Schema 查询:SELECT a.*, b.name FROM tenant_a.users a JOIN tenant_b.orders b ON ... 这类语句必须显式拒绝,可在 PostgreSQL 中用 row_security + SECURITY DEFINER 函数封装,或在 API 网关层校验 SQL AST
  • DBA 手工运维时,绝不用租户账号执行 psql -U tenant_123_app,而应切换到专用运维账号;否则一次 \dt 就可能暴露租户 Schema 列表

最易被忽略的点是:RLS 策略开启后,SELECT 语句受控,但 INSERT 和 UPDATE 仍可能被绕过——比如插入时没校验 tenant_id 是否匹配当前会话上下文,导致数据写错 Schema 或行。这需要在触发器或应用层双重检查,不能只信 RLS。

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

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

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

3863

2023.10.12

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

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

831

2023.10.27

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

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

1009

2024.02.23

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

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

5701

2024.03.06

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

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

2643

2024.03.06

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

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

5680

2024.04.07

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

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

7481

2024.04.29

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

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

1030

2024.04.29

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

0

2026.09.30

热门下载

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

精品课程

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

共10课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn