PHP - добавить новый столбец с заполнителем MS SQL, предотвращающим SQL-инъекцию - PullRequest
0 голосов
/ 23 ноября 2018

Я работаю над приложением PHP, основанным на MS SQL, которое, помимо прочего, может добавить столбец в таблицу, либо bit, int, либо varchar.Мой текущий код похож на это:

$sql = "ALTER TABLE myTable ADD ? ".$type;
$values = array($columnname);
if($type == "varchar")
    $sql = $sql."(".$length.")";
$sql = $sql.";";
sqlsrv_query($conn, $sql, $values);

Однако я получаю только ошибку, которая говорит мне, что неправильный синтаксис рядом с '@ P1'.Я думал о вставке имени столбца в строку напрямую, но боюсь SQL-инъекций, так как это ввод текста.Меня беспокоит не столько тип и длина, сколько выбор и ввод числа.

Я надеюсь, что один из вас может дать мне несколько советов о том, как добавить столбец, не подвергая себя опасности.в SQL-инъекцию.Заранее спасибо!

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

1 Ответ

0 голосов
/ 24 ноября 2018

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

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

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

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

$columnname = str_replace("]", "]]", $columnname);
$sql = "ALTER TABLE myTable ADD [$columnname] $type";

MS SQL Server использует квадратные скобки для разделения идентификатора, который может содержать специальные символы.Str_replace () на всякий случай, если само имя столбца содержит квадратные скобки.Прочитайте https://sqlsunday.com/2014/09/21/identifiers-in-tsql/ для более подробного объяснения.

А как насчет $ type?Как мы можем убедиться, что это безопасно?Другая техника - , белый список .Чтобы сделать $ type безопасным, вам нужно проверить его по списку допустимых значений.

switch ($type) {
case "int":
  // OK, nothing to change
  break;
case "varchar":
  $type = "varchar($length)"
  break;
// ...add cases for other allowed types...
default:
  die("Unrecognized type: $type");
}

Вы можете либо умереть с ошибкой в ​​предложении default, либо вы можете установить $type вразумный дефолт.Зависит от того, как вы хотите с этим справиться.

Вы можете спросить, Зачем столько кода?Почему это не может быть проще?

Потому что вам требуется, чтобы программное обеспечение делало что-то динамичное.Вы пытаетесь заставить код делать правильные вещи независимо от того, что вводит пользователь.Если вам не нужно поддерживать пользовательский ввод, вы можете сделать имя и тип столбца фиксированными, и тогда все будет просто.

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