Резюме безопасности PHP, защита от инъекций SQL

база данных MySQL PHP SQL

Используйте Mysqli и PDO
причина

Основная причина в том, что некоторые данные не были строго проверены, а затем напрямую склеены SQL с запросом. привести к уязвимостям, таким как:

$id  = $_GET['id'];
$sql = "SELECT name FROM users WHERE id = $id";

Поскольку проверка типа данных для $_GET['id'] отсутствует, инжектор может отправлять данные любого типа, например небезопасные данные, такие как " и 1 = 1 или ". Будет безопаснее, если вы напишете это следующим образом.

$id  = intval($_GET['id']);
$sql = "SELECT name FROM users WHERE id = $id";

Преобразование id в тип int удаляет небезопасные вещи.

проверить данные

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

$id =intval( $_GET['id']);

Обработка символов более сложная.Во-первых, отформатируйте вывод с помощью функции sprintf, чтобы убедиться, что это строка. Затем удалите некоторые недопустимые символы с помощью некоторых функций безопасности, таких как:

$str = addslashes(sprintf("%s",$str));

//Вы также можете использовать функцию mysqli_real_escape_string вместо слешей, что будет безопаснее в будущем. Конечно, вы можете дополнительно оценить длину строки, чтобы предотвратить «атаки переполнения буфера», такие как:

$str = addslashes(sprintf("%s",$str)); 
$str = substr($str,0,40); //最大长度为40

параметризованная привязка

Параметризованная привязка, еще один барьер против SQL-инъекций. И php MySQLi, и PDO предоставляют такую ​​функциональность. Например, MySQLi может запрашивать так:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
$stmt->bind_param('sssd', $code, $language, $official, $percent);

PDO еще удобнее, например:

/* Execute a prepared statement by passing an array of values */
$sql = 'SELECT name, colour, calories  
FROM fruit
WHERE calories < :calories AND colour = :colour'; $sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
$sth->execute(array(':calories' => 175, ':colour' => 'yellow'));
$yellow = $sth->fetchAll();

Большинство из нас использует php-фреймворк для программирования, поэтому лучше не писать SQL самостоятельно, а запрашивать в соответствии с привязкой параметров, заданной фреймворком. Когда вы сталкиваетесь с более сложным оператором SQL, вы должны внимательно относиться к его написанию самостоятельно. Не используя PDO или MySQLi, вы также можете написать подготовленный, например, оператор запроса wordprss db, видно, что он прошел строгую проверку типа.

function prepare( $query, $args ) {
    if ( is_null( $query ) )
         return;
    // This is not meant to be foolproof -- 
           but it will catch obviously incorrect usage.
    if ( strpos( $query, '%' ) === false ) {
         _doing_it_wrong( 'wpdb::prepare' , 
         sprintf ( __( 'The query argument of %s
                 must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
   }
    $args = func_get_args();
    array_shift( $args );
    // If args were passed as an array (as in vsprintf), move them up
    if ( isset( $args[ 0] ) && is_array( $args[0]) )
         $args = $args [0];
    $query = str_replace( "'%s'", '%s' , $query ); 
        // in case someone mistakenly already singlequoted it
    $query = str_replace( '"%s"', '%s' , $query ); 
        // doublequote unquoting
    $query = preg_replace( '|(?<!%)%f|' , '%F' , $query ); 
        // Force floats to be locale unaware
    $query = preg_replace( '|(?<!%)%s|', "'%s'" , $query ); 
        // quote the strings, avoiding escaped strings like %%s
    array_walk( $args, array( $this, 'escape_by_ref' ) );
    return @ vsprintf( $query, $args );
}

Суммировать

Безопасность важна, вы также можете видеть, что база людей, уязвимость проекта, масштабируемость и ремонтопригодность также бесполезны. Обычно уделяйте больше внимания, устанавливайте осведомленность о безопасности, вырабатывайте привычку, некоторая базовая безопасность, конечно, не займет время кодирования. Выработайте эту привычку, даже если проект срочный, времени мало, оно все равно может быть высоким. Не ждите, пока сами за себя ответите, базу отнимут, в результате убытки. взаимное поощрение!

Хотя многие PHP-программисты в Китае по-прежнему полагаются на добавление слешей для предотвращения внедрения SQL, рекомендуется усилить проверку китайского языка для предотвращения внедрения SQL. Проблема с addlashes заключается в том, что хакеры могут использовать 0xbf27 вместо одинарных кавычек, но addlashes просто изменяет 0xbf27 на 0xbf5c27, чтобы он стал допустимым многобайтовым символом, в котором 0xbf5c по-прежнему будет рассматриваться как одинарная кавычка, поэтому addlashes не может быть успешно перехвачен.

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

Кроме того, для примера get_magic_quotes_gpc в руководстве по php:

if (!get_magic_quotes_gpc()) {  

    $lastname = addslashes($_POST[&lsquo;lastname&rsquo;]); 

} else {  

    $lastname = $_POST[&lsquo;lastname&rsquo;]; 

}

Лучше всего проверить $_POST['lastname'], если magic_quotes_gpc уже открыт.

Давайте поговорим о разнице между двумя функциями mysql_real_escape_string и mysql_escape_string: mysql_real_escape_string необходимо использовать в случае (PHP 4 >= 4.3.0, PHP 5). В противном случае можно использовать только mysql_escape_string.Разница между ними заключается в следующем: mysql_real_escape_string учитывает соединение

Текущий набор символов, который mysql_escape_string не учитывает.

В заключение:

  • addlashes() добавляется принудительно;
  • mysql_real_escape_string() будет оценивать набор символов, но есть требования к версии PHP;
  • mysql_escape_string не учитывает текущий набор символов соединения.

Конфигурация на стороне сервера
(1) Откройте безопасный режим php
Режим безопасности PHP — это очень важный встроенный механизм безопасности, который может управлять некоторыми функциями PHP, такими как system(),
В то же время права доступа контролируются для многих функций работы с файлами, а некоторые ключевые файлы запрещены, например, /etc/passwd,
Но дефолтный php.ini не открывает безопасный режим, открываем его:
safe_mode = on

(2) Безопасность группы пользователей
Когда safe_mode включен, safe_mode_gid выключен, тогда php-скрипт может получить доступ к файлу, и то же самое
Пользователи группы также могут получать доступ к файлам.

Рекомендуемые настройки:

safe_mode_gid = off

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

(3) Выполнение основного каталога программы в безопасном режиме Если безопасный режим включен, но когда вы хотите выполнить некоторые программы, вы можете указать основной каталог программы, которая будет выполняться:

safe_mode_exec_dir = D:/usr/bin

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

safe_mode_exec_dir = D:/tmp/cmd

Однако я предпочитаю не запускать никакую программу, тогда вы можете указать на наш веб-каталог:

safe_mode_exec_dir = D:/usr/www

(4) Включить файлы в безопасном режиме. Если вы хотите включить некоторые общедоступные файлы в безопасный режим, измените параметры:

safe_mode_include_dir = D:/usr/www/include/

На самом деле файлы, входящие в общий php-скрипт, уже прописаны в самой программе, что можно настроить под конкретные нужды.

(5) Управляйте каталогом, к которому может получить доступ php-скрипт
Используйте параметр open_basedir, чтобы управлять PHP-скриптом только для доступа к указанному каталогу, что позволяет избежать доступа к PHP-скрипту.
Файлы, которые не должны обращаться к доступу, должны иметь ограниченный PHPHELL в определенной степени, мы обычно можем быть установлены только для доступа только к каталогу веб-сайта:

open_basedir = D:/usr/www

(6) Отключить опасные функции
Если включен безопасный режим, то запрет функции излишен, но мы все же считаем его для безопасности. Например,
Мы не хотим выполнять функции php, которые могут выполнять команды, включая system() и т. д., или могут просматривать информацию php.
phpinfo() и другие функции, то их можно отключить:

disable_functions = system,passthru,exec,shell_exec,popen,phpinfo

Если вы хотите запретить любые операции с файлами и каталогами, вы можете отключить многие операции с файлами.

disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir, rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown

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

(7) Закройте утечку информации о версии PHP в заголовке http Чтобы предотвратить получение хакерами информации о версии PHP на сервере, мы можем закрыть информационный пандус в заголовке http:

expose_php = Off

Например, когда хакеры используют telnet www.12345.com 80, они не смогут увидеть информацию PHP.

(8) Тесная регистрация глобальных переменных
Переменные, отправленные в PHP, включая переменные, отправленные с помощью POST или GET, будут автоматически зарегистрированы как глобальные переменные, и к ним можно будет получить прямой доступ.
Это очень небезопасно для сервера, поэтому мы не можем зарегистрировать его как глобальную переменную, поэтому отключите опцию регистрации глобальной переменной:

register_globals = Off

Конечно, если это установлено, то следует использовать разумный метод для получения соответствующей переменной. Например, чтобы получить переменную var, представленную GET, для ее получения следует использовать $_GET['var']. программист должен обратить внимание.

(9) Включите magic_quotes_gpc, чтобы предотвратить внедрение SQL.
SQL-инъекция — очень опасная проблема: в небольших случаях происходит вторжение в серверную часть веб-сайта, а в серьезных случаях скомпрометирован весь сервер.
Так что будьте осторожны. В php.ini есть настройка:

magic_quotes_gpc = Off

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

magic_quotes_gpc = On

(10) Управление сообщениями об ошибках
Как правило, php выдает ошибку, когда он не подключен к базе данных или в других ситуациях.Как правило, сообщение об ошибке будет содержать php-скрипт, когда
Такая информация, как предыдущая информация о пути или оператор запроса SQL и т. Д., После того, как такая информация предоставляется хакеру, небезопасна, поэтому общий сервер рекомендует запретить сообщение об ошибке:

display_errors = Off

Если вы хотите отображать сообщения об ошибках, обязательно установите уровень отображения ошибок, например, отображать только сообщения выше предупреждений:

error_reporting = E_WARNING & E_ERROR

Конечно, я все же рекомендую отключить подсказку об ошибке.

(11) Журнал ошибок предполагает, что информацию об ошибке можно записать после отключения display_errors, чтобы найти причину, по которой работает сервер:

log_errors = On

При этом необходимо задать каталог, в котором хранится лог ошибок.Рекомендуется, чтобы логи корневого апача существовали вместе:

error_log = D:/usr/local/apache2/logs/php_error.log

Примечание. Пользователь и группа Apache должны иметь права на запись в файл.

Операция понижения версии MYSQL для создания нового пользователя, такого как mysqlstart

net user mysqlstart fuckmicrosoft /add
net localgroup users mysqlstart /del

не принадлежит ни к одной группе
Если MYSQL установлен в d:mysql, дайте mysqlstart права на полный доступ
Затем задайте в системном сервисе свойства сервиса MYSQL, в свойствах входа выберите пользователя mysqlstart и введите пароль, ОК.
Перезапустите службу MYSQL, после чего MYSQL запустится с низкими привилегиями.
Если апач собран под платформу виндос, то надо еще обратить внимание на то, что апач по умолчанию работает с системными разрешениями.
Это ужасно, и это заставляет людей чувствовать себя очень некомфортно. Тогда давайте понизим разрешения для apache.

net user apache fuckmicrosoft /add
net localgroup users apache /del

хорошо Мы создали пользовательский apche, который не принадлежит ни к одной группе.
Открываем диспетчер компьютеров, выбираем службу, нажимаем свойства службы апача, выбираем вход в систему, выбираем эту учетную запись, заполняем созданную выше учетную запись и пароль,
Перезапустите службу apache, хорошо, apache работает с низкими привилегиями.
Фактически, мы также можем установить разрешения для каждой папки, чтобы пользователь apache мог делать только то, что мы хотим, и создать отдельного пользователя для чтения и записи для каждого каталога.
В настоящее время это также популярный метод настройки для многих провайдеров виртуального хостинга, но этот метод используется для того, чтобы он не был излишним.