Accueil · Guides de dépannage · Erreur 403

Erreur 403 forbidden WordPress : trouver ce qui refuse l'accès et débloquer le site

Fenêtre de navigateur affichant 403, Forbidden

Le serveur a compris votre demande et il a décidé de ne pas y répondre. C'est tout ce que dit un 403. Contrairement à une erreur 500, il n'y a rien de cassé à réparer : il y a une décision de refus à retrouver, entre le pare-feu de votre hébergeur et un fichier de configuration de votre site. Voici la procédure qu'on applique en intervention, avec les chemins exacts et les lignes de journal à y chercher.

Le test à faire avant tout le reste

Prenez votre téléphone, coupez le wifi, ouvrez votre site en 4G. Dix secondes, aucun risque, et le résultat sépare les deux grandes familles de causes.

Le site s'affiche sur le téléphone et reste en 403 sur votre ordinateur. Le refus ne vise pas votre site, il vise l'endroit d'où vous le regardez : votre adresse IP publique, ou la provenance de la requête. Aucun réglage de droits ne produit ce comportement, et vous pouvez ignorer les trois quarts de ce qui s'écrit sur le sujet.

Le 403 vous suit sur le téléphone. Le refus est attaché au site. Continuez.

Coupez le wifi pour de bon : sur le réseau du bureau, vous sortez par la même adresse publique que votre ordinateur et vous refaites le même test. Un cas du corpus l'illustre, tous les postes filaires d'un bureau en 403 sur leur propre site, tous les autres sites du web accessibles, et l'hébergeur qui finit par débloquer l'adresse. Cette cause arrive en deuxième position dans tout ce que nous avons lu, et presque aucun article français ne la mentionne.

Ce que vous voyez, et qui l'a écrit

Trois pages de refus circulent sous le même code, et elles ne se réparent pas de la même façon. Voici ce que nous avons mesuré sur une installation de test, sous Apache 2.4 avec PHP en FPM.

Ce qui a causé le refus Code Poids Texte affiché
Une règle du serveur ou du .htaccess qui refuse la requête 403 290 octets You don't have permission to access this resource. puis la signature du serveur
Un dossier privé de son droit d'exécution 403 290 octets le même, à l'octet près
Un fichier PHP que le serveur n'arrive pas à lire 403 15 octets Access denied.
Page de refus d'Apache sur boulangerie-lemoulin.fr, texte « You don't have permission to access this resource » suivi de la signature du serveur
Page de refus d'Apache sur boulangerie-lemoulin.fr, texte « You don't have permission to access this resource » suivi de la signature du serveur

Les quinze octets sont la signature la plus utile de ce guide. Cette page n'est pas écrite par Apache mais par PHP, qui n'a pas réussi à ouvrir le script demandé : deux mots, aucune mise en forme, aucune signature. Là, vous avez un vrai problème de droits, et c'est le seul cas où le chmod sert à quelque chose.

Page de quinze octets affichant uniquement « Access denied. », réponse de PHP-FPM à un fichier qu'il ne peut pas lire
Page de quinze octets affichant uniquement « Access denied. », réponse de PHP-FPM à un fichier qu'il ne peut pas lire

Deux variantes se reconnaissent au premier coup d'œil. Des hébergeurs français remplacent la page d'Apache par leur libellé maison, Erreur 403 - Refus de traitement de la requête (Interdit - Forbidden). Et une page mise en forme, avec un logo et votre adresse IP, désigne une extension de sécurité.

En trente secondes

Après le test du téléphone, voyez si le refus frappe tout le site ou une partie. Essayez l'accueil, une page interne, wp-login.php, une image de wp-content/uploads. Sur la panne reproduite au laboratoire, seul wp-login.php renvoyait 403 pendant que l'accueil répondait normalement : un 403 qui ne frappe qu'une partie du site désigne une règle ciblée, jamais un problème général de droits. Avec un terminal, curl -I https://votre-domaine.fr donne le code réellement renvoyé, parfois un 401, un 429 ou un 503.

Les causes, dans l'ordre où elles apparaissent vraiment

Nous n'inventerons pas de pourcentages. Ce qui suit vient de dix fils publics sur le 403 lus en entier, et de vingt-deux pages du top 10 de huit marchés.

Cause Ce qui la trahit
Une règle de refus dans le .htaccess, souvent laissée par un durcissement Le refus frappe certains fichiers et pas d'autres, typiquement les .php
Le pare-feu applicatif de l'hébergeur, ModSecurity ou celui du panneau Un refus reproductible sur une action ou une URL précise. Rien dans les journaux de WordPress
Une adresse IP ou une provenance bloquée Le site répond ailleurs que chez vous
Une extension de sécurité La page de refus est mise en forme et affiche votre adresse IP
La propriété des fichiers, plus rarement leurs droits Page de quinze octets, ou journal qui dit qu'un fichier n'existe pas alors qu'il est bien là
Un site compromis Comptes d'utilisateurs inconnus, refus qui va et vient

Le pare-feu de l'hébergeur mérite un mot : c'est la cause numéro un en mutualisé, et la seule source française qui le dise est un fil du forum d'OVH, quatrième de la page de résultats. Les articles qui le devancent ne le nomment jamais en tête, et le premier de tous ne le nomme pas du tout.

Le chmod que tout le monde vous conseille, et ce qu'il fait vraiment

Toutes les pages ou presque commencent par là, remettre les dossiers en 755 et les fichiers en 644. Nous avons voulu savoir ce que ce geste répare.

Sur un 403 provoqué par un bloc de durcissement laissé dans le .htaccess, du type <FilesMatch> Require all denied, la page visée reste en 403 après un chmod 644, après un chmod 755, et après un chmod 777. Trois mesures, trois refus identiques. Le conseil donné en premier partout n'a aucun effet sur la cause la plus fréquente du 403.

Les fils disent la même chose autrement : aucun des dix ne se conclut par « j'ai corrigé les droits et c'était réglé ». Un auteur avait tout appliqué avant même de poster, un autre est monté jusqu'à 777 sur le fichier et sur son dossier parent, sans rien changer.

Un cas mesuré fait exception, le dossier privé de son droit d'exécution : à 644 le serveur ne peut plus le traverser et refuse tout ce qu'il contient, à 755 tout revient. C'est le scénario du transfert FTP qui a appliqué aux dossiers les droits prévus pour les fichiers, et le journal le désigne par une ligne précise, donnée plus bas. Ailleurs, 755 et 644 sont l'état normal d'une installation, rien de plus.

L'arbre de diagnostic

Le site s'ouvre-t-il depuis un téléphone en 4G ? Oui : l'adresse IP ou la provenance est bloquée, cause 3. Non : continuez.

La page fait-elle quinze octets, avec pour seul texte Access denied. ? Oui : PHP n'arrive pas à lire le fichier, cause 4. Non : c'est la page du serveur, continuez.

Le refus frappe-t-il tout le site ? Une partie seulement : règle ciblée, causes 1 puis 2. Tout, fichiers statiques compris : cause 1, puis les droits du dossier racine.

Renommer le .htaccess de la racine change-t-il quelque chose ? Le site revient : la règle était dedans. Rien ne change : le refus vient du serveur ou de son pare-feu.

La réparation, cause par cause

Téléchargez d'abord une copie du .htaccess sur votre ordinateur, et ne changez qu'une chose à la fois. Après quinze modifications, plus personne ne sait dans quel état est le site.

Cause 1 : une règle de refus dans le .htaccess

Ouvrez le .htaccess de la racine, le dossier qui contient wp-config.php, souvent nommé public_html, www ou htdocs. Il commence par un point, donc il est caché : activez l'affichage des fichiers cachés dans votre client FTP avant de conclure qu'il n'existe pas.

Cherchez les directives de refus, reconnaissables aux mots Require all denied, Deny from all ou Order deny,allow, souvent dans un bloc <FilesMatch> ou <Files>. Le cas le mieux documenté du corpus est un bloc qui refusait toutes les extensions de fichiers PHP, laissé par un durcissement recopié sur un forum.

La réparation consiste à remettre le bloc standard de WordPress, et rien d'autre :

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Plutôt que de supprimer l'ancien, renommez-le en htaccess-ancien et créez le nouveau à côté.

Le fautif n'est pas toujours celui de la racine, chaque dossier peut avoir le sien et find . -name ".htaccess" les liste tous. Si le fichier se réécrit après chaque correction, une extension le régénère : désactivez-la d'abord. Sous nginx ou LiteSpeed, le .htaccess n'est pas lu, ou seulement en partie, ce qui rend cette section sans objet.

Cause 2 : le pare-feu applicatif de l'hébergeur

Le .htaccess est propre, le 403 est toujours là, et vous n'êtes bloqué que sur certaines actions. Presque tous les mutualisés font tourner un pare-feu applicatif, souvent ModSecurity, parfois celui du panneau : il inspecte les requêtes, refuse celles qui ressemblent à une attaque connue, se trompe régulièrement, et vous n'avez aucune visibilité dessus depuis WordPress.

Les signes qui le désignent : un refus reproductible sur une action précise, publier un contenu contenant certains mots, appeler xmlrpc.php ou admin-ajax.php. Rien n'apparaît dans les journaux de WordPress, puisque la requête n'y est jamais arrivée.

Certains panneaux exposent un interrupteur, le pare-feu CDN chez OVH, les réglages ModSecurity en Plesk. Coupez-le le temps d'un test, rechargez la page en panne, remettez-le : vous cherchez seulement à savoir si c'est lui.

Ce que vous demandez au support change tout : l'heure de votre test à la seconde, l'URL exacte, votre adresse IP publique, et la question « quelles règles se sont déclenchées à ce moment-là, avec leur numéro ». Demandez l'exclusion de cette règle pour votre site, pas la désactivation du pare-feu.

Si l'hébergeur ne refuse pas vos requêtes mais les compte, parce que vous dépassez une limite de ressources ou de connexions simultanées, le code renvoyé n'est plus un 403 mais un 503, et la panne se diagnostique autrement, dans le guide de l'erreur 503.

Cause 3 : une adresse IP ou une provenance bloquée

C'est la sortie du test du téléphone. Le site va bien, c'est vous qui n'y avez plus droit.

Trois endroits ont pu prendre la décision. L'extension de sécurité, qui tient sa propre liste et y ajoute une adresse après quelques échecs de connexion. Le pare-feu de l'hébergeur, qui a la sienne. Le service placé devant votre site, qui peut refuser une plage entière.

Partagez le point d'accès de votre téléphone à votre ordinateur : si le tableau de bord s'ouvre, la liste de blocage de votre extension de sécurité contient peut-être votre adresse, avec la date et la raison. Sans tableau de bord, renommez le dossier de l'extension dans wp-content/plugins/, wordfence en wordfence-off par exemple, et WordPress la considère comme désactivée.

La variante qui déroute le plus est un 403 qui ne frappe que les liens ouverts depuis l'application d'un réseau social : ces applications passent par une adresse intermédiaire, et c'est cette provenance qui est refusée. Pensez aussi au réseau privé virtuel. Sous la vidéo la plus vue au monde sur le sujet, un commentaire résume le diagnostic en une phrase, ce n'était pas l'historique du navigateur, c'était le VPN.

Cause 4 : les droits, et surtout le propriétaire des fichiers

C'est la cause de la page de quinze octets, et la seule où le chmod mérite d'être tapé. Les valeurs de référence sont 755 sur les dossiers, 644 sur les fichiers.

Reste un cas que le corpus français ignore et qui explique les 403 les plus résistants : ce n'est pas le droit qui est mauvais, c'est le propriétaire. Un site restauré par un mauvais compte système donne des fichiers en 644, corrects en apparence, illisibles pour le serveur quel que soit le chmod. Le journal affirme alors qu'un fichier n'existe pas alors que vous le voyez dans votre gestionnaire. La réparation est un changement de propriétaire, et sur un mutualisé c'est le support qui doit le faire.

Avec un accès SSH, la remise à plat tient en deux commandes lancées depuis la racine :

find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

Quand le 403 ne frappe que /wp-admin

Le site public s'affiche parfaitement et seule l'administration refuse de s'ouvrir. La dissymétrie est déjà une information : le serveur répond, PHP tourne, WordPress démarre, donc ce qui bloque est une règle ciblée.

Trois pistes. Un .htaccess propre à wp-admin, déposé par une extension de sécurité ou par une protection par mot de passe mal réglée. Une règle du pare-feu visant wp-login.php, cible de la quasi-totalité des attaques par force brute. Une extension qui protège la page de connexion et qui a banni votre adresse. Et si /wp-admin bascule vers une adresse contenant upgrade.php au lieu de renvoyer 403, ce n'est pas un blocage mais une mise à jour de base de données en attente, que le bouton proposé termine.

Vérifiez aussi le code renvoyé. Un 502 sur /wp-admin ressemble beaucoup à un 403 sur /wp-admin, la page est aussi nue, le symptôme aussi asymétrique, et le diagnostic n'a rien de commun : c'est le guide de l'erreur 502 qu'il faut ouvrir. Et si l'administration ne renvoie aucun code particulier mais vous ramène en boucle à la page de connexion, la piste est du côté des cookies et de l'adresse du site, que traite le guide sur l'administration WordPress inaccessible.

Les journaux, et la ligne exacte à y chercher

Toutes les pages du monde disent « consultez vos journaux », aucune ne dit où ils sont ni ce qu'il faut y lire.

Où ils sont. En cPanel, un fichier error_log apparaît dans le dossier où l'erreur s'est produite, et le panneau propose un écran « Erreurs » avec les dernières lignes. Chez OVH en mutualisé, les journaux ne sont pas dans l'espace FTP du site : ils vivent sur un espace de logs séparé, accessible depuis l'espace client, un fichier par jour. En Plesk, /var/www/vhosts/votre-domaine.fr/logs/error_log. Sur un serveur que vous administrez, /var/log/apache2/error.log ou /var/log/httpd/error_log selon la distribution.

Ce qu'il faut y lire. Trois lignes suffisent à trancher.

Une règle du serveur ou d'un .htaccess a refusé la requête :

[authz_core:error] [client 203.0.113.7:52544] AH01797: client denied by
server configuration: /home/compte/public_html/wp-login.php

AH01797 désigne toujours une directive de refus, jamais un problème de droits.

Un dossier du chemin n'a pas son droit d'exécution :

[core:error] AH00035: access to /wp-login.php denied (filesystem path
'/home/compte/public_html/wp-login.php') because search permissions are
missing on a component of the path

Là, et seulement là, le chmod 755 sur les dossiers du chemin est la réparation.

PHP n'a pas pu ouvrir le script, ce qui correspond à la page de quinze octets :

Unable to open primary script: /home/compte/public_html/index.php
(Permission denied)

La trace du pare-feu applicatif porte la mention ModSecurity: Access denied with code 403 et, entre crochets, un identifiant de règle. C'est ce numéro qu'il faut donner au support, le seul élément qui permette une exclusion ciblée plutôt qu'une désactivation générale. Sur la plupart des mutualisés ce journal ne vous est pas accessible, d'où l'importance d'une demande précise.

« Je n'ai rien touché », et pourquoi c'est parfois vrai

Un fichier PHP rendu illisible continue d'être servi normalement tant que le pool PHP n'a pas redémarré, parce que le cache d'opcode a gardé la version compilée. Mesuré : 200 avant le redémarrage du pool, 403 après. Entre les deux il s'écoule parfois des heures, et personne n'a effectivement rien fait.

La bonne question n'est donc pas « qu'est-ce qui s'est passé juste avant », c'est « qu'est-ce qui a bougé dans les vingt-quatre heures ». Une mise à jour automatique nocturne, une intervention de l'hébergeur, un durcissement appliqué la veille au soir.

Si rien n'a marché

Le tableau de bord s'ouvre, le site public renvoie 403, et des comptes que vous n'avez pas créés apparaissent. Cette combinaison oriente vers une compromission, et le refus n'est qu'un symptôme.

Vous n'avez accès à aucun journal. Demandez au support les lignes correspondant à l'horaire exact d'un test que vous venez de faire, avec l'URL et votre adresse IP.

Notre forfait couvre la panne : rendre le site accessible et documenter ce qui le refusait. Il ne couvre pas la reconstruction d'une mise en page abîmée dans un constructeur, ni la refonte d'un thème. Si vous préférez ne pas y passer la soirée, le dépannage d'un site WordPress qui refuse l'accès est notre métier.

Comment éviter que ça recommence

Mettez l'adresse IP publique de votre bureau en liste blanche dans votre extension de sécurité, avant d'en avoir besoin. C'est ce qui vous évitera de vous enfermer dehors le jour où vous vous tromperez trois fois de mot de passe.

Ne recopiez pas de blocs de durcissement trouvés sur un forum sans savoir ce que chaque ligne refuse. La personne qui a subi le cas le mieux documenté du corpus ne savait plus ce qu'elle avait collé, ni quand.

Repérez dès maintenant où votre hébergeur expose ses journaux, et vérifiez toute correction ailleurs que sur l'accueil. Un refus ciblé se cache très bien derrière un accueil qui répond.

Le site boulangerie-lemoulin.fr de nouveau accessible après retrait de la règle de refus, page d'accueil complète
Le site boulangerie-lemoulin.fr de nouveau accessible après retrait de la règle de refus, page d'accueil complète

Questions fréquentes

Comment supprimer erreur 403 ?

Ouvrez le site depuis un téléphone en 4G, wifi coupé : s'il s'affiche, votre adresse IP est bloquée et aucun réglage de fichier n'y changera rien. Sinon regardez la page de refus, quinze octets et le texte Access denied. désignent des droits, la page du serveur désigne une règle. Renommez ensuite le .htaccess de la racine et rechargez. Si le site revient, la règle était dedans ; sinon, demandez à l'hébergeur quelle règle de son pare-feu s'est déclenchée à l'heure de votre test.

C'est quoi le code erreur 403, et pourquoi un site est forbidden ?

Un code de réponse HTTP qui signifie « j'ai compris ta demande et je refuse d'y répondre ». Il se distingue du 401, qui demande de s'identifier, et du 404, qui dit que la ressource n'existe pas : avec un 403, elle existe et le serveur sait où elle est. Une règle a refusé la requête, dans le .htaccess, dans le pare-feu de l'hébergeur, dans une extension de sécurité, dans un blocage d'adresse IP, ou plus rarement dans des droits de fichiers. Le mot forbidden est celui qui s'affiche à l'écran, y compris sur les sites en français.

Pourquoi « you don't have permission to access this resource » ?

C'est le texte standard de la page de refus d'Apache. Malgré le mot « permission », il ne désigne pas les droits de vos fichiers dans la majorité des cas : c'est le message générique affiché pour tout refus. La distinction se fait sur le poids de la page et sur le journal.

Comment débloquer 403 forbidden ?

Si le site est le vôtre, suivez l'arbre de diagnostic de ce guide : il mène à la règle qui refuse, et l'accès revient en la retirant. Si vous êtes un visiteur, il n'y a rien à contourner. Essayez une autre connexion, désactivez votre VPN, et si le refus persiste prévenez le propriétaire. Un pare-feu qui bloque fait son travail, et le seul déblocage légitime vient de celui qui l'a réglé.

Décrire ma panne