问题
This related question asks about using a parameterized query when using the commandline mysql tool in bash. However, it seems that the top answer is still vulnerable to injection (eg ; DROP TABLE user; --). While the answer certainly does address the question of how to pass in variables at all, it does not address the question of how to do it using parameterized queries.
My question: Does the linked accepted answer in the linked question provide protection against SQL injection, and have all the useful protections of paramterization? If so, why? If not, how can I securely use a parameterized query from the MySQL command line tool?
Note: Technically I am running mysql Ver 15.1 Distrib 10.3.13-MariaDB.
回答1:
Common practice for customer-facing applications is to have an API-endpoint for each database query, which will require user authentication. The API server will then validate the input while formatting the query.
Directly exposing bash on server is never a good idea. Besides SQL injection, other much worse situations, like ; scp ~/.ssh/id_rsa my_proxy ;, can easily happen.
It appears that security is not OP's primary concern based on the comments below. Rather, the main focus is generating valid queries.
For that, the simplest solution is to perhaps use existing libraries, and let them handle the formatting. For example, in Python there is
https://dev.mysql.com/doc/connector-python/en/
Usually insertion should be done in batch for efficiency. But if preferred, you can write a script for inserting a row like
python3 tableX_insert.py --field1 value1 --field2 value2
I am sure in other languages similar modules for DB conn and cursor exist. Any effort to do the same with raw bash command line is re-inventing wheels.
回答2:
You can run PREPARE and EXECUTE in an SQL script to do parameterized statements, but then the tricky part for a bash script is to get values assigned to session variables in the SQL script without introducing an SQL injection vulnerability.
I mean you can do this:
myshellvar=1234
mysql -e "set @myvar = $myshellvar ; prepare stmt from 'select ?'; execute stmt using @myvar"
+------+
| ? |
+------+
| 1234 |
+------+
But that's still vulnerable to SQL injection, because $myshellvar could contain troublesome content.
I did this experiment:
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 |
+----------+
That's a safe way to ensure the content doesn't cause SQL injection, but you'd need a MySQL instance that is configured to allow load_file(), and it seems like a lot of work because you'd need to create a separate file for each variable you want to load.
I agree with @PMHui's answer that you should use some other scripting language if you want to write parameterized SQL queries conveniently.
来源:https://stackoverflow.com/questions/55374938/injection-proof-sql-statements-from-command-line