Есть ли риск безопасности при представлении имен таблиц MySQL в javascript?

У меня есть метод ajax, который в настоящее время работает как

function getRow(tableName, idName, idValue, callback)

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

Также добавьте белый/черный список для таблиц и столбцов, добавьте LIMIT 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";

Ответ 4

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

Ответ 5

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

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

$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.user&idname=user&idvalue=root Этот запрос создаст запрос:

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

SQL Injection:

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

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

Ответ 6

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

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

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