小鱼塘--自说自话的地方

  • 小玩意
  • 小想法
记录自己技术和想法地方
  1. 首页
  2. c++
  3. workflow
  4. 正文

怎么解决SQL注入

15 12 月, 2025 12点热度 0人点赞 0条评论
内容目录

产生背景

因为我使用sogou workflow 开发c++ http 后台,它没有提供预处理api,所以又思考sql注入,我跟AI聊了好久,重新认识到sql注入,我发现以前认知好多是错误的。

拼接字符串,如果直接传入用户数据,那么可能导致用户语句把用户字符串,变成含有其他语义的sql语句,你可以理解,这样子可以传入构建任何执行脚本,导致你的他可以访问你的数据或者可以修改你的数据

转义

这个转义基本说mysql 转义,这个是mysql 特有

这个是文档的介绍:
MySQL :: MySQL 8.0 Reference Manual :: 11.1.1 String Literals

为什么转义可以防止注入

因为mysql 解析时候检测含有\ 然后判断后面字符替换成对应字符串,这个可以我们c/c++ 写\n代换行符号,我现在突然明白以前为什么写c/c++语言 在字符串中\n \t \0代表,用来换行或者进行间隔。

mysql 在执行sql语句,估计编译sql 会检测这些符号,他不会遇到\' 中的单引号,认为是单引号,所以这里不是替换,不然\' 替换成单引号,不然就会截断sql

举例
用户可以查询名字获取用户信息,这个是最简单的sql
正常sql

select * from user_table where name = '?';   

这里?是用户传入的名字

注入sql
用户名字是恶意构建: ‘or 1= 1--

select * from user_table where name = ''or 1= 1--'

等价的sql执行

select * from user_table

这个查询所有的数据

转义后的
用户名字是恶意构建: ‘or 1= 1--

select * from user_table where name = '\'or= 1--'

如果你用 markdown 支持sql语法,你会发现说明内容是字符串,不会截断字符串,但还是要mysql 客户端执行,你发现转义不会报错,说明\'

怎么转义

sogou workflow escape_string 转义的代码的

std::string MySQLUtil::escape_string(const std::string& str)
{
    std::string res;
    char escape;
    size_t i;

    for (i = 0; i < str.size(); i++)
    {
        switch (str[i])
        {
        case '\0':
            escape = '0';
            break;
        case '\n':
            escape = 'n';
            break;
        case '\r':
            escape = 'r';
            break;
        case '\\':
            escape = '\\';
            break;
        case '\'':
            escape = '\'';
            break;
        case '\"':
            escape = '\"';
            break;
        case '\032':
            escape = 'Z';
            break;
        default:
            res.push_back(str[i]);
            continue;
        }

        res.push_back('\\');
        res.push_back(escape);
    }

    return res;
}

这个把原来符号,转换成字符串,比喻一个单引号,转换一个反斜杠 和 单引号,我开始都没有明白,我就是\'就是单引号,这个是编译器会进行处理,这样子语法才不会报错。

前提

默认情况mysql开启转义,如果你要关闭这个转义,你要设置 SQL_MODE ,设置成 NO_BACKSLASH_ESCAPES,但这样子如果通过转义防止注入就是失效了

sql 转移

上面是c 语言特有的转移规则,只是mysql 支持这种c语言特有转移,貌似好多语言都支持这些转义。

' => ''

只有这种,所以其实用 sql 转义来保证防止sql 注入。

总结

  1. 转义基本能解决字符串中含有单引号和双引号的注入手段,多条语句拼接不在这篇讨论,所以你看到所有文章说,转义不能百分百解决,可能考虑编码和考虑是否关闭了Mysql转义的功能,但默认情况下就是开启的并用utf8编码,所以可以单条语句,并保证处理传入值是字符串一定被转义就没有问题了,这样子保证sql语句和值分开了,因为不会被截断
  2. 可以用sql 转义,所有字符串用''包含起来,然后包含值的内容,全部用' =>''转义,这个标准,所以sql 语法支持都支持这种,其实用这种方式更加好,但如果内容含有\可能就有问题,因为被数据库转义了,不过这个防注入没有关系,只是我存放JSON 字符串的时候发现中文就有\ 导致被数据转义,这个反斜杠就被吃掉,取出来就有问题了
  3. 遇到模糊的地方,应该多思考几次就会发现更多知识点,目前有AI,很多技术可以反复讨论
  4. 对了解决sql注入百分百肯定预处理了,因为数据库层面解决这个问题,因为明确区分脚本和数据,所以根本不会存在这个问题,SQL注入原因就是拼接字符串不能区分sql 和 数据。
标签: 暂无
最后更新:15 12 月, 2025

小鱼儿

爱研究技术,爱玩LOL

点赞
< 上一篇

COPYRIGHT © 2022 小鱼塘. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

湘ICP备18005349号