Запретить прямой доступ ко всем файлам .php, кроме index.php - PullRequest
75 голосов
/ 27 августа 2009

Я хочу запретить прямой доступ ко всем .php файлам, кроме одного: index.php

Единственный доступ к другим .php файлам должен осуществляться через php include.

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

UPDATE:

Общее правило было бы неплохо, поэтому мне не нужно просматривать все файлы. Риск в том, что я забываю файл или строку.

ОБНОВЛЕНИЕ 2:

index.php находится в папке www.myadress.com/myfolder/index.php

Я хочу запретить доступ ко всем .php файлам в myfolder и вложенным папкам в этой папке.

Ответы [ 13 ]

103 голосов
/ 27 августа 2009

Вы уверены, что хотите это сделать? Даже CSS и JS файлы и изображения и ...?

ОК, сначала проверьте, установлен ли mod_access в apache, затем добавьте в ваш .htaccess следующее:

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

<Files /index.php>
    Order Allow,Deny
    Allow from all
</Files>

Первая директива запрещает доступ к любым файлам, кроме как с localhost, поскольку Order Deny,Allow, позже разрешается применение Allow, вторая директива влияет только на index.php

Предупреждение: после запятой в строке заказа не должно быть пробелов.

Чтобы разрешить доступ к файлам, соответствующим * .css или * .js, используйте эту директиву:

<FilesMatch ".*\.(css|js)$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

Вы не можете использовать директивы для <Location> или <Directory> внутри файлов .htaccess.

Вы могли бы использовать <FilesMatch ".*\.php$"> вокруг первого разрешения, запретить группу и затем явно разрешить доступ к index.php.

Обновление для Apache 2.4: Этот ответ правильный для Apache 2.2. В Apache 2.4 парадигма контроля доступа изменилась, и правильный синтаксис должен использовать Require all denied.

80 голосов
/ 29 июля 2012

На самом деле, я пришел сюда с тем же вопросом, что и создатель темы, но ни одно из приведенных решений не было полным ответом на мою проблему. Зачем добавлять код для ВСЕХ файлов на вашем сервере, когда вы можете просто настроить его один раз? Самым близким был Residuum, но он исключал ВСЕ файлы, когда я хотел исключить только файлы php, которые не были названы index.php.

Итак, я придумал .htaccess, содержащий это:

<Files *.php>
    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1
</Files>

<Files index.php>
    Order Allow,Deny
    Allow from all
</Files>

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

А вот и мы. Единственными php-файлами, которые будут доступны для пользователя, будут файлы с именем index.php. Но вы все равно можете получить доступ к каждому изображению, таблице стилей CSS, сценарию js и т. Д.

34 голосов
/ 22 октября 2009

Косвенным ответом на вопрос является написание всего кода в виде классов, кроме файлов index.php, которые являются единственными точками входа. Файлы PHP, содержащие классы, не вызовут каких-либо изменений, даже если они вызываются напрямую через Apache.

Прямой ответ - включить в .htaccess следующее:

<FilesMatch "\.php$">
    Order Allow,Deny
    Deny from all
</FilesMatch>
<FilesMatch "index[0-9]?\.php$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

Это позволит получить доступ к любому файлу, например index.php, index2.php и т. Д., Но запретит доступ любого вида к другим файлам .php. Это не повлияет на другие типы файлов.

16 голосов
/ 27 августа 2009

Вы можете попробовать определить константу в index.php и добавить что-то вроде

if (!defined("YOUR_CONSTANT")) die('No direct access');

к началу других файлов.

ИЛИ, вы можете использовать mod_rewrite и перенаправлять запросы в index.php, редактируя .htaccess следующим образом:

RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php/$1 [L,R=301]

Тогда вы сможете анализировать все входящие запросы в index.php и выполнять соответствующие действия.

Если вы хотите пропустить, например, все файлы * .jpg, * .gif, * .css и * .png, вам следует отредактировать вторую строку следующим образом:

RewriteCond $1 !^(index\.php|*\.jpg|*\.gif|*\.css|*\.png)
11 голосов
/ 27 августа 2009

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

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

5 голосов
/ 12 февраля 2013

Перезапись URL может использоваться для сопоставления URL с файлами .php. Следующие правила могут определить, был ли запрос .php сделан напрямую или переписан. Запрещает запрос в первом случае:

RewriteEngine On
RewriteCond %{THE_REQUEST} ^.+?\ [^?]+\.php[?\ ]
RewriteRule \.php$ - [F]
RewriteRule test index.php

Эти правила запрещают все запросы, заканчивающиеся на .php. Однако такие URL-адреса, как / (который запускает index.php), /test (который переписывает в index.php) и /test?f=index.php (который содержит index.php в строке запроса), все еще разрешены.

THE_REQUEST содержит полную строку HTTP-запроса, отправленную браузером на сервер (например, GET /index.php?foo=bar HTTP/1.1)

2 голосов
/ 22 мая 2013

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

<?php
// Security check: Deny direct file access; must be loaded through index
if (count(get_included_files()) == 1) {
    header("Location: index.php"); // Send to index
    die("403"); // Must include to stop PHP from continuing
}
?>
1 голос
/ 01 марта 2016

В Apache 2.4 изменился синтаксис для контроля доступа. Если используются такие директивы, как:

Order deny,allow
Deny from all

не работает, вы, вероятно, используете Apache 2.4.

Документы Apache 2.4 находятся здесь .

Вам необходимо использовать Require all denied одним из следующих способов:

# you can do it this way (with "not match")

<FilesMatch ^((?!index\.php).)*$>
  Require all denied
</FilesMatch>

# or 

Require all denied

<Files index.php>
  Require all granted
</Files>
1 голос
/ 24 марта 2012

Простое решение - переименовать все файлы, не относящиеся к index.php, к .inc, а затем запретить доступ к файлам * .inc. Я использую это во многих моих проектах, и это прекрасно работает.

0 голосов
/ 09 декабря 2015
<Files ~ "^.*\.([Pp][Hh][Pp])">
 Order allow,deny
 Deny from all
 Satisfy All
</Files>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...