Будет ли это регулярное выражение ^ [^ \ s] + $ предотвращать внедрение SQL? если нет как обойти ограничение? - PullRequest
1 голос
/ 19 ноября 2009

используется для проверки ввода пользователя, например, имени пользователя, а не учетной записи.

Ответы [ 6 ]

6 голосов
/ 19 ноября 2009

Нет, ваше регулярное выражение вообще не поможет с внедрением SQL, извините. Давайте посмотрим на некоторые SQL-инъекции:

Сначала предположим, что вы создаете команды SQL в виде строк, например:
snprintf( sqlcommand, dimensionof(sqlcommand), "INSERT INTO users (username, password) VALUES ('%s', '%s')", username, password );

Проблема с внедрением SQL заключается в том, что пользователь может создать входное значение (в данном случае имя пользователя или пароль), которое заставит сгенерированную команду SQL сделать что-то другое, чем предполагалось. Например, если имя пользователя было «aardvark», «f»); DROP / ** / TABLE / ** / users; - », то сгенерированный оператор SQL будет выглядеть так:

INSERT INTO users (username, password) VALUES ('aardvark','f');DROP/**/TABLE/**/users;--', 'password_value')

Итак, вы пропустили своим регулярным выражением несколько моментов:

  • Обычный метод «выделения» из строки SQL включает неэкранированные символы одинарных кавычек.
  • / ** / - это разделитель, но не пробел.

А вам не следует исправлять это регулярное выражение . Как ответили другие, такой подход фильтрации входных данных опасен. По крайней мере, вы можете позвонить на mysql_real_escape_string(), рекомендованный Cletus.

Однако лучший ответ у Джиши и Марка Байерса: использовать параметризованные SQL-запросы, а не создавать SQL-запросы из строковых манипуляций. Этот подход безошибочен по сравнению с обработкой входных данных для экранирования необходимых символов.

Пожалуйста, примите ответы Джиши или Марка Байерса, так как они были самыми ранними и правильными.

6 голосов
/ 19 ноября 2009

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

Теперь вы можете ограничить количество символов (типа и / или числа) в именах пользователей, но это совершенно отдельная проблема. Или, по крайней мере, так и должно быть.

3 голосов
/ 19 ноября 2009

Никогда не используйте регулярные выражения для фильтрации строки SQL - вы потерпите неудачу. Вместо этого используйте подготовленные заявления. Вот пример использования PDO:

$sql = "
    SELECT * FROM users
    WHERE login = :l AND password = :p
";
$pdo = new PDO($dsn, $dbUser, $dbPassword);
$stmt = $pdo->prepare($sql);
$stmt->bindValue('l', $_POST['login']);
$stmt->bindValue('p', md5($_POST['password']));
$stmt->execute();
print_r($stmt->fetch());

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

Подробнее о PDO , подготовленные операторы и связанные значения на php.net.

3 голосов
/ 19 ноября 2009

Читайте на подготовленные заявления. Это один из лучших способов избежать SQL-инъекций. Поддерживается в mysqli для PHP и в ADO.NET.

3 голосов
/ 19 ноября 2009

Нет. Чтобы предотвратить внедрение SQL, не используйте строки для построения вашего запроса. Используйте параметры.

2 голосов
/ 19 ноября 2009

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

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

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