Почему index.php находится в папке public, а не в общей папке?

Evg Evg 3 Апреля 2022

Если вы знакомы со структурой сайта libArea, то знаете, что файл index.php находится в папке public. Это хорошая идея держаться index.php за пределами корневого каталога вашего проекта:

Структура LibArea

Публичный каталог (public)

Публичный каталог (/public) является домом для всех общедоступных и статических файлов вашего приложения, включая изображения, таблицы стилей и файлы JavaScript. Там же находится index.php.

Другие фреймворки и приложения PHP могут использовать другой подход и добавлять index.php файл непосредственно в root каталог. Пока вы направляете сервер в «общедоступный» каталог, содержащий index.php файл, сайт должен отображаться так, как ожидалось.

В LibArea файл index.php находится в public папке с другими «безопасными для просмотра» ресурсами, такими как css, js, изображения и т.д. Это способствует хорошей практике безопасности, чтобы общедоступные файлы были общедоступными, а частные файлы — частными.

Поощряйте надлежащие методы обеспечения безопасности, чтобы общедоступные файлы были общедоступными, а другие, нет.

Но как насчет приложений, которые добавляют index.php в корень?

Есть много популярных веб-приложений, которые не следуют этой структуре и предоставляют index.php в корневом каталоге.

Существует (если обобщать и упрощать) два подхода.

Использование папки /public — это подход к безопасности с использованием «белого списка», означающий, что все запрещено, кроме того, что находится в белом списке (все в общей папке).

Неиспользование папки /public — это подход к безопасности с использованием «черного списка», означающий, что разрешено все, кроме того, что занесено в черный список (правила, определенные в файле конфигурации вашего веб-сервера).

LibArea использует подход «белого списка» к веб-безопасности. Это сделано потому, что мы считаем, что держать весь наш системный код в корневой папке — не очень хорошая идея. (Аналогично обстоят дела и с Content Security Policy).

Настройка веб-сервера (для локальной отладки)

Пример конфигурации для XAMPP, PHP 8.2, httpd-xampp.conf:


    ServerAdmin webmaster@lib.loc
        DocumentRoot "d:/xampp/htdocs/lib.loc/public"
        ServerName lib.loc
    ServerAlias www.lib.loc
    ErrorLog "d:/xampp/htdocs/lib.loc/error.log"
        CustomLog "d:/xampp/htdocs/lib.loc/access.log"

        Require all granted
        AllowOverride All
        Order allow,deny
        Allow from all

Или для пакета: XAMPP для Windows 8.1.4 (PHP 8.1.4), файл (httpd-vhosts.conf):


    ServerAdmin webmaster@lib.loc
    DocumentRoot "D:/xampp/htdocs/lib.loc/public"
    ServerName lib.loc

Больше информации: https://libarea.com/ru/web-server-configuration/

P.S. обычно техническая поддержка хостинга (если вы объясните ей ситуацию по поводу public) знает о чем разговор и довольно охотно поможет сделать подобающие настройки. Тем более подобная практика применяется и в некоторых других приложениях.


Если уж разговор зашел про локальный хостинг, то можно ещё столкнуться при авторизации с ошибкой: Protected from CSRF

Чтобы исправить её необходимо закомментировать 2 строки в файле: public/.htaccess

# php_value session.cookie_httponly 1
# php_value session.cookie_secure 1

И если есть, то это:

#  
#    Header onsuccess edit Set-Cookie ^(.*) "$1; SameSite=Strict; HttpOnly; Secure"
#  

На реальном хостинге всё должно работать…


English:

Using a /public folder is a white-list approach to security, meaning everything is banned except for the things that are white listed (everything in the public folder).

Not using a /public folder is a black-list approach to security, meaning everything is allowed except for things that are black listed (rules defined in your webserver configuration file).

LibArea uses a white-list approach to web security. This is because we don't think it's a good idea to keep all of our system code in the root folder.

The situation is similar with Content Security Policy.

4 Ответа

  1. German German 3 Апреля 2022

    Хорошая идея написать статью, а то вижу много вопросов задают?

    1. Evg Evg 3 Апреля 2022

      Да. Когда 1 спрашивает, — это одно, но когда достаточно много людей интересуются, статья просто необходима.

  1. 4xpro 4xpro 4 Апреля 2022 (ред.)

    Основной недостаток index.php в подкаталоге (на мой взгляд, кстати, более понятным является имя www, а не public) — сложность поставить два таких приложения на одном домене на shared-хостинге без доступа к конфигу Apache (и знания, как его править). Ну и плюс установка становится неинтуитивной — нужно прочитать документацию, чтобы выяснить, куда должен указывать DocumentRoot. Кстати, не на всех хостингах его можно менять самому, иногда приходится писать в техподдержку (это для меня существенный минус).

    Я в своём движке сделал чуть иначе — в корень проекта положил .htaccess, в котором прописал

    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteRule ^(www/.*)$ $1 [QSA,L]  # защита от зацикливания
      RewriteRule ^(.*)$ www/$1 [QSA]
    </IfModule>

    В результате чего DocumentRoot можно направлять как в каталог www, так и на корень проекта, и всё будет работать и в том, и в другом случае, а каталоги вне www остаются недоступными.

    P.S. session.cookie_httponly прекрасно работают и на localhost, комментировать нужно только вторую строчку, т.к. она делает cookies доступными только по https.

    1. Evg Evg 4 Апреля 2022 (ред.)

      Спасибо большое, тут есть такая возможность, но менять (по умолчанию) не думаю, что стоит. Этот вопрос в частном порядке можно решить без особых проблем для VPS (что касается хостинга, не особо знаком с ним).

      Использование .htaccess я не рекомендую, т.к. идет в разрез с политикой безопасности, подхода, который используется тут (см. выше: белый и черный список).

Комментарий удален...