# Erreur 403 Forbidden sur WordPress : causes et solutions

> Erreur 403 Forbidden sur WordPress : droits des fichiers, .htaccess, nginx, WAF et ModSecurity. Trouvez la règle qui bloque et débloquez l’accès.

- Auteur : WordPress Développement
- Publié le : 2026-10-02
- Mis à jour le : 2026-10-02
- URL : https://www.wpmoderne.fr/erreurs-wordpress/erreur-403/

> Le serveur a compris la requête mais refuse de la servir : droits de fichiers erronés, règle .htaccess ou nginx, IP bannie ou pare-feu (WAF, ModSecurity). Le journal d’erreurs du serveur indique quelle règle a refusé l’accès.

Votre navigateur affiche « 403 Forbidden », parfois accompagné de « You don’t have permission to access this resource » (Apache) ou de « nginx » en pied de page. Selon le cas, la page d’accueil, l’administration, un fichier précis ou une seule action (un envoi de formulaire, un appel `admin-ajax.php`, une route de l’API REST) est refusée.

Le 403 se distingue du 401 et du 404 : le serveur **a bien trouvé** la ressource et **sait qui vous êtes ou ce que vous demandez**, mais une règle lui interdit de répondre. Il s’agit presque toujours d’une règle de permissions ou de sécurité, pas d’un bogue de WordPress.

## Ce que signifie cette erreur

Le code 403 « Forbidden » est un libellé standard que WordPress connaît (`get_status_header_desc()` dans `wp-includes/functions.php`), mais l’erreur est produite avant PHP dans la majorité des cas. Les sources possibles, de la plus proche du disque à la plus lointaine :

- **Le système de fichiers** : le processus du serveur web n’a pas le droit de lire le fichier ou de traverser un dossier (mauvais propriétaire, droits trop restrictifs, SELinux) ;
- **La configuration du serveur** : un `deny all` (nginx), un `Require all denied` ou un `Deny from all` (Apache), l’absence de fichier d’index dans un dossier dont le listing est désactivé ;
- **Un pare-feu applicatif** (ModSecurity avec ses règles OWASP, WAF d’hébergeur, WAF de CDN) qui juge la requête suspecte ;
- **Un blocage d’adresse IP** : fail2ban, extension de sécurité WordPress, règle de pare-feu, pays bloqué ;
- **WordPress et ses extensions**, qui répondent 403 de leur propre initiative : l’API REST renvoie par exemple 403 à un utilisateur connecté sans le droit requis, ou à une requête dont le nonce est invalide (`rest_cookie_invalid_nonce`, « Cookie check failed », dans `wp-includes/rest-api.php`).

Les messages que WordPress affiche lui-même pour un droit manquant, comme « Désolé, vous n’avez pas l’autorisation d’accéder à cette page. », relèvent d’une autre fiche : [accès refusé à une page](https://www.wpmoderne.fr/erreurs-wordpress/acces-refuse-page/).

## Diagnostic rapide

| Symptôme / constat | Cause probable | À vérifier |
| --- | --- | --- |
| Tout le site en 403, y compris la page d’accueil | Droits de fichiers, dossier sans index, règle globale | Droits du dossier racine ; journal du serveur ; présence d’un fichier `index.php` |
| 403 seulement sur `/wp-admin/` ou `wp-login.php` | Règle de sécurité (liste d’IP, WAF, extension de sécurité) | Votre IP actuelle ; règles de l’hébergeur ; extension de sécurité |
| 403 à l’envoi d’un formulaire ou d’un import | WAF ou ModSecurity qui bloque le contenu de la requête | Journal d’audit ModSecurity ; identifiant de la règle |
| 403 sur un seul fichier ou dossier (images, `uploads`) | Droits ou règle `.htaccess` propre à ce dossier | `.htaccess` du dossier ; droits du fichier |
| 403 sur `/wp-json/` ou une route de l’API | Pare-feu, extension qui restreint l’API REST, nonce invalide | Fiche API REST ; extensions de sécurité |
| 403 depuis un seul réseau ou un seul pays | Blocage d’IP ou géoblocage | Essai depuis un autre réseau ; liste des bans (fail2ban, CDN) |

## Les causes les plus fréquentes

1. **Un pare-feu applicatif ou ModSecurity** qui bloque une requête légitime (contenu de formulaire, JSON, import).
2. **Des droits ou un propriétaire erronés** sur les fichiers, après une migration, une restauration ou un déploiement.
3. **Une adresse IP bannie** par fail2ban, un CDN, l’hébergeur ou une extension de sécurité, souvent après des tentatives de connexion échouées.
4. **Un fichier `.htaccess` modifié** (règle `Deny`, blocage de pays, protection de `wp-admin`) ou une configuration nginx trop restrictive.
5. **Un dossier sans fichier d’index** alors que le listing est désactivé, typiquement quand la réécriture d’URL n’est pas en place.
6. **Une protection anti-hotlink** ou une règle sur les types de fichiers qui interdit un accès normal.

## Solutions pas à pas

Sauvegardez avant de modifier des droits ou des fichiers de configuration. Du moins invasif au plus technique :

### 1. Éliminer les causes côté visiteur

Essayez depuis un autre réseau (connexion mobile) et un autre navigateur. Si le site fonctionne ailleurs, votre IP est bloquée : désactivez un éventuel VPN, ou faites débannir l’adresse (solution 6). Videz le cache du navigateur et du plugin de cache, car un 403 mis en cache est resservi tel quel.

### 2. Lire le journal d’erreurs du serveur

Le journal nomme la règle qui a refusé. Cherchez ces motifs à l’heure de votre essai :

```
# Apache : « AH01630: client denied by server configuration »
sudo tail -n 50 /var/log/apache2/error.log

# nginx : « access forbidden by rule » ou « directory index of ... is forbidden »
sudo tail -n 50 /var/log/nginx/error.log

# ModSecurity : « ModSecurity: Access denied with code 403 »
sudo grep -i 'access denied with code 403' /var/log/apache2/error.log | tail -n 5
```

Sur un mutualisé, ces journaux se trouvent dans le panneau de l’hébergeur. La méthode générale de lecture est détaillée dans la fiche [erreur 500](https://www.wpmoderne.fr/erreurs-wordpress/erreur-500/).

### 3. Vérifier les droits et le propriétaire des fichiers

Les dossiers doivent être lisibles et traversables (755), les fichiers lisibles (644), et appartenir à l’utilisateur du site. Depuis la racine du site, en SSH :

```
cd /var/www/exemple/html
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
sudo chown -R utilisateur:groupe .
ls -ld . wp-content wp-content/uploads
```

Remplacez le chemin, l’utilisateur et le groupe par ceux de votre installation. En SFTP, faites un clic droit sur le dossier racine puis « Attributs » pour appliquer 755 aux dossiers et 644 aux fichiers. Sur un système avec SELinux, un contexte incorrect donne le même symptôme : consultez le journal d’audit.

### 4. Remettre le .htaccess de WordPress par défaut

Sauvegardez le fichier `.htaccess` existant (renommez-le en `.htaccess.old`), puis créez-en un contenant les règles par défaut de WordPress :

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

Si le 403 disparaît, une règle de l’ancien fichier en était la cause : réintroduisez vos règles une par une. Sinon, passez à la suite. Sur Apache 2.4, `Deny from all` ne fonctionne que si `mod_access_compat` est chargé ; la syntaxe moderne est `Require all denied`.

### 5. Corriger la configuration nginx

Avec nginx, un dossier sans index ou sans repli sur `index.php` produit « directory index … is forbidden ». Vérifiez que le bloc principal ressemble à ceci :

```
server {
    root /var/www/exemple/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
```

Cherchez aussi dans la configuration un `deny all;` ou un `allow` trop restrictif sur `wp-admin` ou `wp-login.php` : `sudo grep -rn 'deny' /etc/nginx/`. Après modification : `sudo nginx -t && sudo systemctl reload nginx`.

### 6. Débloquer une IP bannie ou un faux positif du WAF

Si fail2ban est installé, listez les prisons et retirez votre adresse :

```
sudo fail2ban-client status
sudo fail2ban-client status nom-de-la-prison
sudo fail2ban-client set nom-de-la-prison unbanip 203.0.113.10
```

Pour un faux positif ModSecurity, relevez l’identifiant de la règle dans le journal d’audit, puis désactivez-la **uniquement** pour l’URL concernée, jamais globalement :

```
<LocationMatch "^/wp-admin/admin-ajax\.php$">
    SecRuleRemoveById 949110
</LocationMatch>
```

L’identifiant 949110 est un exemple : remplacez-le par celui de votre journal. Avec le WAF d’un CDN ou de l’hébergeur, créez une règle d’exception pour l’URL ou l’adresse concernée plutôt que d’éteindre le pare-feu. Le cas d’une intégration légitime bloquée est traité dans [403 Forbidden : quand un WAF bloque une intégration légitime](https://www.wpmoderne.fr/securite/waf-bloque-integration-legitime-403/), et la mise en place d’un filtrage propre dans [WAF et fail2ban pour WordPress](https://www.wpmoderne.fr/securite/waf-fail2ban-proteger-wordpress/).

### 7. Sans accès à l’administration ni au serveur

Connectez-vous en SFTP ou par le gestionnaire de fichiers de l’hébergeur : renommez `wp-content/plugins` en `plugins.off` pour écarter une extension de sécurité qui bloque, et contrôlez le `.htaccess` et les droits comme ci-dessus. Si rien ne change, contactez l’hébergeur : son pare-feu mutualisé a peut-être banni votre IP ou une règle de votre requête, et lui seul peut le lever.

## Prévenir l’erreur

- Appliquez les droits **755 / 644** et le bon propriétaire après chaque migration ou restauration.
- Avant d’activer un WAF ou des règles ModSecurity strictes, passez-les un temps en mode détection et examinez les faux positifs.
- Ne durcissez `wp-admin` par liste d’IP que si votre adresse est fixe, et gardez un accès de secours.
- Conservez une copie du `.htaccess` et de la configuration nginx qui fonctionnent, sous gestion de version.
- Testez les formulaires, l’API REST et `admin-ajax.php` après toute modification des règles de sécurité.
