0

0

C# 防止SQL注入方法 C#如何使用参数化查询防止注入

煙雲

煙雲

发布时间:2026-03-11 10:28:03

|

867人浏览过

|

来源于php中文网

原创

参数化查询必须使用@param占位符,确保用户输入仅作为值不参与sql解析;禁止字符串拼接、动态sql及非白名单的标识符拼接;存储过程、ef core和dapper均需严格遵循参数化规范。

c# 防止sql注入方法 c#如何使用参数化查询防止注入

SqlCommand 参数化查询必须用 @param 占位符,不能拼字符串

直接把用户输入塞进 SQL 字符串里(比如 "SELECT * FROM Users WHERE name = '" + input + "'")等于给攻击者开后门。SQL Server 会把引号、分号、UNION SELECT 全当语法执行,参数化查询的核心就是让输入**永远只被当作值**,不参与 SQL 解析。

正确做法是用 @ 开头的命名参数,再通过 Parameters.Add() 绑定值:

string sql = "SELECT * FROM Users WHERE email = @email AND status = @status";
using var cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add(new SqlParameter("@email", userEmail));
cmd.Parameters.Add(new SqlParameter("@status", "active"));
  • @email@status 必须和 SQL 字符串里完全一致(包括大小写)
  • 不要用 ? 占位符(那是 ODBC 或 SQLite 的写法,SQL Server 不认)
  • 避免用 Parameters.AddWithValue() —— 它会自动推断类型,可能把 int 推成 decimal,导致索引失效或隐式转换错误

存储过程调用也得用参数,别在 SP 内部拼接

有人以为“用了存储过程就安全了”,其实不然。如果在存储过程中用 EXEC(@sql)sp_executesql 拼接用户输入,照样中招。真正安全的是:C# 层传参进去,SP 内部只用参数变量做条件判断。

例如 SP 定义为:

CREATE PROC GetUserByPhone @phone NVARCHAR(20)
AS
SELECT * FROM Users WHERE phone = @phone

C# 调用时:

var cmd = new SqlCommand("GetUserByPhone", conn) { CommandType = CommandType.StoredProcedure };
cmd.Parameters.Add(new SqlParameter("@phone", userPhone));
  • 务必设 CommandType = CommandType.StoredProcedure,否则 SQL Server 当成普通 SQL 执行
  • SP 内部禁止出现 CONCAT+ 连接用户输入、或 QUOTENAME() 后再拼接——那只是“看起来像防注入”,实际仍可能绕过

动态列名/表名不能参数化,得靠白名单或 QUOTENAME

参数化只适用于**值(value)**,不适用于对象名(如列名、表名、排序字段)。如果你要根据用户选择动态切换 ORDER BY 字段,@sortColumn 是无效的:

Molica AI
Molica AI

一款聚合了多种AI工具的一站式创作平台

下载
/* ❌ 错误:SQL Server 不允许参数化标识符 */
SELECT * FROM Logs ORDER BY @sortColumn

可行方案只有两个:

  • 硬编码白名单:switch (userSort) { case "created": order = "created_at"; break; ... }
  • QUOTENAME() 包裹后再拼(仅限 T-SQL 层):"ORDER BY " + QUOTENAME(@rawSort),但注意 C# 层仍需先校验 @rawSort 是否在允许范围内,不能无条件信任

任何试图用反射、表达式树或 DataTable.Columns 动态生成列名的操作,都得走白名单兜底——没例外。

Entity Framework 也得小心 FromSqlRaw 和字符串插值

EF Core 默认 LINQ 查询是安全的,但一旦用到 FromSqlRawExecuteSqlRaw,就重回手写 SQL 场景。下面这段看着像参数化,实则危险:

/* ❌ 错误:字符串插值在编译期就拼好了,参数化失效 */
context.Users.FromSqlRaw($"SELECT * FROM Users WHERE name = '{name}'");

正确写法必须显式传参:

context.Users.FromSqlRaw("SELECT * FROM Users WHERE name = {{0}}", name); // EF Core 5+
// 或更推荐:
context.Users.FromSqlInterpolated($"SELECT * FROM Users WHERE name = {name}");
  • FromSqlInterpolated 是 EF Core 提供的安全插值方式,它会自动转成参数化
  • 绝对不要在 FromSqlRaw 里用 $"..." 插入变量,哪怕加了 @ 前缀也没用
  • 第三方库如 Dapper 同理:connection.Query<user>("SELECT * FROM Users WHERE id = @id", new { id = userId })</user> 是安全的;new { sql = $"WHERE id = {userId}" } 就是自毁

最常被忽略的一点:参数化能防注入,但防不了逻辑漏洞(比如用户越权查别人数据)、也防不了错误信息泄露(比如把 SQL 异常直接返回前端)。真正的防护是分层的——参数化只是第一道,后面还得有最小权限账号、输入长度/格式校验、异常屏蔽。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

1133

2023.10.12

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

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

340

2023.10.27

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

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

381

2024.02.23

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

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

2152

2024.03.06

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

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

380

2024.03.06

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

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

1663

2024.04.07

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

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

585

2024.04.29

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

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

440

2024.04.29

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.1万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.4万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号