跳到主要内容
系统常识 SQL Server注入安全

防 SQL 注入的基本做法

防 SQL 注入的四道核心防线:参数化查询、预编译、最小权限、输入校验,以及在 T-SQL 里写动态 SQL 时的安全写法。

发布于 2026/11/11 所属频道 SQL Server

结论先行

防注入的核心就一条:永远不要把用户输入直接拼进 SQL 文本。四道防线按优先级排:①参数化/预编译(根治)→ ②最小权限账号(限损)→ ③输入校验(纵深)→ ④动态 SQL 时参数化批处理。做到 ①② 两项,注入面就基本关死了。

四道防线

① 参数化查询(根治手段)

-- 错误:拼接
DECLARE @sql NVARCHAR(400) = N'DELETE FROM Orders WHERE Id = ' + CAST(@Input AS NVARCHAR(10));
EXEC(@sql);

-- 正确:参数化批处理
EXEC sp_executesql N'DELETE FROM Orders WHERE Id = @Id', N'@Id int', @Id = @Input;

应用层同理:所有 ORM 的参数绑定、ADO 的 @参数 占位符都是参数化;字符串拼 SQL 本身就是病。

② 最小权限(限损)

应用账号只给需要的表的 SELECT/INSERT/UPDATE 权限,不给 sysadmin、不给 DROP 权——即使被注入执行了语句,能破坏的范围也有限(见最小权限相关条目)。

③ 输入校验(纵深)

白名单优先:期望数字就只收数字,期望枚举就收枚举值;校验在入口做,别指望数据库替你筛。

④ 动态 SQL 的额外注意

EXEC(@动态语句) 必须走 sp_executesql 参数化;语句里要拼入表名/列名(不能参数化的对象名)时,只能白名单映射(从代码里已知的合法名列表里选),绝不接受用户直传。

常见误判

「我做了输入过滤(禁分号、禁 DROP)」≠ 防注入。过滤永远比参数化晚到一步,绕过成本极低。

  • 报错信息泄露结构(列名、表名):面向用户层的错误不要原样透出数据库报错(应用层处理)。
  • 视图/存储过程里 EXECUTE AS 权限提升:定义权限的存储过程是「白盒」,改对象逻辑前评估调用方权限。

在 SQL Server 2022 Developer 条目环境下可用 SSMS 管理工具条目 演练参数化写法与权限配置;旧引擎(如 SQL Server 2019 Developer)上这些防线的要求完全相同——注入是应用与权限设计问题,不随引擎版本变。

相关链接

本文内容基于公开资料整理,仅供参考;涉及授权与合规的操作请以厂商官方文档为准。

相关推荐下载

按本文主题匹配的官方原版镜像条目

配套 PE 工具

制作启动盘、备份数据、修复引导

其他常识文章

同一集合内的相近主题,按标签与关键词匹配