如何编写安全的SQL查询_使用参数化查询彻底杜绝注入
string.Format拼SQL必然导致SQL注入因用户输入会直接混入SQL结构必须用参数化查询如SqlCommand.Parameters.Add隔离值与结构并对动态表名/列名等采用白名单校验。为什么 string.Format 拼 SQL 一定会出事因为数据库不会区分“你是想查用户”还是“你想删表”。只要字符串里混了用户输入WHERE name {input} 这种写法攻击者塞个 OR 11 就能绕过条件塞个 ; DROP TABLE users; -- 就直接执行非法命令。这不是“可能被利用”是只要输入可控就必然可利用。常见错误现象SqlException 报错信息里出现意外的 OR、UNION 或多出的引号查询返回本不该看到的数据甚至日志里发现 SELECT * FROM users WHERE id 1; DELETE FROM orders; 这种明显拼接痕迹。永远别用 string.Format、$ 插值、 拼接构造 SQL 条件或表名/列名连“管理员固定查 status1”这种看似安全的硬编码一旦未来加个动态筛选入口就会立刻变成漏洞点ORM 的 .Where(x x.Name input) 是安全的但 .Where($name {input})EF Core 早期某些扩展照样危险用 SqlCommand Parameters.Add() 是最稳的写法SQL Server 的参数化查询本质是把值和结构分开命令文本是纯模板参数是独立数据包驱动层确保它们不混合解析。哪怕你传入 Robert; DROP TABLE Students; --数据库也只当它是字符串值绝不会当成语句执行。使用场景所有带用户输入的 SELECT、INSERT、UPDATE、DELETE包括分页参数、模糊搜索关键词、状态筛选下拉值。必须用 cmd.Parameters.Add(name, SqlDbType.NVarChar).Value userInput而不是 AddWithValue —— 后者会猜类型遇到空字符串可能推成 varchar(0) 导致索引失效参数名必须以 开头且不能和变量名重复比如别写 cmd.Parameters.Add(id, id)id 是变量这里要传值批量操作时每个参数单独 Add不要试图用循环拼 p0、p1 —— 那又回到手动管理的脆弱路径var cmd new SqlCommand(SELECT * FROM users WHERE status status AND name LIKE pattern, conn);cmd.Parameters.Add(status, SqlDbType.Int).Value status;cmd.Parameters.Add(pattern, SqlDbType.NVarChar).Value $%{search}%;IN 列表和动态列名没法直接参数化得换思路IN (p1, p2, p3) 看似参数化但实际不支持变长列表——你不能在运行时决定加几个 p。而表名、列名、排序字段这些语法成分数据库根本不允许用参数占位否则会报 Incorrect syntax near table。 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手依托大模型帮助用户记录、整理和分析音视频内容体验用大模型做音视频笔记、整理会议记录。