Получить таблицу с подготовленным оператором, используя пользовательский ввод

0

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

Значение GET форматируется как строка (например: nmcxxwakfe) и первоначально динамически генерируется, поэтому нет возможности разрешать только определенные значения.

try {
$db = new PDO("mysql:dbname=somedb;host=localhost", "person", "mysupersecretpw" );

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );//Error Handling

$sql = "SELECT * FROM $value";
$result = $db->prepare($sql);
$result->execute();
$daten = $result->fetchAll();
} catch(PDOException $e) {
echo $e->getMessage();//Remove or change message in production code
}

Спасибо за помощь!

  • 0
    Что такое $value ? Если это несуществующая переменная или пустая, то вы отправляете DB SELECT * FROM , что действительно синтаксически неверно. Посмотрите, что содержит $sql (например, с echo ) перед отправкой в $db->prepare() .
  • 0
    if (isset ($ _ GET ['id'])) {$ value = $ _GET ['id']; } Мой оригинальный код работает, но это небезопасная реализация, и я хочу сделать его более безопасным.
Показать ещё 8 комментариев
Теги:
input
pdo

1 ответ

0
Лучший ответ

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

Итак, как бы вы подтвердили правильность принятой таблицы? Белый список. Возможны два подхода:

  1. Жесткий код: список допустимых таблиц в вашем скрипте:

    $validTableNames = ['somename', 'othertablename', 'stattable'];

  2. Динамически получить их из БД:

    $sql = "SELECT table_name FROM information_schema.tables where table_schema = '<your_database_name>'"
    $validTableNames = [];
    foreach ( $db->query( $sql ) as $row )
        $validTableNames[] = $row['table_name'];
    

И затем подтвердите, что переданный вход является допустимым именем:

if ( ! in_array($_GET['id'], $validTableNames) ) {
    // the passed table name is not valid.  Do what you will ...
}
  • 0
    Мне нравится прагматичный подход! Оно работает; благодарю вас! ^^ Кстати: если вы знаете о еще более безопасном методе, было бы неплохо знать.
  • 0
    @Landstalker security - это редко флажок, и чаще всего вопрос состоит в том, чтобы сделать его слишком дорогим для взломщика («Не стоит моего времени!»). С вашим надуманным сценарием, это примерно так же хорошо, как вы собираетесь получить. Когда вы добавляете больше сложности и больше переменных, мы можем говорить о разных подходах, но для поставленного вопроса, я сомневаюсь, вы найдете намного лучше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню