What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
SQL 注入(SQL Injection,简称 SQLi)是一种服务器端漏洞:应用程序把用户可控输入直接拼接进 SQL 查询,导致数据库把本应是“数据”的内容当成 SQL 代码执行。
开发者最应优先做的是使用参数化查询(预编译语句或绑定变量);普通用户无法通过浏览器设置修复网站服务器端的 SQL 注入,只能降低账户和数据暴露风险。
SQL 注入是怎么发生的?
SQL 是应用与关系型数据库通信的语言。用户输入并不只来自表单,也可能来自 URL 参数、Cookie、HTTP Header、JSON、移动应用、内部 API、后台管理页面、文件导入或批处理任务。
Free tools Windows power users keep installed
One-click scans. No signup required.
危险之处在于“代码”和“数据”没有分离。例如:
#1 Best Overall
- MESSAGE: A clear “SQL INJECTION” statement with Black background with a worn rusted brown distressed border; large white textured text reading "SQL INJECTION"; white outlined stylized database icon (stacked cylindrical data storage symbol); two white outlined syringes piercing the database icon from left and right; whole design uses a scratched hatched texture for a distressed effect.
- FINISH: The metal panel helps the “SQL INJECTION” artwork stand out on the wall.
- PLACEMENT: The compact 8 x 12 inch format gives the “SQL INJECTION” design a focused wall presence.
- STYLING: Complements home office, tech office while keeping the “SQL INJECTION” message easy to notice.
- WHY IT FITS: Combines the specific “SQL INJECTION” message with easy everyday display.
username = request.args["username"]
sql = "SELECT * FROM users WHERE username = '" + username + "'"
cursor.execute(sql)
这里的用户输入被放进了 SQL 语句文本中。问题不在于某一个特殊字符,而在于应用让外部输入有机会改变查询的语义。MITRE 将该问题归类为 CWE-89:SQL 命令中的特殊元素未被正确中和。
前端 JavaScript、HTML 的 maxlength、隐藏字段和浏览器表单校验都不能解决这个问题。攻击者可以绕过页面,直接构造 HTTP 请求;Cookie 和隐藏字段同样不能被视为可信数据。
SQL 注入可能造成什么后果?
- 数据泄露:读取其他用户的个人信息、订单、财务记录、内部配置或凭据;盲注还可能通过响应差异逐步推断数据。
- 数据篡改或删除:修改账户、权限、价格、订单和内容,甚至删除或锁定数据。
- 身份验证或访问控制绕过:不安全的登录或授权查询可能让攻击者绕过密码验证或改变权限判断。
- 服务中断:触发昂贵查询、锁定资源,造成数据库或应用不可用。
- 进一步影响基础设施:在数据库类型、账户权限、网络配置和启用功能都允许的情况下,漏洞可能成为攻击服务器或其他系统的跳板,但 SQL 注入并不必然等于取得服务器权限。
具体影响取决于查询、数据库、应用账户权限和网络环境。只读账户也不能被视为安全:它仍可能造成敏感数据泄露、登录绕过和后续攻击。
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesRank #2
- Artwork theme: Sql Injection Cybersecurity for display in Office, Tech Office, and Cyber Lab.
- Aluminum construction: Glossy surface and high-resolution UV printing keep the design sharp and readable.
- Long-term use: Waterproof and rust-resistant finish also helps resist sunlight and fading.
- Format: 8 x 12 inch single-sided flat sign, 0.03 inch thick, with rounded corners and four pre-drilled holes.
- Suitable present: Cybersecurity Gift. No screws, hooks, or other mounting hardware are included.
常见的 SQL 注入类型
| 类型 | 特征 |
|---|---|
| 带内注入 | 注入结果通过同一个响应渠道返回,例如页面直接显示结果或数据库错误。 |
| 盲注 | 页面不显示数据,但真假条件、响应内容或时间差会发生变化。 |
| 错误型注入 | 详细数据库错误暴露查询结构,帮助攻击者调整请求。 |
| 联合查询或堆叠查询 | 尝试组合查询或执行多个语句,是否可行取决于数据库和驱动接口。 |
| 二阶注入 | 输入先被保存,之后在另一条流程中进入 SQL;保存时看起来正常并不代表安全。 |
| 带外注入 | 结果通过其他网络渠道传出,受数据库功能和网络配置限制。 |
这些分类用于理解风险,不意味着所有数据库或接口都支持同一种行为。可参考 OWASP 的 SQL 注入说明和 PortSwigger 的 SQL 注入学习资料。
最可靠的防护:参数化查询
参数化查询先固定 SQL 结构,再将输入作为独立参数传给数据库,使其被当作值而不是 SQL 语法。这是 OWASP 推荐的首选防护。
Python DB-API
sql = "SELECT * FROM users WHERE username = %s"
cursor.execute(sql, (username,))
Java JDBC
String sql = "SELECT account_balance FROM user_data WHERE user_name = ?";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, customerName);
ResultSet results = statement.executeQuery();
PHP PDO
$stmt = $pdo->prepare(
'SELECT * FROM users WHERE username = :username'
);
$stmt->execute(['username' => $username]);
C# ADO.NET
using var command = new SqlCommand(
"SELECT * FROM Users WHERE Username = @username", connection);
command.Parameters.Add("@username", SqlDbType.NVarChar, 100)
.Value = username;
using var reader = command.ExecuteReader();
Node.js
const [rows] = await connection.execute(
"SELECT * FROM users WHERE username = ?",
[username]
);
不要机械复制占位符。不同数据库驱动可能使用 %s、?、:name 或 $1。应按照实际驱动的参数绑定 API 编写,并确认驱动确实采用安全的预处理方式。
Rank #3
- Funny SQL design for SQL Programmer, Software Engineer, DBA, and Hacker.
- Funny SQL Injection Knock knock joke design for Network programmer, computer security professional, web developer, backend coder, and database programmer.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
动态表名、列名和排序方向怎么办?
参数通常适用于值,不一定能直接绑定表名、列名或 ASC/DESC。例如,不能把任意用户输入直接放进:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →SELECT * FROM users ORDER BY <user-supplied-column>
应使用代码中的固定映射:
allowed_sort_columns = {
"name": "display_name",
"date": "created_at",
}
sort_key = request.args.get("sort", "date")
sort_column = allowed_sort_columns.get(sort_key, "created_at")
direction = "DESC" if request.args.get("descending") == "1" else "ASC"
sql = f"SELECT * FROM users ORDER BY {sort_column} {direction}"
cursor.execute(sql)
这里进入 SQL 的是开发者预先定义的合法标识符,而不是用户原始字符串。对于表名、列名、排序方向和其他 SQL 结构,优先重新设计查询;无法重构时,使用严格允许列表和固定映射。
ORM 和存储过程并不会自动免疫
ORM 通常提供参数化接口,但原生 SQL、raw、unsafe、execute 等低级 API,以及查询构造器中的字符串拼接,仍可能产生注入。HQL、JPQL、LINQ 等抽象层也必须使用命名参数或其他参数化机制。
Rank #4
存储过程同样取决于实现。参数化接收输入的存储过程可以安全,但内部动态拼接 SQL 仍然危险:
SET @sql = 'SELECT * FROM users WHERE name = ''' + @name + '''';
EXEC(@sql);
详细错误信息不应返回给用户;但隐藏错误只能减少信息泄露,不能阻止恶意查询执行。
纵深防御:参数化之外还要做什么?
- 输入校验:校验类型、长度、格式、业务范围和枚举值,例如页码必须大于 0、状态只能是规定选项。它是辅助防线,不是参数化的替代品。
- 拒绝黑名单思维:只过滤单引号,或禁止
SELECT、UNION、DROP等字符串,都不能可靠覆盖不同编码、语法和查询上下文。 - 最小权限:应用账户不应使用数据库管理员权限。根据实际需要限制读、写、建表、删除和执行系统功能的权限;必要时使用视图限制可访问的行和列。
- 数据库隔离:数据库不直接暴露公网,关闭默认账户、示例数据库和不必要功能,并使用适当的加密和密钥管理。
- 日志与监控:记录异常查询失败率、异常参数模式、响应时间和高风险操作,同时避免记录密码、令牌和完整敏感数据。
- WAF:可作为暂时防线或纵深防御,但可能漏报、误拦或被绕过,不能修复代码,也不能覆盖非 HTTP 输入路径、内部 API 和二阶注入。参见 MITRE 对防护局限的说明。
“转义所有输入”也不是首选方案。转义规则依赖数据库、字符集和 SQL 上下文,容易漏掉某条查询路径;只有无法使用参数化查询时,才应在充分了解具体环境的前提下考虑它作为最后手段。参见 OWASP SQL 注入防护备忘单。
Best Value
- Select From Where Users Clue No Records Found SQL Query is best for database admin and computer expert programmers that protect the system, devices, and data from hacking or cyber-attacks.
- Excellent treat shirt or accessories for IT or any computer programming specialists to wear on any occasion. Grab one for yourself or for someone who will love this trendy artwork design.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
如何安全测试和修复自己的应用?
测试只能针对自己拥有的系统、明确授权的环境、教学靶场或漏洞赏金明确允许的范围。不要在第三方网站或生产系统上盲目尝试攻击请求。
- 代码审查:搜索 SQL 字符串拼接、动态 SQL、原生查询、
EXEC、sp_executesql以及 ORM 的 raw API。 - 追踪数据流:从 URL、表单、Cookie、Header、JSON、文件和消息队列一路追踪到数据库执行点。
- 改写查询:删除字符串拼接,使用当前驱动的参数化 API;动态结构改用固定映射。
- 收紧权限:限制应用数据库账户,检查敏感数据访问和数据库网络暴露。
- 测试:在隔离数据库中使用引号、Unicode、长文本和边界值编写单元与集成测试,确认输入不会改变查询结构。
- 自动化与人工复核:结合 SAST、DAST 或 IAST,但人工确认误报、业务逻辑和复杂 ORM 封装。OWASP 的安全代码审查指南强调自动化工具与人工审查应互补。
- 回归验证:修复后检查同一数据流的其他接口、后台任务和导入流程,避免只修复一个入口。
- 生产事件响应:如果漏洞可能已被利用,应评估日志、数据完整性、数据库凭据轮换和会话撤销,而不是只提交代码补丁。
学习和授权练习可使用 PortSwigger Web Security Academy。OWASP ZAP 等工具适合授权环境的动态扫描,但自动化扫描可能漏报和误报,不能替代修复。
普通用户能做什么?
SQL 注入主要是网站服务器端问题,普通用户无法通过安装浏览器插件、修改浏览器设置或运行杀毒软件来修复它。你能做的是降低漏洞被利用后的影响:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Quick Recap
- 在可疑网站上不要输入不必要的个人信息。
- 每个网站使用唯一密码,最好使用密码管理器生成密码。
- 开启多因素认证,关注登录、密码重置、订单和支付通知。
- 及时更新操作系统、浏览器和客户端应用。
- 发现数据库报错、异常跳转或数据泄露迹象时停止操作,并向网站运营方报告。
- 怀疑账户被入侵时,立即修改密码、撤销会话;涉及支付账户则联系银行或支付机构。
修复检查清单
- 所有用户输入是否都通过参数化 API 进入数据库?
- 是否仍存在 raw SQL、动态 SQL 或字符串拼接?
- 表名、列名和排序方向是否使用固定映射?
- ORM 和存储过程内部是否还会拼接 SQL?
- 应用数据库账户是否遵循最小权限?
- 生产环境是否隐藏详细数据库错误?
- 是否有单元测试、集成测试、自动化扫描和人工复核?
- 修复后是否检查了相同输入进入数据库的其他路径?
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

