This related question询问在bash中使用命令行mysql
工具时如何使用参数化查询。但是,似乎最高的答案仍然容易受到注入的影响(例如; DROP TABLE user; --
)。虽然答案确实确实解决了如何传入变量 的问题,但并未解决如何使用参数化查询的问题。
我的问题:链接问题中的链接接受答案是否提供了防止SQL注入的保护,并且具有所有有用的参数化保护?如果是这样,为什么?如果没有,如何从MySQL命令行工具安全地使用参数化查询?
注意:从技术上讲,我正在运行mysql Ver 15.1 Distrib 10.3.13-MariaDB
。
答案 0 :(得分:3)
面向客户的应用程序的常见做法是为每个数据库查询都有一个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和cursor的类似模块。对原始bash命令行执行相同操作的任何努力都是重新发明轮子。
答案 1 :(得分:1)
您可以在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查询,则应使用其他脚本语言。