Intereting Posts
PDO Невозможно выполнить запросы, в то время как другие небуферизованные запросы активны Соединение NSURLConnection с сервером, но не размещение данных API Карт Google v3: как установить уровень масштабирования и центр карты в отправленное пользователем местоположение? Как получить идентификатор заказа в woocommerce_email_headers JS <—> Связь с PHP получение ошибки при попытке использовать созданное мной пространство имен Echo 'string', в то время как каждая итерация длинного цикла (flush () не работает) Неизвестное имя столбца при импорте таблицы Как отобразить DOMElement? Существует ли рациональное объяснение этого поведения PHP по поведению? Или PHP ошибка? получение автозаполнения jquery для передачи элемента в другое поле при выборе Дата PHP добавляет 1 год к текущей дате Вызов функции PHP каждую секунду Загрузка изображения ajax не работает Переместить массив в массив в родительский массив php

База данных PHP / SQL, запрашивающая передовую практику и безопасность

Поэтому я немного опытный разработчик php и с тех пор «делал эту чертову»; Тем не менее, я все еще отношусь к n00bish, когда речь заходит о защите моих приложений. В том, что я действительно не знаю всего, что знаю, могу и должен.

Я взял Securing PHP Web Applications и читаю свой путь через это, проверяя вещи на этом пути. У меня есть некоторые вопросы для общей группы SO, которые относятся к запросу базы данных (в основном в mysql):

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

Может ли кто-нибудь объяснить хранимые процедуры и подготовленные операторы немного больше информации, чем: вы делаете их и звоните им. Я хотел бы знать, как они работают, что валидация продолжается за кулисами.

Я работаю в среде, связанной с php4, и php5 пока не является опцией. Кто-нибудь еще был в этом положении раньше, что вы сделали, чтобы защитить свои приложения, в то время как все классные дети используют этот сладкий новый интерфейс mysqli?

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

Примечание. У нас не было ничего похожего на поиск, который попал в систему безопасности php-mysql.

Мои рекомендации:

  1. ditch mysqli в пользу PDO (с драйвером mysql)
  2. использование подготовленных заявлений PDO с использованием paremeterized

Затем вы можете сделать что-то вроде:

$pdo_obj = new PDO( 'mysql:server=localhost; dbname=mydatabase', $dbusername, $dbpassword ); $sql = 'SELECT column FROM table WHERE condition=:condition'; $params = array( ':condition' => 1 ); $statement = $pdo_obj->prepare( $sql, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ) ); $statement->execute( $params ); $result = $statement->fetchAll( PDO::FETCH_ASSOC ); 

PROs:

  1. Больше нет ручного экранирования, поскольку PDO делает все для вас!
  2. Внезапно можно легко переключить базы данных.

Недостатки:

  • я не могу думать ни о чем.

Ответ Хавьера, который имеет ссылку на овас, – хорошее начало.

Есть еще несколько вещей, которые вы можете сделать больше:

  1. Что касается атак SQL-инъекций, вы можете написать функцию, которая будет удалять общие инструкции SQL из ввода типа «DROP» или «DELETE * WHERE», например:

    * $ sqlarray = array ("DROP", "или 1 = 1", "union select", "SELECT * FROM", "select host", "create table", "FROM users", "users WHERE"); *

    Затем напишите функцию, которая будет проверять ваш ввод против этого массива. Убедитесь, что какой-либо материал внутри $ sqlarray не будет распространяться среди ваших пользователей. (Не забудьте использовать strtolower на этом, спасибо lou).

  2. Я не уверен, что memcache работает с PHP 4, но вы можете создать некоторую защиту от спама с помощью memcache, разрешив только определенный удаленный доступ к IP-адресу на странице process.php X раз в Y-период.

  3. Привилегии важны. Если вам нужны только привилегии вставки (скажем, обработка заказов), вы должны войти в базу данных на странице процесса заказа с пользователем, который имеет только вставку и, возможно, выбор привилегий. Это означает, что даже если SQL-инъекция прошла, они могут выполнять только запросы INSERT / SELECT, а не удалять или реструктурировать.

  4. Поместите важные файлы обработки php в каталог, например / include. Затем запретите доступ всех IP-адресов к этому каталогу / include.

  5. Поместите соленое MD5 с помощью агента пользователя + remoteip + your salt в сеанс пользователя и убедитесь, что на каждой загрузке страницы проверяется, что правильный MD5 находится в их файле cookie.

  6. Отключите определенные заголовки ( http://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST ). Disallow PUT (Если вам не нужны файлы) / TRACE / CONNECT / DELETE заголовки.

Обычно я не работаю с PHP, поэтому я не могу предоставить рекомендации, специально предназначенные для ваших требований, но я предлагаю вам взглянуть на страницу OWASP, особенно в 10 самых популярных уязвимостей: http://www.owasp.org /index.php/Top_10_2007

На этой странице для каждой уязвимости вы получаете список вещей, которые вы можете сделать, чтобы избежать проблемы на разных платформах (.NET, Java, PHP и т. Д.).

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

AFAIK, PHP / mySQL обычно не имеют параметризованных запросов.

Использование sprintf() с mysql_real_escape_string() должно работать очень хорошо. Если вы используете соответствующие строки форматирования для sprintf() (например, «% d» для целых чисел), вы должны быть довольно безопасными.

Возможно, я ошибаюсь, но не должно быть достаточно использовать mysql_real_escape_string для предоставленных пользователем данных?

если они не являются числами, и в этом случае вы должны убедиться, что они фактически являются числами, используя, например, ctype_digit или is_numeric или sprintf (используя %d или %u для ввода ввода в число).

Кроме того, наличие serarate-пользователя mysql для ваших php-скриптов, которые могут только SELECT, INSERT, UPDATE и DELETE, вероятно, хорошая идея …


Пример из php.net

Пример №3 Запрос «Лучшая практика»

Использование mysql_real_escape_string () вокруг каждой переменной предотвращает SQL Injection. В этом примере демонстрируется метод «лучшей практики» для запроса базы данных, независимо от настройки «Волшебные кавычки».

Теперь запрос будет выполнен правильно, а атаки SQL Injection не будут работать.

  <?php if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) { // Connect $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password'); if(!is_resource($link)) { echo "Failed to connect to the server\n"; // ... log the error properly } else { // Reverse magic_quotes_gpc/magic_quotes_sybase effects on those vars if ON. if(get_magic_quotes_gpc()) { $product_name = stripslashes($_POST['product_name']); $product_description = stripslashes($_POST['product_description']); } else { $product_name = $_POST['product_name']; $product_description = $_POST['product_description']; } // Make a safe query $query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)", mysql_real_escape_string($product_name, $link), mysql_real_escape_string($product_description, $link), $_POST['user_id']); mysql_query($query, $link); if (mysql_affected_rows($link) > 0) { echo "Product inserted\n"; } } } else { echo "Fill the form properly\n"; } 

Используйте хранимые процедуры для любой активности, которая включает в себя привязку к БД, и используйте параметры привязки для всех выборок.