Skip to content
EN
← Все статьи

Ошибка 403 Forbidden: что значит и как исправить на сайте

Ноутбук со страницей ошибки и монитор с терминалом на рабочем столе

Ошибка 403 (403 Forbidden, «доступ запрещён») означает, что сервер получил и понял запрос, но отказывается его выполнять: у запрашивающего нет прав на этот файл, каталог или адрес. Сайт при этом работает. Причина — в правилах доступа на сервере: права файлов, запрет в .htaccess или nginx, блокировка по IP, стране или правилу WAF.

Ниже — отдельно, что делать посетителю, который увидел «403 Forbidden», и как владельцу сайта или разработчику API найти и убрать причину: по сообщениям в логах, заголовкам ответа и конфигурации сервера.

Что значит ошибка 403: код ответа HTTP 403 Forbidden

По RFC 9110 §15.5.4 код 403 означает, что сервер понимает запрос, но не авторизует его. Если в запросе были учётные данные (логин, токен, ключ API), сервер считает их недостаточными: повторять запрос с теми же данными бессмысленно, помочь могут только другие данные или изменение правил на сервере. Если учётных данных не было вовсе, а нужен вход, корректнее ответить 401 — но на практике многие сайты отдают 403 в обоих случаях.

Важная деталь из того же RFC: сервер, который не хочет раскрывать само существование закрытого ресурса, вправе вместо 403 ответить 404. Поэтому «страница не найдена» на приватном адресе — не всегда ошибка, иногда это та же 403, только замаскированная. Подробный разбор кода есть в справке MDN по коду 403.

Как выглядит код ошибки 403 для пользователя, зависит от сервера и защиты перед ним:

  • Apache: «Forbidden. You don’t have permission to access this resource.»
  • nginx: заголовок «403 Forbidden» и строка «nginx» под ним.
  • Cloudflare: «Sorry, you have been blocked» или «Error 1020: Access denied» с идентификатором Ray ID.
  • IIS: «403 — Forbidden: Access is denied», в логе — подстатус (например, 403.14 — просмотр каталога запрещён).
  • Браузер или приложение: «HTTP ERROR 403», «Доступ запрещён», «Request failed with status code 403».

Если 403 показывает не браузер, а приложение — сервисы Apple и iMazing, Контур, магазины внутриигровых покупок, игровые лаунчеры, — это отказ серверов конкретного сервиса. Решается он через его поддержку или настройки аккаунта, а эта статья про сайты и API.

Чем 403 отличается от 401, 404 и других кодов

Коды 4xx похожи тем, что проблема на стороне запроса, но смысл у них разный. Путаница между ними приводит к неверной диагностике: 401 чинят входом, 404 — адресом, 403 — правами.

КодЧто говорит серверПоможет ли вход или новый токенГде искать причину
401 Unauthorized«Кто вы? Представьтесь»: учётных данных нет или они неверныДа, для этого код и существует; ответ содержит заголовок WWW-AuthenticateЛогин, токен, срок его жизни, заголовок Authorization
403 Forbidden«Знаю, кто вы, но сюда нельзя» или «сюда нельзя никому»Только если у другого аккаунта или ключа есть нужные праваПрава файлов, deny-правила, роли пользователя, WAF, IP- и гео-блокировки
404 Not Found«Такого ресурса нет» (или сервер скрывает, что он есть)НетАдрес, маршрутизация, удалённые страницы
429 Too Many Requests«Слишком часто, подождите»Нет, нужно снизить частоту; время ожидания — в Retry-AfterЛимиты запросов
451 Unavailable For Legal Reasons«Закрыто по юридическим причинам»НетТребования закона или правообладателя

Подробнее о соседних кодах — в разборах ошибки 401 Unauthorized и ошибки 404 Not Found.

Ошибка 403 на сайте: что делать, если вы посетитель

Посетитель не может поменять права на чужом сервере, но может понять, закрыто ли всё для всех или только для него, и дать владельцу данные для разбора.

  1. Проверьте адрес. 403 часто возникает, когда адрес ведёт на каталог без файла (/uploads/, /files/2024/) или на служебный путь. Уберите лишнюю часть адреса и откройте главную страницу.
  2. Обновите страницу без кэша: Ctrl+F5 в Windows, Cmd+Shift+R в macOS. Браузер мог показать сохранённую ошибку.
  3. Удалите cookie этого сайта. Истёкшая сессия или устаревший CSRF-токен в форме нередко дают 403 при отправке формы. В Chrome: значок слева от адреса → «Настройки сайтов» → «Удалить данные».
  4. Войдите в аккаунт или проверьте роль. Страницы личного кабинета, админки и закрытых разделов отдают 403, если у вашей учётной записи нет доступа.
  5. Отключите расширения, которые меняют запросы (подмена User-Agent, удаление Referer). Защита от хотлинка отвечает 403 на картинки и файлы, если в запросе нет ожидаемого Referer.
  6. Проверьте, видят ли 403 другие. Откройте сайт с другого устройства или в другой сети либо проверьте ответ извне через проверку HTTP-заголовков enterno. Если извне приходит 200, а у вас 403 — заблокированы ваш IP, подсеть или регион.

Если заблокированы именно вы, напишите владельцу или в поддержку сайта. Приложите время ошибки, свой IP (его показывает определение IP), адрес страницы и, если это Cloudflare, Ray ID со страницы ошибки — по нему администратор найдёт событие за минуту. Блокировка по стране — решение владельца; снять её может только он.

Почему сервер выдаёт ошибку 403: частые причины

  1. Неправильные права файлов — 600 или 640 вместо 644, и веб-сервер не может прочитать файл.
  2. Нет права на «проход» по каталогу — у одного из каталогов на пути к файлу нет бита x для пользователя веб-сервера (например, домашний каталог с правами 700).
  3. Владелец файла — не пользователь веб-сервера (root:root вместо www-data:www-data), а права закрыты для остальных.
  4. Отсутствует index-файл в директории, а просмотр каталога (directory listing) отключён.
  5. Блокировка в .htaccess или nginx — Deny from all, Require all denied, deny all, слишком широкий шаблон в location.
  6. ModSecurity или WAF-правило заблокировало запрос, похожий на атаку: SQL-фрагменты в параметрах, необычный User-Agent, большой POST.
  7. IP-блокировка через Cloudflare, fail2ban, firewall, плагин безопасности CMS или белый список IP для админки.
  8. Гео-блокировка — сервер или CDN закрывает доступ из отдельных стран.
  9. SELinux/AppArmor запрещает веб-серверу читать файл с чужим контекстом безопасности.
  10. Hotlink protection — Referer не соответствует разрешённым доменам.
  11. Права приложения — роль пользователя или ключ API не имеет доступа к ресурсу, CSRF-проверка не пройдена.

Сообщение в логе обычно прямо называет причину. Сводка самых частых строк:

Строка в error.logСерверЧто означаетЧто сделать
open() "..." failed (13: Permission denied)nginxНет прав на чтение файла или на проход по каталогуПрава 644/755, владелец, SELinux-контекст
directory index of "..." is forbiddennginxВ каталоге нет файла из директивы index, а autoindex выключенДобавить index-файл или исправить index/try_files
access forbidden by rulenginxСработала директива denyНайти правило: nginx -T | grep -n deny
AH01630: client denied by server configurationApache 2.4Запрет Require в конфиге или .htaccessПроверить Require и Deny для этого пути
AH01276: Cannot serve directory ...: No matching DirectoryIndexApacheНет index-файла, просмотр каталога запрещён Options -IndexesДобавить index-файл или поправить DirectoryIndex
AH00035: access to ... denied ... because search permissions are missingApacheУ каталога на пути нет права xchmod 755 на каталоги пути
[id "949110"] Inbound Anomaly Score ExceededModSecurityЗапрос набрал порог аномалий OWASP CRSНайти правила, давшие баллы, и сделать точечное исключение

Как проверить, кто отдаёт 403: сервер, WAF или CDN

Сначала важно понять, какой слой отвечает: ваш веб-сервер, приложение, WAF-модуль или CDN перед сайтом. От этого зависит, в каком логе искать.

  1. Проверьте ответ снаружи через HTTP Header Checker: он покажет код, цепочку редиректов и все заголовки. server: cloudflare и заголовок cf-ray означают, что ответ мог сформировать Cloudflare; cf-mitigated: challenge — что сработала проверка посетителя.
  2. Прогоните Security Scanner — он покажет, не выдают ли заголовки версию сервера и модулей, и какие защитные заголовки настроены.
  3. Сравните ответы для разных клиентов из консоли.
# Linux / macOS: только заголовки ответа
curl -sI https://example.com/page

# Тот же запрос с браузерным User-Agent: если код изменился, блокирует WAF по User-Agent
curl -sI -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" https://example.com/page

# Обход CDN для диагностики своего сервера: запрос прямо на IP origin
curl -sI --resolve example.com:443:203.0.113.10 https://example.com/page

# Windows PowerShell: вызывайте именно curl.exe, а не псевдоним Invoke-WebRequest
curl.exe -sI https://example.com/page

Если запрос напрямую на origin возвращает 200, а через домен — 403, блокирует CDN или WAF перед сервером. Если 403 и напрямую — ищите причину в логах своего сервера:

# nginx
tail -50 /var/log/nginx/error.log | grep -i "forbidden\|403\|denied"

# Apache
tail -50 /var/log/apache2/error.log
tail -50 /var/log/apache2/access.log | grep " 403 "

# ModSecurity
tail -50 /var/log/modsec_audit.log

# Проверка прав
ls -la /var/www/html/problem-file
# Должно быть: -rw-r--r-- 1 www-data www-data

# Права на каждый каталог по пути к файлу
namei -l /var/www/html/problem-file

Где лежат логи и как настроить их формат, чтобы в access.log попадал нужный контекст, — в статье логи nginx. В CentOS и RHEL логи Apache лежат в /var/log/httpd/, а не в /var/log/apache2/.

Как исправить ошибку 403 на своём сервере

Решения идут в том порядке, в котором причины встречаются чаще всего.

1. Исправить права файлов и владельца

# Файлы
find /var/www/html -type f -exec chmod 644 {} \;
# Директории
find /var/www/html -type d -exec chmod 755 {} \;
# Владелец
chown -R www-data:www-data /var/www/html

Пользователь веб-сервера зависит от дистрибутива: www-data в Debian и Ubuntu, apache или nginx в CentOS, Rocky и AlmaLinux. Посмотреть его можно командой ps -eo user,comm | grep -E "nginx|apache|httpd|php-fpm". Файлы с секретами (wp-config.php, .env) можно оставить 640 или 600 — важно лишь, чтобы их читал пользователь PHP-FPM.

2. Проверить index-файл

# nginx
index index.php index.html;

# Apache
DirectoryIndex index.php index.html

В nginx 403 на каталог даёт и типичная строка try_files $uri $uri/ =404;: если каталог существует, а index-файла в нём нет, nginx отвечает 403. Для SPA и фронт-контроллеров нужна другая форма: try_files $uri $uri/ /index.php?$args; или /index.html. Включать autoindex on ради устранения 403 не стоит — это откроет список файлов всем.

3. Найти блокировку в .htaccess

# Ищите:
Deny from all
Require all denied

# Замените на:
Require all granted

Открывайте доступ только к тому, что действительно должно быть публичным: запрет на .env, .git и служебные каталоги должен остаться. Не смешивайте синтаксис Apache 2.2 (Order/Deny) и 2.4 (Require) в одном блоке — результат трудно предсказать. Найти все правила быстро поможет grep -rn -E "Deny|Require|Order" /var/www/html --include=.htaccess. Подробнее — в разборе файла .htaccess и в документации Apache по управлению доступом.

4. nginx: deny-директивы

# Проблемная строка:
location ~ \.(env|git|htaccess)$ {
    deny all;
}

# Если блокировка слишком широкая — пересмотрите паттерн

Весь итоговый конфиг со всеми include выводит nginx -T. Директивы allow и deny проверяются по порядку до первого совпадения, поэтому deny all; выше allow закроет доступ всем. Синтаксис описан в документации модуля ngx_http_access_module. После правки — nginx -t && systemctl reload nginx.

5. Ошибка 403 только по HTTPS

Если по http:// страница открывается, а по https:// отдаёт 403, у блока для порта 443 свои root, allow/deny или правила доступа. Сравните блоки:

# nginx: все listen, root и deny с номерами строк
nginx -T 2>/dev/null | grep -n -E "listen|server_name|root|deny|allow"

# Apache: какие виртуальные хосты обслуживают 80 и 443
apachectl -S

6. ModSecurity: ложное срабатывание

# Определите правило в логе:
# [id "949110"] [msg "Inbound Anomaly Score Exceeded"]

# Отключите конкретное правило для URL
SecRule REQUEST_URI "@beginsWith /api/safe-endpoint" \
    "id:1001,phase:1,ctl:ruleRemoveById=949110,nolog,allow"

Правило 949110 — итоговое: оно только суммирует баллы. Точнее отключать те правила, что начислили баллы (их id стоят в том же аудит-логе выше), и только для конкретного пути или параметра. Отключение ModSecurity целиком ради одной формы оставит сайт без защиты.

7. Проверить IP-блокировки

# fail2ban
fail2ban-client status
fail2ban-client status sshd
fail2ban-client set sshd unbanip 198.51.100.7

# iptables
iptables -L -n | grep DROP
iptables -D INPUT -s 198.51.100.7 -j DROP

# nftables
nft list ruleset | grep -n 198.51.100.7

Заблокированный через firewall IP обычно получает таймаут, а не 403. Ответ 403 приходит, когда запрет стоит в веб-сервере (deny, Require not ip), в плагине безопасности CMS или в WAF.

8. SELinux и AppArmor (CentOS/RHEL, Ubuntu)

ls -Z /var/www/html/
# Должно быть httpd_sys_content_t

restorecon -Rv /var/www/html/
chcon -t httpd_sys_content_t /var/www/html/newfile.php

# Недавние отказы SELinux
ausearch -m avc -ts recent

Типичный случай — файлы перенесли командой mv из домашнего каталога: они сохраняют контекст исходного места, и права 644 не помогают, пока не выполнить restorecon. В Ubuntu аналогичные отказы AppArmor видно в journalctl -k | grep -i apparmor.

9. PHP-FPM: «Access denied.»

Если вместо страницы приходит 403 с текстом «Access denied.», PHP-FPM отказался исполнять файл, расширение которого не входит в security.limit_extensions (по умолчанию только .php). Обычно это значит, что в nginx на PHP-FPM отправляются не только PHP-файлы — проверьте location ~ \.php$, а не расширяйте список.

10. WordPress

  • Переименуйте .htaccess, зайдите в Настройки → Постоянные ссылки для регенерации.
  • Проверьте плагины безопасности (Wordfence, iThemes) — могли заблокировать IP.
  • chmod 644 wp-config.php, chmod 755 wp-content/
  • Если админка недоступна, временно отключите все плагины, переименовав каталог wp-content/plugins по SFTP, и включайте их по одному.

«Forbidden. You don’t have permission to access this resource» в Apache

Эту страницу выдаёт Apache 2.4; в старых версиях текст звучал как «You don’t have permission to access / on this server». Сама фраза причину не называет — она всегда есть в error.log рядом с IP клиента. Три сообщения покрывают почти все случаи:

  • AH01630: client denied by server configuration — сработал Require all denied или Deny from all. Частая причина после переезда на Apache 2.4 — блок <Directory> для нового DocumentRoot без Require all granted.
  • AH01276 — в каталоге нет index-файла, а Options -Indexes запрещает листинг.
  • AH00035 ... search permissions are missing — у каталога на пути нет бита x.

Минимальный корректный блок для каталога сайта в Apache 2.4:

<Directory /var/www/html>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

После правки — apachectl configtest и systemctl reload apache2 (в CentOS — httpd).

403 от Cloudflare и WAF

Если в ответе есть cf-ray, а в логах вашего сервера этого запроса нет вовсе, запрос остановил Cloudflare. Страница «Sorry, you have been blocked» означает срабатывание правила WAF или управляемых правил, «Error 1020» — пользовательского правила доступа. Что делать:

  1. Возьмите Ray ID со страницы ошибки или из заголовка cf-ray.
  2. В панели Cloudflare откройте раздел Security → Events и найдите событие по Ray ID или IP: там указано, какое правило сработало и почему.
  3. Сузьте правило или добавьте исключение для конкретного пути, IP партнёра или верифицированных ботов, а не отключайте защиту целиком.

Разбор кода 1020 — в статье Cloudflare Error 1020 Access Denied. Для других WAF (Qrator, DDoS-Guard, облачные WAF хостингов) логика та же: идентификатор запроса на странице блокировки → журнал событий WAF → точечное исключение.

Ошибка 403 из-за блокировки по стране или IP

Гео-блокировка — сознательное решение владельца: закрыть сайт для стран, откуда идут атаки или спам, или ограничить доступ к админке. Проблемы начинаются, когда правило задевает своих: базы GeoIP ошибаются для мобильных операторов и адресов облачных провайдеров, а корпоративный NAT выводит сотни сотрудников через один IP, который мог попасть под автоматический бан.

Пример гео-ограничения в nginx с модулем GeoIP2 — ответ 403 только тем, кого вы решили закрыть:

# http-контекст: переменная $geoip2_data_country_code задаётся модулем geoip2
map $geoip2_data_country_code $allowed_country {
    default yes;
    XX      no;   # код страны, которую нужно закрыть
}

# server-контекст
if ($allowed_country = no) {
    return 403;
}

Если на такие правила жалуются посетители, проверьте актуальность базы GeoIP, добавьте белый список для партнёров и не распространяйте блокировку на поисковых роботов, если сайт должен индексироваться. Для посетителей в закрытых регионах полезно отдавать страницу с объяснением и контактом, а не голое «403 Forbidden».

Request failed with status code 403: ошибка 403 в API, axios и requests

В API код 403 почти всегда означает «аутентификация прошла, авторизация — нет». Клиентские библиотеки показывают его по-разному: axios бросает AxiosError: Request failed with status code 403, Python requests после raise_for_status() — 403 Client Error: Forbidden for url, а fetch исключения не бросает вовсе, и 403 видно только в response.status.

Главное правило — читать тело ответа: сервер почти всегда объясняет причину там.

// axios
try {
  await axios.get('https://api.example.com/v1/items', {
    headers: { Authorization: `Bearer ${token}` },
  });
} catch (err) {
  if (err.response?.status === 403) {
    console.log(err.response.headers);
    console.log(err.response.data);   // здесь причина: scope, IP, план
  }
}
# Python requests
import requests

r = requests.get(
    "https://api.example.com/v1/items",
    headers={"Authorization": f"Bearer {token}", "User-Agent": "my-app/1.0 (admin@example.com)"},
    timeout=10,
)
print(r.status_code, r.headers.get("Content-Type"))
print(r.text[:500])   # сообщение сервера о причине отказа

Частые причины ошибки 403 в API:

  • У ключа или токена нет нужного scope или роли — ключ «только на чтение» при запросе на запись, токен другого проекта или окружения (тестового вместо боевого).
  • IP не в белом списке ключа — запросы с нового сервера или из CI.
  • CSRF: Django отвечает 403 «CSRF verification failed. Request aborted.», если POST из браузера пришёл без токена или с чужого Origin.
  • WAF перед API режет клиента по User-Agent: заголовок по умолчанию python-requests/2.x или пустой User-Agent многие фильтры считают ботом. Для своего API добавьте клиента в исключения; для чужого — используйте официальный API и ключ, а не маскировку под браузер.
  • Подписанная ссылка истекла: хранилища вроде Amazon S3 отвечают на просроченную presigned-ссылку 403 AccessDenied.
  • Лимиты: часть API (например, GitHub) при превышении лимита отвечает 403, а не 429 — отличить можно по тексту ответа и заголовкам лимитов.
  • Preflight CORS: если сервер отвечает 403 на запрос OPTIONS, браузер покажет ошибку CORS, хотя корень проблемы — правило доступа, не пропускающее OPTIONS без авторизации.

403 на /admin или /wp-admin — что делать

Если сайт работает, но админка отдаёт 403:

  1. Проверьте IP allowlist в .htaccess или nginx — у вас мог смениться внешний IP.
  2. Проверьте Cloudflare Firewall Rules на admin path.
  3. Посмотрите fail2ban — возможно, ваш IP заблокирован после неудачных входов.
  4. Уточните 2FA — некоторые плагины возвращают 403 при неверном TOTP.
  5. Проверьте HTTP Basic Auth перед админкой: при неверном пароле он отдаёт 401, но конфликт auth_basic и deny в одном location может давать 403.

Как не пропустить 403 в будущем

403 — это диалог о правах доступа. Начинайте с логов, проверяйте права файлов и владельца, ищите deny-правила в .htaccess и nginx, исключайте WAF и IP-блокировки. Самые неприятные 403 появляются после выкладки, переноса файлов или обновления правил WAF и замечаются, когда пользователи уже ушли. Настройте мониторинг на expected_code=200 для главной, страниц оплаты и ключевых точек API, чтобы отлавливать 403-регрессии сразу.

Частые вопросы

В чём разница между 401 и 403?

401 — «авторизуйся»: учётных данных нет или они неверны, и вход может помочь. 403 — «у тебя нет доступа»: сервер знает, кто вы, но прав недостаточно, либо ресурс закрыт для всех.

Почему после scp файл отдаёт 403?

Файл получает владельца и права того, кто его копировал, — часто root и 600. Сделайте chown www-data:www-data file && chmod 644 file, а в CentOS/RHEL ещё restorecon -v file.

Как отличить 403 от сервера и от WAF?

Посмотрите заголовки Server: и cf-ray: Cloudflare обычно показывает свою страницу с Ray ID, и запроса нет в логах вашего сервера. Enterno.io HTTP Checker покажет все заголовки ответа.

403 у Googlebot или Яндекс-робота — это плохо?

Критично: закрытые страницы выпадают из индекса. Проверьте WAF, гео-правила и плагины безопасности. Настоящего робота подтверждают обратным DNS: host 66.249.66.1 должен вернуть имя в googlebot.com или google.com, для Яндекса — в yandex.ru, yandex.net или yandex.com, и прямой запрос этого имени должен вернуть тот же IP.

Можно ли вместо 403 отдавать 404?

Да, RFC 9110 это разрешает, если нужно скрыть само существование ресурса — так поступают с приватными репозиториями и служебными путями. Для страниц, которые пользователь должен видеть после входа, честнее 403 или редирект на вход.

Почему ошибка 403 появляется не всегда, а время от времени?

Так ведут себя динамические блокировки: лимиты запросов, fail2ban, антибот-проверки WAF. Ищите закономерность по времени и IP в access.log и журнале событий WAF.

Проверьте ваш сайт прямо сейчас

Проверить HTTP-статус сайта →
Другие статьи: HTTP
HTTP
HTTP-заголовки: полный разбор запроса и ответа сервера
10.03.2025 · 1 721 просм.
HTTP
Жизненный цикл HTTP-запроса: от URL до готовой страницы
16.03.2026 · 1 246 просм.
HTTP
Ошибка 400 Bad Request: что значит код и как исправить
13.07.2026 · 1 143 просм.
HTTP
HTTP-методы: GET, POST, PUT, DELETE и другие
16.03.2026 · 1 068 просм.