Безопасность и PHP

✅ Смотрим список активных модулей:
# php -m
Отключаем ненужные:
# mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable

✅ Отключаем отображение информации о версии PHP:
expose_php=Off
Это параметр для php.ini.

✅ Отключаем отображение ошибок PHP для посетителей:
display_errors=Off
Вместо этого логируем их отдельно:
log_errors=On
error_log=/var/log/httpd/php_scripts_error.log

✅ Если не нужна загрузка файлов на веб сервер, отключите эту возможность:
file_uploads=Off
Если загрузка нужна, то хотя бы ограничьте максимальный размер файла до необходимого предела:
file_uploads=On
upload_max_filesize=10M

✅ Отключаем функцию allow_url_fopen, если не используются сайтом. Она открывает широкие возможности для взлома, если разработчики забудут о фильтрации входящих данных.
allow_url_fopen=Off

✅ Настройка размера POST запросов. Этот параметр должен быть не меньше upload_max_filesize, если разрешена загрузка файлов. Если же она запрещена, то большой разрешённый размер post запросов не нужен. Вряд ли вам через формы потребуется заливать большой объём данных.
post_max_size=10M
или
post_max_size=10K

✅ Подобрать необходимые лимиты выполнения скриптов. Тут всё сильно зависит от самого сайта. В идеале, много ресурсов не выделять, но, к примеру, тот же Bitrix, требует очень много оперативной памяти и времени выполнения для своих скриптов.
max_execution_time = 30
max_input_time = 30
memory_limit = 64M

✅ Отключаем потенциально опасные функции PHP. Оставляем только то, что реально нужно.
disable_functions = exec,passthru,shell_exec,system,
proc_open,popen,curl_exec,curl_multi_exec,
parse_ini_file,show_source

✅ Убедиться, что параметр cgi.force_redirect не отключен принудительно. По дефолту, если его явно не указать, то он будет включен.
cgi.force_redirect=On

✅ Убедиться, что php работает от отдельного непривилегированного пользователя. Настройка будет зависеть от используемого менеджера процессов php. Проверяем примерно так:
# ps aux | grep php

✅ Ограничиваем доступ php к файловой системе:
open_basedir = «/var/www/html/»

✅ Настраиваем место хранения для сессий:
session.save_path = «/var/lib/php/session»
Важно убедиться, что туда нет доступа посторонним. Кроме веб сервера эта директория никому не нужна. Также туда не должно быть доступа с сайта.

Suhosin позволяет бороться с SQL-инъекциями (SQL injections), атаками на переполнение буфера, с отправкой спама через некачественно написанные скрипты, с воровством cookie и т.д. В некоторых случаях может вызывать проблемы, поэтому использовать осторожно. Возможно стоит сразу прописать в /etc/php5/apache2/conf.d/suhosin.ini значение suhosin.get.max_value_length = 4096

Если требуется передавать параметры suhosin через .htaccess то надо сделать следующее:

  • Изменить в файле /etc/php5/conf.d/suhosin.ini параметр suhosin.perdir на
    suhosin.perdir = "p"
  • Прописать в конфиге Апача для сайта или папки параметр
    AllowOverride All
  • Добавить в .htaccess необходимые параметры, например
    suhosin.post.max_vars = 2048
    suhosin.request.max_vars = 2048
  • Отключаем выполнение некоторых функций:
    • disable_function=«exec, system, passthru, shell_exec, proc_open»
  • Те самые параметры о которых везде понаписано много буковок:
    • magic_quotes_gpc = 1
    • safe_mode = 0
    • register_globals = 0
  • Нет, ничего подключать не будем:
    • allow_url_fopen = Off
    • allow_url_include = Off
  • Никому не надо знать что за ошибки возникают, а если нужно - посмотрим логи
    • display_errors = Off
    • display_startup_errors = Off
    • log_errors = On
    • error_log = php_error.log
  • Запираем php в определенных папках:
    • open_basedir=/var/www/you_mega_site.com:/tmp
  • Можно спрятать информацию о версии PHP:
    • expose_php = Off

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

В некоторых случаях требуется запретить использование некоторых функций через disable_functions и сделать индивидуальные настройки для определенных виртуальных хостов. Ан нет, disable_functions работает только из php.ini. Пр попытке включить конструкцию php_admin_value в .htaccess получаем сообщение « php_admin_value not allowed here», а попытки сделать это через конфиги Apache так же не дают эффекта: получаем ошибку «PHP Warning: exec() has been disabled for security reasons in…»

Как оказалось, победить можно, но при условии использования на сервере suhosin. Сборка php5-suhosin 0.9.29-1ubuntu1 старая, я пересобрал руками 0.9.33.

Итак, делаем:

  • В php.ini устанавливаем
disable_functions = 
  • В suhosin.ini (а если такого нет, то в php.ini) запрещаем требуемые функции, например:
suhosin.executor.func.blacklist = "exec,system,passthru,shell_exec,proc_open"
  • В настройках виртуального хоста Apache добавляем конструкцию (например, разрешаем exec)
php_admin_value suhosin.executor.func.blacklist "system, passthru, shell_exec, proc_open"
# find . -type f -name '*.php' -mtime -7
#!/bin/sh

$files_path = "/root/bin/data"
$search_path = "/var/www/site/"
$mail_to = "[email protected]"

rm  $files_path/before.txt
rm  $files_path/diff.txt

mv $files_path/current.txt $files_path/before.txt

find $search_path -name "*.php" -type f -print0 | xargs -0 sha1sum > $files_path/current.txt
find $search_path -name "*.js" -type f -print0 | xargs -0 sha1sum >> $files_path/current.txt
find $search_path -name "*.html" -type f -print0 | xargs -0 sha1sum >> $files_path/current.txt
find $search_path -name "*.css" -type f -print0 | xargs -0 sha1sum >> $files_path/current.txt

diff -urN $files_path/before.txt $files_path/current.txt > $files_path/diff.txt

if [ `ls -la $files_path/diff.txt | awk '{print $5}'` -ne 0 ]; then

 echo "Files changed!"

 mail -s "Files changed!" $mail_to < $files_path/diff.txt

fi
# find . -type f -name '*.php' | xargs grep -l "eval *(" --color
# find . -type f -name '*.php' | xargs grep -l "base64_decode *(" --color
# find . -type f -name '*.php' | xargs grep -l "gzinflate *(" --color
# find . -type f -name '*.php' | xargs egrep -i "preg_replace *\((['|\"])(.).*\2[a-z]*e[^\1]*\1 *," --color
# diff -r copy-clean/ copy-compromised/ -x список_исключений

Ищет директории доступные для записи и php файлы в них. Результат будет сохранен в файл results.txt. Скрипт работает рекурсивно.

#!/bin/bash
 
search_dir=$(pwd)
writable_dirs=$(find $search_dir -type d -perm 0777)
 
for dir in $writable_dirs
do
    #echo $dir
    find $dir -type f -name '*.php'
done
  • software/php/security_php.txt
  • Последнее изменение: 2022/07/18 23:14
  • 127.0.0.1