【问题标题】:Injection Proof SQL Statements from Command Line来自命令行的注入证明 SQL 语句
【发布时间】:2019-03-27 10:26:08
【问题描述】:

This related question 在 bash 中使用命令行 mysql 工具时询问是否使用参数化查询。但是,似乎最佳答案仍然容易受到注入(例如; DROP TABLE user; --)。虽然答案确实解决了根本如何传递变量的问题,但它没有解决使用参数化查询如何做到这一点的问题。

我的问题:链接问题中的链接接受答案是否提供针对 SQL 注入的保护,并具有参数化的所有有用保护?如果是这样,为什么?如果没有,如何安全地使用 MySQL 命令行工具中的参数化查询?

注意:从技术上讲,我正在运行mysql Ver 15.1 Distrib 10.3.13-MariaDB

【问题讨论】:

    标签: mysql sql bash security sql-injection


    【解决方案1】:

    面向客户的应用程序的常见做法是为每个数据库查询设置一个 API 端点,这需要用户身份验证。 API 服务器将在格式化查询时验证输入。

    直接在服务器上公开 bash 绝不是一个好主意。除了 SQL 注入之外,其他更糟糕的情况,例如; scp ~/.ssh/id_rsa my_proxy ;,也很容易发生。


    根据下面的 cmets,安全性似乎不是 OP 的主要关注点。相反,主要关注点是生成有效的查询。

    为此,最简单的解决方案可能是使用现有库,并让它们处理格式。例如,在Python 中有

    https://dev.mysql.com/doc/connector-python/en/

    为了提高效率,通常应该分批进行插入。但如果愿意,您可以编写一个用于插入行的脚本,例如

    python3 tableX_insert.py --field1 value1 --field2 value2
    

    我确信在其他语言中存在类似的 DB conn 和 cursor 模块。任何对原始 bash 命令行进行相同操作的努力都是在重新发明轮子。

    【讨论】:

    • 这不是面向用户的脚本。在我遇到的情况下,无论如何都有解决方法。不管怎样,这个问题需要一个答案。特别是,有理由使用与安全无关的参数化查询(分离数据和指令是非常好的做法)。关于这个网站上的其他问题,有一篇非常好的帖子,但我现在找不到。
    • 也许你可以解释你的问题的更多细节。当脚本不适合客户时,我不明白为什么安全是一个问题,因为可以进入服务器的用户被允许在那里。我认为他们的查询不应被视为“注入”。
    • 我已编辑问题以消除对安全性的关注。请参阅here 和同一作者here 的答案。但总结一下这个问题:我希望O'Connolly 是一个有效的输入,不会破坏查询或产生不利的副作用。
    • 这是一个我没有考虑过的更好的主意。我已经投了赞成票,但不会接受它,希望能有更好的答案(如果mysql 没有办法做到这一点,我会感到非常震惊)。无论如何,谢谢!
    【解决方案2】:

    您可以在 SQL 脚本中运行 PREPARE and EXECUTE 来执行参数化语句,但 bash 脚本的棘手部分是在 SQL 脚本中获取分配给会话变量的值,而不会引入 SQL 注入漏洞。

    我的意思是你可以这样做:

    myshellvar=1234
    mysql -e "set @myvar = $myshellvar ; prepare stmt from 'select ?'; execute stmt using @myvar"
    
    +------+
    | ?    |
    +------+
    | 1234 |
    +------+
    

    但这仍然容易受到 SQL 注入的影响,因为$myshellvar 可能包含麻烦的内容。

    我做了这个实验:

    echo "O'Reilly" > /tmp/name
    
    mysql -e "set @myvar = replace(load_file('/tmp/name'), '\n', ''); prepare stmt from 'select ?'; execute stmt using @myvar"
    +----------+
    | ?        |
    +----------+
    | O'Reilly |
    +----------+
    

    这是一种确保内容不会导致 SQL 注入的安全方法,但您需要一个配置为允许 load_file() 的 MySQL 实例,这似乎需要做很多工作,因为您需要创建您要加载的每个变量都有一个单独的文件。

    我同意@PMHui 的回答,如果您想方便地编写参数化 SQL 查询,您应该使用其他一些脚本语言。

    【讨论】:

    • 也谢谢你。这就是我一直在寻找的。​​span>
    • 我想明确一点,这只是一个概念证明,我不会使用这个解决方案。
    • 我不知道你可以在存储过程之外使用这些语句。
    • @Barmar,是的,仅在存储例程中有效的语句记录在手册中的 Compound Statement Syntax 部分中。 PREPARE/EXECUTE 在它前面的部分。
    猜你喜欢
    • 2017-08-30
    • 2010-12-11
    • 2021-05-23
    • 2010-12-22
    • 2010-10-27
    • 2020-04-28
    • 2010-11-05
    相关资源
    最近更新 更多