Общая небезопасная настройка PHP?

10

Я работаю с системным администратором в университете и просто наткнулся на что-то, что, вероятно, распространено, но было для меня шоком.

Все каталоги public_html и веб-области хранятся в afs с разрешениями на чтение для веб-серверов. Поскольку пользователям разрешено иметь php-скрипты в своем public_html, это означает, что они могут обращаться к файлам друг друга изнутри php (и основных веб-файлов!).

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

Простой пример:

<?
  header("Content-type: text/plain");
  print file_get_contents("/afs/example.com/home/smith/public_html/.htpasswd"); 
?>

Это общая проблема? И как вы обычно это решаете?

ОБНОВИТЬ:

Спасибо за вклад. К сожалению, кажется, нет простого ответа. В большой общей среде, такой как эта, пользователям, вероятно, не следует предоставлять такой большой выбор. Лучший подход, который я могу придумать, - это установить open_basedir в основной конфигурации для всех каталогов public_html, запустить suphp и разрешить только чистый php (без сценариев cgi, запуска внешних команд с обратными галочками и т. Д.).

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

Понт
источник
Это интересный вопрос. Я уверен, что на крупных провайдерах виртуального хостинга (например, DreamHost) это невозможно. Но мне было бы интересно, как они защищают от этого. suphp, как упомянуто cstamas, выглядит хорошим решением, но разве этим пользуется большинство хостинг-провайдеров?
Lèse Majesté
1
Я использовал приведенное open_basedirниже решение для производственных систем общего хостинга, но мы разделили всех на своих собственных виртуальных хостов - не уверен, работает ли он для отдельных каталогов ...
voretaq7

Ответы:

8

Можно использовать suphp, который запускает скрипт php с идентификатором своего владельца.

http://www.suphp.org

cstamas
источник
Это, вероятно, не решит вышеуказанную проблему (по крайней мере, в среде общего хостинга .htpasswd файлы обычно принадлежат пользователю, который владеет читаемым сайтом и группой (apache) или миром (потому что пользователи не знают / не заботятся о безопасности), так что даже с suphp они смогут читать эти файлы)
voretaq7
@ voretaq7: может быть применено несколько других ограничений. Насколько я помню, вы даже можете запретить доступ к файлам, которые вам не принадлежат. Так что это исключает атаку выше.
cstamas
Я знаю, что вы можете ограничить разрешения для файлов («Не может быть доступно для записи группе / другим / кому-либо»), но я не знаю способа блокировать чтение за пределами разрешений FS. У них есть check_vhost_docroot, но AFAIK, который применяется только к исполняемому сценарию (? Я могу ошибаться)
voretaq7
1
Я не уверен, является ли suphp хорошим решением в такой среде. Пользователь может иметь все виды разрешений, которых нет у пользователя www. Злоумышленник, который нашел способ проникновения через php, может найти ssh-ключи или keytabs или изменить сценарии входа пользователя в систему для создания бэкдоров. И настройки vhosts не очень полезны, так как каталоги public_html доступны через "/ ~ username" на главном виртуальном хосте. Я думаю, что сценарии в public_html должны быть полностью отключены.
Понт
4

Я бы предложил ограничить доступ PHP к файлам (через open_basedir& подобные директивы, для каждого хоста): вы хотите, чтобы пользователи могли открывать / читать / записывать файлы под своим рутом и, возможно, на один уровень выше (для нуля) пространство), но не каталог, в котором они будут хранить, например, htpasswdфайлы.

Структура каталогов, например:

/Client
    /auth
    /site
        /www_root
        /www_tmp

Соответствует этому требованию: open_basedirможет быть /Client/siteбезопасно указано , и htpasswdфайлы хранятся в /Client/auth.htaccessфайлами или httpd.confизменены, чтобы указывать вместо этого в соответствующем месте).
Это препятствует тому, чтобы ваши клиенты открывали чьи-либо файлы, и в качестве преимущества злоумышленники не могут читать содержимое /Client/auth(или что-либо еще в вашей системе, например /etc/passwd:-)

Смотрите http://php.net/manual/en/ini.core.php для получения дополнительной информации о реализации open_basedir & per-vhost.

voretaq7
источник
1
suphpКак отметил cstamas, это также действительно хорошая идея в среде виртуального хостинга. Его настройка требует небольшого объема, но я бы сказал, что повышение безопасности того стоит. Если не считать песочницу всех ваших сайтов PHP в чем-то вроде FreeBSD Jail или выделенной виртуальной машины, это одно из самых больших достижений безопасности.
voretaq7
«open_basedir» кажется простым способом отделения основных веб-файлов от пользовательских, при условии, что «public_html» обслуживается через его собственный виртуальный хост. Но это не защищает пользователей друг от друга, поскольку у них нет собственных виртуальных хостов. Правильно?
Понт
Я не пробовал устанавливать open_basedirвнутри директивы <Directory>, но я думаю, что это должно быть допустимо («попробуйте и посмотрите» - худшее, что можно сделать, это не работает :)
voretaq7
1
Пока что похоже, что open_basedir используется большинством коммерческих веб-хостов (обычно подписчики имеют свои собственные платные домены или получают бесплатный поддомен), но для домашних страниц на основе каталогов, как в академическом учреждении, suphp кажется лучшим ответом.
Lèse Majesté
1

Нет, это не распространенная проблема, поскольку большинство общих хостов определяют конфигурацию open_basedir в файле htaccess в каталоге public_html каждого пользователя (или в vhost, если у каждого пользователя есть собственный vhost).

например, файла .htaccess:

# Assuming these are not set globally - its good practice to limit:
  php_flag magic_quotes_gpc off
  php_flag magic_quotes_runtime off
  php_flag register_globals off
  php_flag short_open_tag off
  php_value max_execution_time 60

# These set the user-specific paths
  php_value open_basedir /afs/example.com/home/smith:/usr/share/php/include
  php_value session.save_path /afs/example.com/home/smith/tmp
  php_value upload_tmp_dir /afs/example.com/home/smith/tmp

Но убедитесь, что вы установили правильные разрешения для файла .htaccess, чтобы предотвратить изменение пользователем open_basedir (если они пытаются переопределить его в subdir / .htaccess, это не должно работать - но вам, вероятно, следует проверить это, чтобы убедиться) ,

НТН

C.

symcbean
источник
2
Это может помочь предложить некоторую начальную защиту новых учетных записей. Но тот факт, что пользователь не может отредактировать его, может вызвать искушение удалить файл .htaccess (что он может сделать, поскольку для него требуется только доступ на запись в каталог public_html) и создать свой собственный. Добавление «<Directory>» - блока в основной конфигурации для каждого пользователя будет работать, но здесь им все еще разрешается отсылать внешние команды из php, что означает, что open_basedir легко обойти.
Понт
@Pontus: хорошая мысль об удалении файла (я не уверен, поддерживает ли afs неизменный атрибут файла). Я бы дал +1, если бы вы сказали, что запуск веб-сервера в chroot-тюрьме защитит от всевозможных уязвимостей при выполнении программы.
Symcbean
1

AFS игнорирует простые пользовательские разрешения Unix. suPHP выполняет setuid перед запуском программы php, но это не дает процессу токенов kerberos, необходимых для доступа к AFS, и ограничивается его разрешениями. Для получения этих токенов необходимо было бы каким-то образом изменить suPHP, прежде чем он сможет представить себя в системе AFS в качестве этого пользователя. Насколько я знаю, это не было сделано. (На самом деле, я нашел этот вопрос, когда смотрел, сделал ли это кто-нибудь еще.)

Чарльз Б
источник