Существует ли риск для безопасности при отображении имен таблиц MySQL в javascript?

#php #javascript #mysql #security

#php #javascript #mysql #Безопасность

Вопрос:

У меня есть метод ajax, который, по сути, работает следующим образом

 function getRow(tableName, idName, idValue, callback)
  

Очевидным преимуществом этого является то, что у меня есть одна функция, которая может извлекать данные из любой таблицы. Однако это просто кажется неправильным с точки зрения безопасности, является ли это риском для безопасности? Соответствующие PHP-файлы, которые фактически читают базу данных / управляют ею, защищены с помощью предварительного процесса аутентификации, поэтому теоретически видимость имен таблиц в вакууме не должна представлять риска (не говоря уже о том, что база данных принимает только подключения к localhost), но мне интересно, нет ли лучшего способа добиться этого.

Редактировать: просто чтобы прояснить процесс аутентификации, безопасность пользователя / роли запрещает доступ ко всем таблицам, кроме тех, которые явно разрешены пользователю.

Комментарии:

1. Что, если я вызову эту функцию с syscolumns в качестве параметра?

Ответ №1:

Если вы уверены, что у вас нет уязвимостей для SQL-инъекций и что у вас никогда не будет, все в порядке.

Если у вас действительно есть уязвимость SQL-инъекции, это несколько облегчит работу злоумышленника.

Само собой разумеется (я надеюсь), что серверный скрипт должен использовать белый список таблиц и столбцов, которые могут быть представлены с помощью этого метода.

Комментарии:

1. Мне это нравится, несколько проще, потому что если у вас есть уязвимость при внедрении SQL, то найти имена таблиц несложно.

2. @mcdonald: Если вы не можете получить какие-либо выходные данные из-за уязвимости, это немного упрощает задачу.

3. 1, я согласен с @SLaks. Однако (просто мысль), знание имен таблиц, я думаю, немного упрощает для них задачу. Что я обычно делаю, просто потому, что мне не нравится, когда люди что-то знают о том, что у меня есть в фоновом режиме (т. Е. Таблицы, базы данных, файлы и т.д.), я обычно использую XOR для имен моих таблиц и файлов. Это не предназначено для того, чтобы «остановить» или «Помешать» людям разобраться в этом, но это немного усложняет для обычного человека определение используемых имен. Но вы, вероятно, не хотите дополнительных накладных расходов, связанных с необходимостью XOR имен.

4. @JTS: Если вы делаете это, вы могли бы также использовать жестко запрограммированный поиск от имен таблиц до случайных строк на сервере, чтобы клиент никогда не видел никаких реальных имен.

Ответ №2:

Сами по себе имена таблиц не так уж плохи, однако API, который вы, похоже, создаете, может быть не лучшей идеей…

Тщательно подумайте, есть ли какие-то таблицы, к которым люди не должны иметь возможности запрашивать, потому что, судя по всему, я мог бы запросить любую таблицу в вашей базе данных со стороны клиента. Например:

 getRow('users', 'id', '7', function(data){console.log(data)})
  

Что, если таблица users вернет их пароль? даже если это хэшировано, это нехорошо. Или их электронной почты? Что, если я хочу получить все электронные письма пользователей? Для этого я мог бы написать довольно простой скрипт.

Комментарии:

1. Я надеюсь , что это то, что он подразумевает под аутентификацией на стороне сервера.

2. Точно, надеюсь, аутентификация не остановится на «могу выполнить запрос!»

Ответ №3:

Это риск, потому что он предоставляет информацию злоумышленникам. Это то же самое, что предоставлять версию программного обеспечения, которое вы используете. Это не уязвимость как таковая, но это путь к уязвимостям.

Ответ №4:

Это действительно плохая идея.

Допустим, например, вы используете этот код:

 $table_name=mysql_real_escape_string($_GET['table']);
$id_name=mysql_real_escape_string($_GET['idname']);
$id_value=mysql_real_escape_string($_GET['idvalue']);

mysql_query("select * from `$table_name` where `$id_name`='$id_value'");
  

Это можно использовать несколькими способами:

НЕ SQL-инъекция

Этот запрос вернет пользователя root в mysql.user , и это

?table=mysql.useramp;idname=useramp;idvalue=root Этот запрос создаст запрос:

select * from mysql.user where пользователь ='root'

Внедрение SQL:

Это работает, потому что mysql_real_escpae_string не экранирует обратные галочки:`

 ?table=`table where 1 union select * from mysql.user/*amp;idname=junkamp;idvalue=junk
  

Комментарии:

1. Да, но имя таблицы MySQL может содержать только w символы, если я не ошибаюсь. Но входные данные должны быть проверены.

2. @webarto не раскрывать подобную функциональность просто глупо. Вы могли бы получить хэш пароля для другого пользователя в той же БД без необходимости ставить точку.

Ответ №5:

Вы можете показать, например, users имя таблицы в JS, но на стороне сервера добавьте префикс like forum_users , который будет фактическим именем таблицы в базе данных. Таким образом, если кто-то найдет точку внедрения, он попытается DROP TABLE users и запрос завершится неудачей, если вам повезет 🙂

Также добавьте белый / черный список для таблиц и столбцов, добавьте ОГРАНИЧЕНИЕ 1 (не зацикливаться), не возвращайте несколько массивов, и вам следует выполнить очистку с помощью чего-то вроде этого.

 $select = preg_replace("#[w]#", "", $_GET["select"]);
$from = preg_replace("#[w]#", "", $_GET["from"]);
$where = preg_replace("#[w]#", "", $_GET["where"]);
$equals = mysql_real_escape_string($_GET["equals"]);

$query = "SELECT $select FROM $from WHERE $where = '$equals' LIMIT 1";
  

Ответ №6:

Конечно, для особых случаев следует использовать прямой API базы данных на стороне клиента. Но вы можете легко защитить это с помощью белого списка. Например, в PHP:

 if (in_array($tableName, array("users", "log", "messages", ...))) {
  

Так что я не думаю, что это такая уж большая проблема с точки зрения безопасности, пока у вас есть фиксированный список здесь.