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

如何利用PostgreSQL的行级安全性防止SQL注入提权_配置RLS策略

落萱吖_2536

落萱吖_2536

发布时间:2026-05-14 10:34:47

|

289人浏览过

|

来源于php中文网

原创

RLS不能防止SQL注入,但能限制注入成功后的数据越权访问;因其在查询执行前由数据库重写器自动添加WHERE过滤,仅作用于启用了RLS的目标表DML操作,不干预函数调用、系统表查询等绕过场景。

如何利用postgresql的行级安全性防止sql注入提权_配置rls策略

RLS 本身不能防止 SQL 注入,但能有效阻断注入成功后的数据越权提权。 换句话说:SQL 注入若已发生,攻击者仍可能执行任意语句;但只要 RLS 策略正确启用并覆盖所有操作类型,他最多只能读/写自己权限范围内的行——哪怕他拼出了 SELECT * FROM users,数据库也会自动加上 WHERE tenant_id = '当前会话值' 过滤条件。

为什么 RLS 不是 SQL 注入的“防火墙”

SQL 注入发生在应用层拼接字符串阶段,而 RLS 是查询执行前由 PostgreSQL 查询重写器注入的 WHERE 条件。两者不在同一防线:

  • 注入成功 → 攻击者获得数据库连接上下文 → 可执行任意合法 SQL(如 SELECT pg_sleep(10)、UNION SELECT password FROM users)
  • RLS 生效 → 仅对目标表的 DML 操作(SELECT/INSERT/UPDATE/DELETE)自动加过滤,不干预函数调用、元数据查询、系统表访问等
  • 典型绕过场景:SELECT * FROM pg_user 不受任何 RLS 约束;SELECT * FROM app_data WHERE id = 1 OR 1=1 会被 RLS 截断为 ... AND tenant_id = 'xxx',但前提是 app_data 启用了 RLS 且策略未被 TO PUBLIC 或角色遗漏绕过

配置 RLS 策略时必须避免的三个提权漏洞点

很多团队启用了 RLS 却仍被越权,问题常出在策略定义或上下文管理上:

  • USING 和 WITH CHECK 混用错误:比如只写了 USING (tenant_id = current_setting('app.tenant_id')::UUID) 用于 SELECT,却没给 INSERT 加 WITH CHECK,导致攻击者可伪造 tenant_id 插入其他租户数据
  • 会话变量未设默认值或未校验:若应用忘记执行 SET app.tenant_id = 'xxx',current_setting('app.tenant_id', true) 返回 NULL,而 tenant_id = NULL 永远为 false → 启用 RLS 后无策略匹配,用户查不到任何数据(看似安全),但若策略写成 tenant_id = current_setting('app.tenant_id')::UUID OR current_setting('app.tenant_id') IS NULL,就等于放行全部数据
  • 超级用户/表所有者未被强制约束:默认情况下 ALTER TABLE ... FORCE ROW LEVEL SECURITY 未启用,超级用户和表所有者执行查询时 RLS 策略自动失效。生产环境必须显式执行该命令,否则攻击者一旦拿到 superuser 权限,RLS 形同虚设

带 LEAKPROOF 函数的安全策略写法

直接在策略中调用非 LEAKPROOF 函数(如自定义的 get_tenant_id())可能导致侧信道信息泄露,甚至被用于盲注推断数据。正确做法是确保所有策略内函数都声明为 LEAKPROOF:

CREATE OR REPLACE FUNCTION get_current_tenant_id()
RETURNS UUID
LEAKPROOF STABLE LANGUAGE SQL AS $$
  SELECT NULLIF(current_setting('app.tenant_id', TRUE), '')::UUID;
$$;

然后策略使用它:

CREATE POLICY tenant_isolation_policy ON app_data
  FOR ALL USING (tenant_id = get_current_tenant_id())
  WITH CHECK (tenant_id = get_current_tenant_id());

注意:LEAKPROOF 表示该函数不会通过运行时行为(如执行时间、错误消息)泄露输入参数内容,是防御基于函数行为的盲注关键。

验证策略是否真正在生效

别只信 pg_policies 里有记录,要实测策略是否被查询计划实际采纳:

  • 用非管理员角色连接,执行 EXPLAIN (ANALYZE, VERBOSE) SELECT * FROM app_data LIMIT 1;,确认输出中出现类似 Filter: ((tenant_id = 'xxx'::uuid)) 的行
  • 故意 unset 会话变量后查询,检查是否返回 0 行(而非报错或全量返回)
  • 用 pg_has_role(current_user, 'admin', 'MEMBER') 写管理员例外策略时,务必测试 admin 角色能否真正绕过限制——常见错误是把 USING 写成 AND 而非 OR,导致管理员也被过滤

最危险的疏忽不是策略没写,而是策略写了但没覆盖 FOR INSERT 或漏了 FORCE ROW LEVEL SECURITY,让 RLS 在关键路径上静默失效。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

DeepSeek

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

豆包大模型

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

讯飞绘文

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

WorkBuddy

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

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

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

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

4103

2023.10.12

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

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

871

2023.10.27

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

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

1069

2024.02.23

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

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

5981

2024.03.06

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

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

2883

2024.03.06

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

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

5960

2024.04.07

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

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

7961

2024.04.29

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

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

1090

2024.04.29

C++运算符基础入门
C++运算符基础入门

本专题详细讲解了C++运算符的类型、语法与使用方法,涵盖算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符及其他特殊运算符,并通过代码示例解析优先级与结合性。

0

2026.10.09

热门下载

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

精品课程

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

共10课时 | 2.3万人学习

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

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