Cacher le nom de fichier du contrôleur d'entrée Symfony

Publié le 23/08/2019 • Mis à jour le 23/08/2019

Dans cet article nous allons voir comment cacher le nom de fichier du contrôleur d'entrée principal d'une application Symfony ("main front controller" en anglais) pour qu'il soit impossible d'accéder au site en tapant "index.php" dans l'URL. Le moins d'informations les utilisateurs (ou hackers bien sûr) auront sur l'implémentation technique de votre site, le mieux ce sera. C'est parti mon kiki ! 😎

C'est l'été, cet article sera donc assez concis. En fait c'est un test que je voulais faire sur ce blog. Je voulais avoir un contrôleur spécifique pour l'environnement de production (comme avec Symfony3) et pouvoir cacher le contrôleur d'entrée principal pour que l'accès aux pages par "index.php" aboutisse à une erreur 404 et ce, sans avoir à utiliser de fichier .htaccess ni de redirections (quand on utilise Apache comme serveur web). Ce n'est pas considéré comme une bonne pratique, utilisez à vos risques et périls !

» Publié dans "Une semaine Symfonique 660" (du 19 au 25 Août 2019).

utilisez à vos risques et périls

Configuration

  • PHP 7.2
  • Symfony 4.3
  • Apache 2.4

Introduction

Le contrôleur d'entrée principal est le fichier responsable de traiter toutes les requêtes d'une application Symfony. Quand on utilise Symfony4, c'est le fichier index.php situé dans le répertoire "public". Par exemple quand on accède au site officiel Symfony, on remarque que les URLs suivantes sont accessibles :

Le but ici va être d'empêcher les utilisateurs, bots ou moteurs de recherche d'accéder aux URLs via le fichier index.php.

Création du point d'entrée spécifique de production

Ajoutez un fichier dans le répertoire "public" de votre application et nommez le avec une chaîne aléatoire. (ex: ajJoNGJix4KRMM3xwhgLXG4GUgJHhyFk.php) Ajoutez le code suivant :

<?php declare(strict_types=1);

// public/ajJoNGJix4KRMM3xwhgLXG4GUgJHhyFk.php
// this is a fake name, not the one used by this website! 😁

use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;

require __DIR__.'/../vendor/autoload.php';

(new Dotenv())->load(__DIR__.'/../.env');
$kernel = new Kernel('prod', false);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Nous avons supprimé toutes les parties relatives à l'environnement de développement et aux fonctionnalités de débug pour garder le strict minimum. (il n'y a pas de différence de performance substantielle avec le contrôleur original) Nous avons toujours le fichier index.php, dans ce projet j'ai préféré le renommer en index_dev.php afin qu'il n'y ait pas de confusion. Mais on peut garder bien sûr le nom original.

Attention, si vous utilisez les variables d'environnement TRUSTED_PROXIES or TRUSTED_HOSTS vous devez garder les lignes suivantes :

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
    Request::setTrustedHosts(explode(',', $trustedHosts));
}

Cacher le contrôleur d'entrée

Maintenant, cachons le point d'entrée. La première chose à faire est d'exclure le fichier index.php de votre procédure de déploiement. Pour déployer le code relatif à ce blog j'utilise un fichier MakeFile (vous trouverez le code complet ici). Je supprime le fichier voulu dans la cible git-update du Make.) Maintenant, nous devons indiquer au serveur web d'utiliser le nouveau fichier. Par exemple si on utilise Apache :

# configuration/vhosts/prod/strangebuzz.com-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName www.strangebuzz.com
    ServerAlias strangebuzz.com
    DocumentRoot /var/www-protected/strangebuzz.com/public

    <Directory /var/www-protected/strangebuzz.com/public>
        AllowOverride All
        Require all granted
        # this is a fake one, again! 😁
        FallbackResource /ajJoNGJix4KRMM3xwhgLXG4GUgJHhyFk.php
        #FallbackResource /index.php
    </Directory>

    RedirectMatch 404 /\.git

    ErrorLog /var/log/apache2/strangebuzz.com_error.log
    CustomLog /var/log/apache2/strangebuzz.com_access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =strangebuzz.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
SSLCertificateFile /etc/letsencrypt/live/www.strangebuzz.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.strangebuzz.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Comme vous pouvez le voir, nous avons changé la solution de repli (fallback) pour utiliser le nouveau fichier au lieu de l'ancien fichier index.php. Et voilà ! Maintenant, maintenant quand on essaie d'accèder au site avec l'ancien nom de fichier index.php nous aboutissons à une erreur 404, il n'y a donc qu'une seule URL accessible pour cette ressource et nous sommes donc sûrs que l'URL canonique sera toujours celle sans nom de fichier php.

Bonus:
1) Il y a un article sur ce blog ou vous pourriez trouver le nom réel du contrôleur d'entrée de ce site, pouvez-vous le trouver ?
2) Pourquoi est-ce toujours indiqué index.php?

Cliquez ici pour voir les réponses.

1) Il se trouve ici : L'antisèche intéractive de la classe Symfony Request. Le nom de fichier est retourné par la fonction getScriptName() de l'objet / valeur (value object) Request.
2) Je triche un peu, j'ai simplement mis la valeur en dur au lieu d'utiliser le résultat de la fonction ! 😁

[
    'name' => 'getScriptName',
    'parameters' => '',
    'type' => 'string',
    //'result' => $r->getScriptName(),
    'result' => 'index.php', // hide real controller name
    'show' => !$refresh,
    'url' => 812
],

Et voilà ! J'espère que vous avez aimé. Découvrez d'autres informations en rapport à cet article avec les liens ci-dessous. Comme toujours, feedback, likes et retweets sont les bienvenus. (voir la boîte ci-dessous) À la revoyure ! COil. 😊

 La documentation  Plus sur Stackoverflow


» A vous de jouer !

Ces articles vous ont été utiles ? Vous pouvez m'aider à votre tour de plusieurs manières : (utilisez le Tweet à droite pour commenter / me contacter )

  • Me remonter des erreurs ou typos.
  • Me remonter des choses qui pourraient être améliorées.
  • Aimez et retweetez !
  • Suivez moi sur Twitter
  • Inscrivez-vous au flux RSS.

Merci d'avoir tenu jusque ici et à très bientôt sur Strangebuzz ! 😉

COil