Un 403 diffère d'un 404 de façon utile : le serveur a trouvé ce que vous demandiez. Quelque chose a ensuite dit non. Cela réduit le champ à quatre possibilités.

1. Il n'y a pas de fichier d'index

Une requête vers un répertoire sans index.php ni index.html, avec le listage désactivé, donne un 403. C'est le comportement correct, et cela signifie en général qu'un déploiement n'est pas allé au bout.

ls -la /var/www/site/

2. Le serveur ne peut pas le lire

Un fichier que l'utilisateur web ne peut pas lire est refusé. Vérifiez le propriétaire autant que les droits — les droits sont bien plus souvent corrects que le propriétaire.

namei -l /var/www/site/index.php

namei parcourt tout le chemin et affiche les droits à chaque niveau. Un répertoire au milieu sans bit d'exécution bloque tout ce qui est en dessous, et c'est le cas qu'on rate.

3. Une règle le refuse

grep -rn "deny\|Require all denied" /etc/nginx/sites-enabled/ .htaccess 2>/dev/null

Les règles de sécurité qui bloquent par extension ou par répertoire sont le 403 voulu. Si c'est votre propre fichier qui est pris, la règle est trop large.

4. Un pare-feu ou un WAF

Si le 403 arrive avec une page qui n'est pas la vôtre, il vient de quelque chose placé devant le serveur. Son propre journal nomme la règle qui a mordu.

Un 403 sur wp-admin après une mise à jour d'extension, c'est presque toujours une extension de sécurité qui verrouille un chemin qu'elle croit attaqué. Son journal le dira, et la désactiver en renommant son répertoire est le moyen le plus rapide de s'en assurer.