来自命令行的注入证明 SQL 语句
Injection Proof SQL Statements from Command Line
This related question询问在bash中使用命令行mysql
工具时使用参数化查询。但是,似乎顶部的答案仍然容易受到注入(例如; DROP TABLE user; --
)。虽然答案确实解决了如何完全传递变量的问题,但没有解决如何使用参数化查询传递变量的问题].
我的问题: 链接问题中的链接接受答案是否提供针对 SQL 注入的保护,并具有所有有用的参数化保护?如果是这样,为什么?如果没有,我如何才能安全地使用来自 MySQL 命令行工具的参数化查询?
注:技术上我是运行mysql Ver 15.1 Distrib 10.3.13-MariaDB
。
面向客户的应用程序的常见做法是为每个数据库查询提供一个 API 端点,这将需要用户身份验证。 API 服务器将在格式化查询时验证输入。
直接在服务器上公开 bash 从来都不是一个好主意。除了 SQL 注入,其他更糟糕的情况,如 ; scp ~/.ssh/id_rsa my_proxy ;
,也很容易发生。
根据以下评论,安全似乎不是 OP 的主要关注点。相反,主要重点是生成有效查询。
为此,最简单的解决方案可能是使用现有库,并让它们处理格式设置。例如,在 Python
中有
https://dev.mysql.com/doc/connector-python/en/
通常为了提高效率,应该批量插入。但如果愿意,您可以编写一个脚本来插入一行
python3 tableX_insert.py --field1 value1 --field2 value2
我确信在其他语言中存在用于 DB conn 和游标的类似模块。任何使用原始 bash 命令行做同样事情的努力都是在重新发明轮子。
您可以 运行 PREPARE and EXECUTE 在 SQL 脚本中执行参数化语句,但是 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 查询,您应该使用其他脚本语言。
This related question询问在bash中使用命令行mysql
工具时使用参数化查询。但是,似乎顶部的答案仍然容易受到注入(例如; DROP TABLE user; --
)。虽然答案确实解决了如何完全传递变量的问题,但没有解决如何使用参数化查询传递变量的问题].
我的问题: 链接问题中的链接接受答案是否提供针对 SQL 注入的保护,并具有所有有用的参数化保护?如果是这样,为什么?如果没有,我如何才能安全地使用来自 MySQL 命令行工具的参数化查询?
注:技术上我是运行mysql Ver 15.1 Distrib 10.3.13-MariaDB
。
面向客户的应用程序的常见做法是为每个数据库查询提供一个 API 端点,这将需要用户身份验证。 API 服务器将在格式化查询时验证输入。
直接在服务器上公开 bash 从来都不是一个好主意。除了 SQL 注入,其他更糟糕的情况,如 ; scp ~/.ssh/id_rsa my_proxy ;
,也很容易发生。
根据以下评论,安全似乎不是 OP 的主要关注点。相反,主要重点是生成有效查询。
为此,最简单的解决方案可能是使用现有库,并让它们处理格式设置。例如,在 Python
中有
https://dev.mysql.com/doc/connector-python/en/
通常为了提高效率,应该批量插入。但如果愿意,您可以编写一个脚本来插入一行
python3 tableX_insert.py --field1 value1 --field2 value2
我确信在其他语言中存在用于 DB conn 和游标的类似模块。任何使用原始 bash 命令行做同样事情的努力都是在重新发明轮子。
您可以 运行 PREPARE and EXECUTE 在 SQL 脚本中执行参数化语句,但是 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 查询,您应该使用其他脚本语言。