Заборонити прямий доступ до всіх файлів .php, крім index.php


77

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

Єдиний доступ до інших .phpфайлів повинен бути через php include.

Якщо можливо, я хочу, щоб усі файли були в одній папці.

ОНОВЛЕННЯ:

Загальне правило було б непоганим, тому мені не потрібно переглядати всі файли. Ризик полягає в тому, що я забув файл або рядок.

ОНОВЛЕННЯ 2:

Це index.phpзнаходиться в папціwww.myadress.com/myfolder/index.php

Я хочу заборонити доступ до всіх .phpфайлів у myfolderцій папці та вкладених папок.

Відповіді:


106

Ви впевнені, що хочете це зробити? Навіть файли та зображення 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, Дозволити застосовується пізніше, друга директива впливає лише на index.php.

Застереження: після коми в рядку Замовлення не залишається пробілу.

Щоб дозволити доступ до файлів, що відповідають * .css або * .js, використовуйте цю директиву:

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

Однак ви не можете використовувати директиви для файлів .htaccess <Location>або <Directory>всередині них.

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

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


3
Хм ... ні, лише для .php-файлів
Йохан

Добре, я абсолютно новачок у .htaccess. Я спробував скопіювати ваш код, і це працює, щоб заборонити всі файли, крім index.php, але не дозволяти файли, що не .php. Ось мій файл .htaccess: Замовити заборонити, дозволити заборонити з усіх Дозволити з 127.0.0.1 <Files index.php> Замовити дозволити, заборонити дозволити з усіх </Files> <FilesMatch "* \. (Css | js) $" > Замовити дозволити, заборонити дозвіл усім </FilesMatch>
Йохан

2
не спрацював для мене (але я не підтримав вас). Я отримав повідомлення про неправильне налаштування сервера. Можливо, сервер дійсно неправильно налаштований. Це спрацювало: stackoverflow.com/a/1607587/539300
Тайлер

86

Власне, я прийшов сюди з тим самим запитанням, що і творець теми, але жодне з наведених рішень не було повною відповіддю на мою проблему. Навіщо додавати код до ВСІХ файлів на вашому сервері, коли ви можете просто налаштувати його один раз? Найближчим був 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

Коса відповідь на запитання - це написати весь код як класи, крім файлів 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. Це не вплине на інші типи файлів.


Якщо ви використовуєте Joomla, сайти Joomla зазвичай мають лише index.php та index2.php. Зверніть увагу: index2.php застарілий, оскільки Joomla 1.6.
rineez

Хороші речі, але це порушується, коли у вас є інший index.php всередині вашого додатка (що часто зустрічається у поданнях у деяких фреймворках).
Sliq

17

Ви можете спробувати визначити константу в 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)

Ви знаєте як? Я поняття не маю.
Йохан

Чи має значення, що index.php знаходиться в папці.
Йохан

Так, вам слід написати повний абсолютний шлях до нього в RewriteRule, наприклад RewriteRule ^ (. *) $ /Somedir/anotherdir/index.php/$1 [L]
n1313

.htaccess: RewriteRule: unknown flag 'L][R'
Брок Хенслі

Відредаговано: прапори слід розділяти комами
Брок Хенслі,

11

Як щодо збереження всіх файлів .php, крім index.php, над веб-коренем? Не потрібно ніяких правил переписування чи програмних ключів.

Додавання папки Includes до шляху включення допоможе зробити речі простішими, не потрібно використовувати абсолютні шляхи тощо.


Добре, я переміщую свої файли в іншу папку. Дякую за допомогу .htaccess, але це було для мене дуже складно.
Йохан

А може, ні, це було занадто багато посилань між моїми документами, тому я чекаю з цим рішенням.
Йохан

Що ви маєте на увазі під посиланням на посилання? Ви додали папку, до якої ви перенесли файли, у свій шлях включення?
nikc.org

Linkreference = include('file.php')toinclude('myfolder/file.php')
Йохан

Якщо ви включите папку, куди ви переміщуєте файли, у свій шлях include ( ini_set('include_path', ini_get('include_pat'). ':/path/to/files');), то ви можете зробити те саме, не зламавши нічого.
nikc.org

6

Переписування 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)


1
Це рішення, яке я шукав. Я хотів заборонити доступ до всіх php, крім моїх правил перезапису. Дякую!
machineddict

Ви відповідь поруч , що я шукаю, якщо ви все ще тут , може бути , ви можете подивитися на stackoverflow.com/questions/57260003 / ...
Serge

2

Замість того, щоб передавати змінну навколо, я роблю це, що є автономним у верхній частині будь-якої сторінки, до якої ви не хочете отримувати прямий доступ, це все одно має бути в парі з правилами .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
}
?>

Це чудово для крихітних додатків, але коли у вас є навантаження контролерів, моделей, шаблонів тощо, тоді це стає абсолютно некерованим.
Джеймс

2

З 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>

Другий, здається, не працює, якщо ви запитуєте example.org, він працює лише для example.org/index.php
Damien Bezborodow

1

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


0

помістіть усі файли в одну папку. помістіть файл .htaccess у цю папку та надайте йому значення відхилити всі. тоді в index.php, розміщеному за межами папки, буде лунати потрібні сторінки на основі вводу або події користувача



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.