web-dev-qa-db-fra.com

Refuser l'accès direct à tous les fichiers .php sauf index.php

Je souhaite refuser l'accès direct à tous les fichiers .php sauf un: index.php

Le seul accès aux autres fichiers .php devrait se faire par php include.

Si possible, je veux tous les fichiers dans le même dossier.

METTRE À JOUR:

Une règle générale serait bien, donc je n'ai pas besoin de parcourir tous les fichiers. Le risque est que j'oublie un fichier ou une ligne. 

MISE À JOUR 2:

Le index.php est dans un dossier www.myadress.com/myfolder/index.php

Je souhaite refuser l'accès à tous les fichiers .php de myfolder et aux sous-dossiers de ce dossier.

73
Johan

Êtes-vous sûr de vouloir faire ça? Même les fichiers css et js et les images et ...? 

OK, vérifiez d’abord si mod_access est installé sur Apache, puis ajoutez ce qui suit à votre .htaccess:

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

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

La première directive interdit l'accès à tous les fichiers, à l'exception de localhost. En raison de Order Deny,Allow, Allow est appliqué plus tard, la deuxième directive n'affecte que index.php. 

Mise en garde: Pas d'espace après la virgule dans la ligne de commande.

Pour autoriser l'accès aux fichiers correspondant à * .css ou * .js, utilisez cette directive:

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

Cependant, vous ne pouvez pas utiliser de directives pour <Location> ou <Directory> dans les fichiers .htaccess.

Votre option serait d’utiliser <FilesMatch ".*\.php$"> autour du premier permis, refuser, puis d’autoriser explicitement l’accès à index.php.

Mise à jour pour Apache 2.4: Cette réponse est correcte pour Apache 2.2. Dans Apache 2.4, le paradigme de contrôle d'accès a changé et la syntaxe correcte consiste à utiliser Require all denied.

103
Residuum

En fait, je suis venu ici avec la même question que le créateur du sujet, mais aucune des solutions proposées ne constituait une réponse complète à mon problème… .. Pourquoi ajouter un code à TOUS les fichiers sur votre serveur alors que vous pouviez simplement le configurer une fois? Le plus proche était celui de Residuum, mais il excluait TOUS les fichiers, alors que je voulais exclure uniquement les fichiers php non nommés index.php.

Alors je suis arrivé avec un .htaccess contenant ceci:

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

(N'oubliez pas que les fichiers htaccess fonctionnent de manière récursive, ce qui convient parfaitement aux conditions préalables de la question.)

Et c'est reparti. Les seuls fichiers php qui seront accessibles à un utilisateur seront ceux nommés index.php . Mais vous pouvez toujours accéder à chaque image, feuille de style CSS, script JS, etc.

79
Jerska

Une réponse oblique à la question consiste à écrire tout le code en tant que classes, à l'exception des fichiers index.php, qui sont alors les seuls points d'entrée. Les fichiers PHP contenant des classes ne provoqueront rien, même s'ils sont invoqués directement via Apache.

Une réponse directe consiste à inclure les éléments suivants dans .htaccess:

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

Cela permettra d’accéder à tout fichier tel que index.php, index2.php, etc., mais refusera tout accès à d’autres fichiers .php. Cela n'affectera pas les autres types de fichiers.

34
user185631

Vous pouvez essayer de définir une constante dans index.php et ajouter quelque chose comme

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

au début des autres fichiers.

OU, vous pouvez utiliser mod_rewrite et rediriger les demandes vers index.php, en éditant .htaccess comme ceci:

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

Ensuite, vous devriez pouvoir analyser toutes les demandes entrantes dans le fichier index.php et prendre les mesures qui s’imposent.

Par exemple, si vous souhaitez omettre tous les fichiers * .jpg, * .gif, * .css et * .png, vous devez éditer la deuxième ligne comme suit:

RewriteCond $1 !^(index\.php|*\.jpg|*\.gif|*\.css|*\.png)
16
n1313

Que diriez-vous de conserver tous les fichiers .php, sauf index.php au-dessus de la racine Web? Pas besoin de règles de réécriture ou de kludges programmatiques.

Ajouter le dossier includes-dossier à votre chemin d’inclusion vous aidera alors à garder les choses simples, pas besoin d’utiliser des chemins absolus, etc.

10
nikc.org

La réécriture d'URL peut être utilisée pour mapper une URL sur des fichiers .php. Les règles suivantes permettent d’identifier si une demande .php a été faite directement ou si elle a été réécrite. Il interdit la demande dans le premier cas:

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

Ces règles interdiront toutes les demandes se terminant par .php. Toutefois, les URL telles que / (qui déclenche index.php), /test (qui réécrit en index.php) et /test?f=index.php (qui contient index.php dans chaîne de requête) sont toujours autorisées.

THE_REQUEST contient la ligne de requête HTTP complète envoyée par le navigateur au serveur (par exemple, GET /index.php?foo=bar HTTP/1.1)

5
Salman A

Au lieu de passer une variable autour de je fais ceci qui est autonome en haut de toute page à laquelle vous ne voulez pas d’accès direct, cela devrait quand même être associé à des règles .htaccess mais je me sens plus en sécurité sachant qu’il existe un fail-safe si htaccess se gâte un jour.

<?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
Brock Hensley

Une solution simple consiste à renommer tous les fichiers non-index.php en .inc, puis à refuser l'accès aux fichiers * .inc. J'utilise cela dans beaucoup de mes projets et cela fonctionne parfaitement bien.

1
Dan Ambrisco

Avec Apache 2.4, la syntaxe de contrôle d'accès a changé. Si vous utilisez des directives telles que:

Order deny,allow
Deny from all

ne fonctionne pas, vous utiliserez probablement Apache 2.4.

Les docs Apache 2.4 sont ici .

Vous devez utiliser Require all denied de l'une des manières suivantes:

# 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>
0
Josiah

placer tous les fichiers dans un dossier. Placez un fichier .htaccess dans ce dossier et donnez-lui la valeur nier tout. puis dans index.php, qui se trouve en dehors du dossier, renvoie les bonnes pages en fonction de la saisie de l'utilisateur ou de l'événement. 

0
Quincy