当前位置: 首页 > news >正文

SQL 注入 (C++向)

SQL 注入(SQL Injection)原理

SQL 注入是一种常见的 Web 安全漏洞,攻击者通过在输入字段中注入恶意 SQL 代码,来操纵数据库查询,从而窃取数据、修改数据,甚至破坏数据库。

基本原理

  • 服务器接收用户输入,并将其作为 SQL 语句的一部分执行。
  • 如果输入未经过严格检查和过滤,攻击者可以构造特殊输入,使 SQL 语句的逻辑发生变化,从而执行额外的数据库操作。

例如,假设有以下 SQL 查询:

std::string sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";

如果 username 传入:

' OR '1'='1

那么最终 SQL 语句变成:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';

'1'='1' 始终为真,导致 查询返回所有用户,攻击者可以直接绕过登录验证。


SQL 注入攻击示例

示例 1:绕过登录认证

假设有一个 C++ 代码处理用户登录:

std::string sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
sql::ResultSet* res = mysqlUtil_.executeQuery(sql);
if (res->next()) {
    std::cout << "登录成功!" << std::endl;
} else {
    std::cout << "用户名或密码错误!" << std::endl;
}

攻击方式

  • 输入用户名admin' --
  • 输入密码随便填

最终生成的 SQL 语句:

SELECT * FROM users WHERE username = 'admin' --' AND password = '';
  • -- 使得 后面的 AND password = '' 被注释掉,攻击者成功绕过密码验证,直接以 admin 身份登录。

示例 2:获取数据库中的所有用户

假设攻击者想要获取 users 表中的所有数据,他们可以输入:

  • 用户名' OR 1=1 --
  • 密码随便填

导致 SQL 变成:

SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = '';

由于 1=1 始终为真,这个查询会返回 所有用户的数据,攻击者就能获取整个 users 表的信息。


示例 3:修改数据库中的数据

如果数据库允许修改密码:

std::string sql = "UPDATE users SET password = '" + new_password + "' WHERE username = '" + username + "'";

攻击者输入:

  • 用户名admin' --
  • 新密码hacked

最终 SQL 语句:

UPDATE users SET password = 'hacked' WHERE username = 'admin' --';

攻击者成功修改了 admin 用户的密码。


示例 4:删除数据库表

如果服务器执行如下 SQL 语句:

std::string sql = "DELETE FROM users WHERE username = '" + username + "'";

攻击者输入:

  • 用户名' OR 1=1 --

导致 SQL 变成:

DELETE FROM users WHERE username = '' OR 1=1 --';

1=1 始终为真,结果是 删除 users 表中所有数据


示例 5:联合查询窃取数据库信息

如果前端显示用户信息:

std::string sql = "SELECT id, username FROM users WHERE username = '" + username + "'";

攻击者输入:

  • 用户名' UNION SELECT id, password FROM users --

最终 SQL 语句:

SELECT id, username FROM users WHERE username = '' UNION SELECT id, password FROM users --';

这样攻击者就能获取 users 表中的 idpassword 字段!


SQL 注入的防范方法(C++)

C++ 主要使用 MySQL Connector/C++SQLite 进行数据库操作,防止 SQL 注入的关键在于:

  1. 使用预处理语句(Prepared Statements)
  2. 限制数据库权限
  3. 使用输入过滤
  4. 隐藏错误信息
  5. 使用 Web 应用防火墙(WAF)

方法 1:使用预处理语句

预处理语句(Prepared Statement)可以自动处理用户输入,防止 SQL 注入

使用 MySQL Connector/C++ 预处理语句

sql::PreparedStatement* pstmt;
pstmt = conn->prepareStatement("SELECT id FROM users WHERE username = ? AND password = ?");
pstmt->setString(1, username);
pstmt->setString(2, password);
sql::ResultSet* res = pstmt->executeQuery();
if (res->next()) {
    std::cout << "登录成功!" << std::endl;
} else {
    std::cout << "用户名或密码错误!" << std::endl;
}

为什么安全?

  • ? 占位符不会被 SQL 解析为代码,不会拼接 SQL 语句,而是让数据库单独处理参数。
  • setString() 自动转义输入,无论攻击者输入什么,数据库都不会把它当成 SQL 代码执行,而是当成 普通字符串。

方法 2:限制数据库权限

即使攻击者获得了访问权限,也应该 最小化数据库的权限

GRANT SELECT ON mydb.users TO 'webuser'@'localhost';
REVOKE DELETE, INSERT, UPDATE ON mydb.users FROM 'webuser'@'localhost';
  • webuser 只能查询数据,不能修改、删除数据。

方法 3:输入过滤

对用户输入进行严格的 白名单过滤

bool isValidUsername(const std::string& username) {
    return username.find("'") == std::string::npos && username.find("--") == std::string::npos;
}

但这不能完全防止 SQL 注入,最好结合预处理语句!


方法 4:隐藏错误信息

在 SQL 语句执行失败时,不要返回数据库错误信息:

try {
    sql::ResultSet* res = stmt->executeQuery(query);
} catch (sql::SQLException &e) {
    std::cout << "系统错误,请稍后再试。" << std::endl;
}

否则攻击者可以通过错误信息 推测数据库结构


方法 5:使用 Web 应用防火墙(WAF)

ModSecurity 等 WAF 可以检测 SQL 注入攻击,并阻止可疑的 SQL 语句:

apt install libapache2-mod-security2

总结

SQL 注入是一种非常危险的漏洞,但可以通过 预处理语句、权限管理、输入过滤等方式防止
使用预处理语句(防止 SQL 拼接)
限制数据库权限(防止数据泄露)
隐藏错误信息(防止信息泄露)
使用 WAF 防火墙(阻止恶意 SQL 语句)

C++ 代码中,一定要使用预处理语句,这样才能从根本上防止 SQL 注入!

相关文章:

  • 【Linux】初识make
  • 78.StringBuilder简单示例 C#例子 WPF例子
  • GPT 4.5 可能是戳破 AI 泡沫的模型
  • C++二叉搜索树代码
  • 西安交大DeepSeek—电力人工智能多模态大模型创新技术应用
  • Leetcode 刷题记录 04 —— 子串
  • 【Linux】多线程(1)
  • python语言总结(持续更新)
  • Vue2 的生命周期有哪些
  • 物联网智慧农业一体化解决方案-可继续扩展更多使用场景
  • SpringBoot整合Caffeine本地缓存
  • Server-Sent Events
  • 正则表达式(2)匹配规则
  • SQL注入练习场:PHPStudy+SQLI-LABS靶场搭建教程(零基础友好版)
  • 【Find My功能科普】防盗黑科技如何改变生活?
  • 提升大模型Text-to-SQL能力应用的实践
  • 人工智能与深度学习的应用案例:从技术原理到实践创新
  • VBA之Word应用第三章第七节:文档Document对象的方法(一)
  • 高效编程指南:PyCharm与DeepSeek的完美结合
  • 2.Swift Tabbar的使用
  • 制作网站企业/网络建站优化科技
  • 网站 外包合同/免费的seo网站下载
  • 政府门户网站建设的必要性/站长综合查询工具
  • 带会员功能的网站/佛山企业用seo策略
  • 建一个优化网站多少钱/在百度平台如何做营销
  • 免费网站内页模板 css/中国百强县市榜单