Экранирование командных строк MYSQL через Bash Scripting - PullRequest
15 голосов
/ 08 декабря 2010

PHP имеет mysql_real_escape_string() для правильного экранирования любых символов, которые могут вызвать проблемы.Каков наилучший способ имитировать эту функциональность для BASH?

Есть ли способ подготовить операторы mysql, используя bash?Кажется, это лучший способ.

Большинство моих переменных не будут (не должны) иметь специальные символы, однако я даю пользователю полную свободу для их пароля.Он может включать такие символы, как 'и ".

Возможно, я делаю несколько операторов SQL, поэтому я хочу создать сценарий, который принимает параметры, а затем выполняет оператор. Это то, что я до сих пор:

doSQL.sh:

#!/bin/sh

SQLUSER="root"
SQLPASS="passwor339c"
SQLHOST="localhost"

SQL="$1"
SQLDB="$2"


if [ -z "$SQL" ]; then echo "ERROR: SQL not defined"; exit 1; fi
if [ -z "$SQLDB" ]; then SQLDB="records"; fi

echo "$SQL" | mysql -u$SQLUSER -p$SQLPASS -h$SQLHOST $SQLDB

и пример с использованием указанной команды:

example.sh:

PASSWORD=$1
doSQL "INSERT INTO active_records (password) VALUES ('$PASSWORD')"

Очевидно, что это не получится, еслипароль пароль содержит одну кавычку.

Ответы [ 5 ]

11 голосов
/ 08 декабря 2010

В Bash printf может сделать экранирование для вас:

$ a=''\''"\;:#[]{}()|&^$@!?, .<>abc123'
$ printf -v var "%q" "$a"
$ echo "$var"
\'\"\\\;:#\[\]\{\}\(\)\|\&\^\$@\!\?\,\ .\<\>abc123

Я оставлю вам решать, достаточно ли это агрессивно.

4 голосов
/ 08 декабря 2010

Это похоже на классический случай использования неподходящего инструмента для работы.

У вас есть лот работы, которую предстоит выполнить для реализации экранирования, выполненного mysql_real_escape_string()в баш.Обратите внимание, что mysql_real_escape_string() фактически делегирует экранирование библиотеке MySQL, которая учитывает наборы символов соединения и базы данных.Он называется «реальным», потому что его предшественник mysql_escape_string() не принимал во внимание набор символов, и его можно было бы обмануть, чтобы ввести SQL.

Я бы предложил использовать язык сценариев с библиотекой MySQL, такой какRuby, Python или PHP.

Если вы настаиваете на bash, используйте синтаксис Подготовленные операторы MySQL *1013*.

2 голосов
/ 20 февраля 2015

mysql_real_escape_string(), конечно, экранирует только один строковый литерал в кавычках, а не целый оператор. Вам должно быть понятно, для какой цели строка будет использоваться в выражении. В соответствии с разделом руководства MySQL о строковых литералах , для вставки в строковое поле вам нужно только экранировать одинарные и двойные кавычки, обратную косую черту и NUL. Однако строка bash не может содержать NUL, поэтому должно быть достаточно следующего:

#escape for MySQL single string
PASSWORD=${PASSWORD//\\/\\\\}
PASSWORD=${PASSWORD//\'/\\\'}
PASSWORD=${PASSWORD//\"/\\\"}

Если вы будете использовать строку после LIKE, возможно, вы захотите экранировать % и _.

Подготовленные заявления являются еще одной возможностью. И убедитесь, что вы не используете echo -e в вашем bash.

См. Также https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

0 голосов
/ 02 декабря 2017

Это будет работать:

echo "John O'hara"  | php -R 'echo addslashes($argn);'

Чтобы передать его в переменную:

name=$(echo "John O'hara"  | php -R 'echo addslashes($argn);')
0 голосов
/ 08 декабря 2010

Это исключит апострофы

a=$(echo "$1" | sed s/"'"/"\\\'"/g)

Обратите внимание, что mysql_real_escape_string также экранирует \ x00, \ n, \ r, \, "и \ x1a. Обязательно избегайте их для полной безопасности.

Чтобы избежать \ x00, например:

a=$(echo "$1" | sed s/"\x00"/"\\\'"/g)

С небольшим усилием вы, вероятно, сможете избежать их, используя одну команду sed.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...