零点博客复盘:C# MySQL 接口开发中 SQL 注入的致命隐患与参数化查询解决方案

大家好,我是零点博客的主理人。昨天在整理 C# 仿 Emlog 博客系统的后端接口时,做了一次低级但惊险的测试。当我们以为代码写得没问题时,一个简单的搜索接口竟然被我利用成了数据泄露通道。今天这篇文章,不讲虚的理论,直接通过这次真实的安全复盘,带你彻底搞定 C# 中 MySQL 的 SQL注入 防护问题。

一、 那个“危险”的搜索接口

在开发搜索功能时,很多新手和我当初一样,图省事直接把前端传来的 JSON 数据直接拼接到 SQL 语句里。当时的代码逻辑是这样的:

// 错误示范:字符串拼接 SQL
string keyword = context.Request.Query["keyword"];
string sql = $"SELECT * FROM emlog_blog WHERE title LIKE '%{keyword}%'";

using (var conn = new MySqlConnection(connString))
{
    conn.Open();
    using (var cmd = new MySqlCommand(sql, conn))
    {
        // 直接执行,完全没经过任何过滤
        cmd.ExecuteNonQuery();
    }
}

表面上这段代码能跑通,但实际上它存在着巨大的 SQL注入 风险。如果你在搜索框里输入 %' OR '1'='1,原本的查询逻辑瞬间就会变成:SELECT * FROM ... WHERE title LIKE '%'' OR '1'='1%'。这等于绕过了身份验证,直接查出了全表数据。对于爬虫开发来说,这种漏洞简直是“送分题”,而对于普通用户,则是致命的隐私泄露。

二、 底层逻辑拆解:为什么拼接 SQL 是大忌?

很多人不理解为什么拼接就危险。简单来说,SQL 的执行分为两个阶段:解析阶段 和 执行阶段。

当你使用字符串拼接时,你的恶意字符直接进入了 执行阶段,数据库将其视为代码的一部分执行。而正确的方法是使用预处理语句(Parameterized Query)。在 C# 操作 MySQL 时,这通常是强制将变量与 SQL 语句分离,在发送 SQL 之前,数据库先编译好结构,然后只把“数据”塞进去。

三、 真正的落地解决方案(含源码)

接下来,我将分享如何改造这个接口,加入参数化查询。为了更好的兼容性,我使用了 MySQL Connector 的标准写法。

// 正确示范:使用参数化查询防止 SQL注入
string keyword = context.Request.Query["keyword"];
string sql = "SELECT * FROM emlog_blog WHERE title LIKE @Title";

using (var conn = new MySqlConnection(connString))
{
    conn.Open();
    using (var cmd = new MySqlCommand(sql, conn))
    {
        // 核心:添加参数对象,数据库会自动对 @Title 进行转义
        cmd.Parameters.Add("@Title", MySqlDbType.VarChar).Value = $"%{keyword}%";

        // 执行查询并返回 JSON 数据给前端
        using (var reader = cmd.ExecuteReader())
        {
            var resultList = new List<dynamic>();
            while (reader.Read())
            {
                // 简单地将查询结果封装成字典
                resultList.Add(new {
                    id = reader["blogid"],
                    title = reader["title"],
                    date = reader["date"]
                });
            }
            // 返回 JSON 格式结果
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsJsonAsync(resultList);
        }
    }
}

四、 补充:爬虫与正则的综合防护策略

虽然参数化查询是防 SQL注入 的最后一道防线,但在数据进入数据库之前,我们还可以通过前端 JavaScript 和后端 C# 代码结合正则表达式来过滤无效字符。在开发在线工具或爬虫接口时,面对极其复杂的网页结构,爬虫开发的稳定性往往取决于对正则表达式的熟练运用。同样地,面对用户输入的 URL 或搜索词,用正则剔除