Картинка рвётся на чужом сайте? Разбор 403 и защиты от хотлинка 2026
Ты вставляешь ссылку на картинку в блог, локальное превью в порядке. Публикуешь — а другие видят треснувшую иконку. Или хуже: место картинки становится просто пустотой, ничего.
В эту яму я падал не раз. Один раз рвануло на проде, когда помогал переносить картинки для форума друга: локально всё зелёное, после публикации треть миниатюр на главной битые, я тогда ещё думал, что кэш не сбросил. Дебажил три дня, пока не понял — проблема вообще не моя: сайт-источник картинок включил защиту от хотлинка (hotlink protection), и любой запрос не с его собственного домена он режет.
С архитектурной стороны «картинка не показывается на чужом сайте» — это три совершенно разных сбоя, слепленных в одну фразу. Чтобы починить правильно, первый шаг — понять, с каким именно из них ты столкнулся.
Сначала разделим: 403, битая картинка и пустой 200 — это три разные вещи
Многие, увидев пропавшую картинку, скопом зовут это «битой картинкой» и тычутся наугад. На деле корни этих трёх симптомов сильно разные, и пути разбора тоже.
| Симптом | HTTP-код | Наиболее вероятный корень | Куда копать |
|---|---|---|---|
| Треснувшая иконка | 403 / 404 | защита от хотлинка или сама ссылка неверна | проверить Referer и правильность адреса |
| Треснувшая иконка | 200, но не картинка | пришла HTML-страница ошибки, а не файл | проверить Content-Type |
| Пустое место (без иконки) | 200 | CSS перекрыл или CSP заблокировал загрузку | проверить Console DevTools и CSP |
| Иконка покрутилась и исчезла | таймаут / CORS | межсайтовая политика или таймаут сервера | проверить детали запроса в Network |
Сначала код, потом Content-Type, и только в конце — картинку на экране. Перевернёшь порядок — будешь долбиться в стену.
Как это работает внутри: Referer и защита от хотлинка
Чтобы понять, почему картинку с чужого сайта режут, надо знать, что браузер втихую делает при загрузке.
Когда страница A загружает картинку сайта B через <img src="https://B.com/photo.jpg">, запрос браузера несёт заголовок Referer (да, это слово исторически написано с ошибкой, без одной r, так и живёт до сих пор). Заголовок сообщает сайту B: «эту картинку запросила страница сайта A».
Внутри всё так: сервер или CDN сайта B, получив запрос, берёт домен из Referer и сверяет с белым списком. Логика примерно такая:
1. Referer пустой (открыли картинку напрямую, закладка) → по настройке пропустить или блок
2. Домен Referer в белом списке → пропустить
3. Домен Referer не в белом списке → вернуть 403 Forbidden
Это и есть защита от хотлинка. Цель простая: не давать другим бесплатно жечь свой трафик. Ты встроил на своём сайте картинку сайта B — и каждый просмотр твоей страницы записывается в счёт трафика сайта B. Ему это, естественно, не нравится.
Тут деталь, о которой многие не знают: Referrer-Policy по умолчанию у современных браузеров — strict-origin-when-cross-origin. При межсайтовом запросе он шлёт только «домен-источник» (например, https://a.com/), без полного пути. Так что защите достаётся имя твоего домена — этого хватает и на сверку с белым списком, и на то, чтобы тебя заблокировать. Вот почему защита от хотлинка справляется с хотлинком.
Почему твоя картинка рвётся на чужом сайте: дерево разбора
Разложив принцип, корень битой картинки сводится к дереву. Просто иди по нему вниз.
Ветка первая: код 403?
Если да — в девяти случаях из десяти это защита от хотлинка. Сайт B видит, что твоего Referer нет в его белом списке, и отказывает. Настройки сайта B ты изменить не можешь, единственное решение — перестать хотлинкать его картинку (правильный путь ниже).
Ветка вторая: код 200, но картинка битая?
Открой «сырое» содержимое этой «картинки». Скорее всего, тебе пришла HTML-страница — некоторые сайты не отдают 403, а возвращают страницу «не хотлинкать», код при этом 200. Браузер парсит HTML как картинку и, конечно, показывает трещину. Проверь Content-Type и всё вскроется: нормальная картинка — image/jpeg, image/png, страница ошибки — text/html.
Ветка третья: ты вставил «ссылку на страницу», а не «прямую ссылку на картинку»?
Самая частая засада новичка. https://imgur.com/aBcDeFg — это страница, а https://i.imgur.com/aBcDeFg.jpg — сам файл картинки. Первую грузишь через <img src> — получишь целую HTML-страницу, а не картинку. Разница в одном i. и расширении, а результат — небо и земля.
Ветка четвёртая: Referrer-Policy подставил тебя самого?
Более скрытый вариант. Если на твоей странице стоит Referrer-Policy: no-referrer, браузер при загрузке картинки вообще не шлёт Referer. У части настроек защиты «пустой Referer режем всегда» — и ты, наоборот, оказываешься заблокирован собственной настройкой приватности. По замерам такое обычно бывает на сайтах, которые очень пекутся о приватности и наглухо закрутили meta referrer.
Диагностика на практике: DevTools и curl, два приёма
Теория позади, как проверять реально? Я стабильно использую два инструмента, за пять минут они локализуют девять из десяти битых картинок.
Приём первый: панель Network в DevTools
Открой инструменты разработчика (F12), перейди в Network, обнови страницу, вбей в фильтр имя файла картинки. Зайди в этот запрос и смотри три вещи:
- Status: 403, 404 или 200?
Content-Typeв Response Headers:image/*илиtext/html?Refererв Request Headers: что реально ушло? Пусто или твой домен?
Посмотрел три — корень примерно всплыл.
Приём второй: curl с ручным контролем Referer
DevTools показывает симптом, но чтобы подтвердить «это точно защита от хотлинка», проще всего curl. Можно вручную подставить любой Referer и смотреть, как меняется реакция сервера:
# Совсем без Referer (имитируем прямое открытие)
curl -I "https://example.com/photo.jpg"
# С Referer, «якобы с самого сайта-источника»
curl -I -H "Referer: https://example.com/" "https://example.com/photo.jpg"
# С Referer, «якобы с твоего внешнего сайта»
curl -I -H "Referer: https://your-blog.com/" "https://example.com/photo.jpg"
Чтение результата прямое. Если первый и третий вернули 403, а второй — 200, поздравляю, защита от хотлинка доказана: сервер принимает только Referer самого источника, остальное режет. Если все три 200 — битая картинка к хотлинку отношения не имеет, возвращайся к проверке адреса или CSP.
По привычке я гоняю все три строки разом — сравнивать результаты нагляднее, чем смотреть на одну. Вот почему curl эффективнее, чем тыкаться в браузере вслепую.
Поведение защиты от хотлинка у популярных хостингов и CDN
Дефолтный характер сервисов сильно разный. Ниже — наблюдения за годы переносов картинок; конкретные настройки каждый может менять в любой момент, но общее направление такое.
| Тип сервиса | Защита от хотлинка по умолчанию | Поведение при пустом Referer | Годится для внешней ссылки? |
|---|---|---|---|
| Свой Nginx / Apache | как настроишь | обычно пропускает | зависит от настройки |
| Корпоративный CDN (с белым списком) | включаемо/выключаемо | настраивается | настроишь верно — можно |
| Часть бесплатных хостингов | часто включена | часто режет | часто режут |
| Домены картинок соцсетей | почти всегда включена | почти всегда режет | нельзя, и не думай |
| Хостинг, заточенный под обмен | обычно выключена | пропускает | можно, в этом его смысл |
Главное — последняя строка. Картинки соцсетей (те самые CDN-домены соцплатформ) почти на сто процентов нельзя вынести по внешней ссылке — их бизнес-модель в том, чтобы запереть тебя внутри сайта. Тащить эти картинки куда-то ещё — тупик.
А хостинг, заточенный под «обмен», по умолчанию хотлинк не режет — смысл его существования в том, чтобы твою картинку стабильно грузили с внешних сайтов. Эти два типа ни в коем случае не путай.
Ловушка Referrer-Policy: даже браузер может подставить тебя
Выше я упомянул скрытый вариант, тут разверну — он доводит до дебага «до потери пульса».
Referrer-Policy — заголовок, который задаёт страница (та, что шлёт запрос). Он решает, сколько информации Referer браузер отправит. Значений несколько:
no-referrer: не шлёт вообще.origin: шлёт только домен-источник.strict-origin-when-cross-origin: межсайтово шлёт только домен, при даунгрейде на HTTP не шлёт (современный дефолт).unsafe-url: шлёт даже полный путь (не советую, утечка приватности).
Противоречие в чём. Защита от хотлинка судит по Referer, а политика приватности, наоборот, поощряет слать Referer меньше или вообще не слать. Когда сайт ради приватности ставит no-referrer и грузит любую картинку с защитой «пустой Referer режем всегда» — всё рвётся.
Раз на проде у меня рвануло именно так: сайт, очень трепетный к приватности, повесил no-referrer на весь сайт — и все внешние картинки битые. Я тогда думал, что хостинг упал, полдня искал, пока не понял, что собственная meta-настройка задушила Referer. Эту засаду сложно предугадать, ведь «усилил приватность» — как оно вообще может навредить себе?
Правильный путь: не хотлинкай чужие картинки
К концу разбора вскрывается жестокий факт: пока картинка размещена не у тебя, любая «чужая картинка» может исчезнуть в момент, который ты не контролируешь. Владелец поменял защиту, сменил адрес, снёс файл или закрыл весь сайт — и твоя страница рвётся следом.
По-настоящему надёжных путей только два.
Первый — перезалей картинку туда, что контролируешь сам. Не встраивай чужой адрес напрямую. Скачай картинку, залей на своё пространство или на хостинг, разрешающий внешние ссылки, и перейди на этот стабильный адрес. С архитектурной стороны суть шага в том, чтобы вернуть доступность своей страницы из рук чужого сервера себе: пока источник не под твоим контролем, любая его правка защиты, смена структуры адресов или полный уход в офлайн отразятся прямо битой картинкой на твоей странице, причём без предупреждения — обычно узнаёшь от читателей, что всё рвануло. Если у тебя уже есть целая пачка старых ссылок, разбросанных по чужим доменам, и её надо разом перенести, я отдельно писал полный SOP по пакетной замене ссылок на картинки — скриптом вычищаешь все старые адреса по сайту за один заход, куда проще ручной замены по одной. Контролируемый источник — только он надёжный.
Второй — выбери хостинг, где защита от хотлинка по умолчанию выключена. Многие бесплатные хостинги ради экономии трафика режут внешние ссылки, вставишь в форум или блог — покажет тебе трещину. Нужна внешняя ссылка — бери сервис, который явно разрешает прямую загрузку.
Это и один из принципов, по которым мы делали lpic.cc: после загрузки ты получаешь стабильную прямую ссылку на картинку, внешние сайты по умолчанию не режутся, вставляй в форум, блог, Telegram — везде показывается нормально, без внезапного 403. Для приватных картинок можно защитой паролем контролировать, кто их видит. Хочешь проверить — загрузи бесплатно одну картинку, вставь ссылку на другой странице и посмотри, держится ли.
Честно скажу и про ограничения: у картинок бесплатного плана срок хранения 30 дней, не вечный архив, и сервис держится на рекламе. Под долгий архив или коммерческую библиотеку картинок в большом объёме тебе стоит взвесить платный профессиональный план или поднять своё хранилище с бэкапом. Инструмент имеет смысл только под свой сценарий — этому я научился, наступив на грабли.
Отдельно для российских реалий: Яндекс Диск, VK и 152-ФЗ
Пара местных нюансов. Ссылки-шары Яндекс Диска и Облака Mail.ru по природе не под «прямую вставку картинки» — они отдают страницу-просмотрщик, а не файл, и наружу для <img src> не годятся; ждать от них стабильного хотлинка бессмысленно, это тот же тупик, что и с любым личным облаком. Домены картинок VK отдают временные подписанные ссылки, которые протухают, — вставишь такую в блог, через время получишь битую картинку. И правовой слой: если ты хостишь картинки с узнаваемыми людьми на зарубежном сервисе, формально это трансграничная обработка персональных данных по 152-ФЗ. Для разовой картинки неактуально, но для сайта, где систематически публикуются чужие лица, разумно держать это в голове и не полагаться на единственную копию за пределами контролируемого хранилища.
Частые вопросы (FAQ)
Q: Почему одну и ту же ссылку на картинку я открываю, а на чужом сайте она рвётся?
Потому что при «прямом открытии» Referer пустой или из разрешённого источника, и защита пропускает. На чужом сайте Referer становится тем внешним доменом, его нет в белом списке — и тебя режут в 403. Один адрес, разный Referer — совершенно разный результат.
Q: 403 и битая картинка — это одно и то же?
Нет. 403 — это явный отказ сервера (код 403), а битая картинка — просто то, как браузер «не смог нарисовать» на экране. 403 приводит к битой картинке, но битая картинка может быть и от неверного адреса, неверного Content-Type, блокировки CSP и других причин. Сначала смотри код, тогда поймёшь, какой это случай.
Q: Поставить странице Referrer-Policy: no-referrer — обойдёт защиту от хотлинка?
Иногда да, иногда, наоборот, хуже. Если у источника защита «пустой Referer пропускаем», то не слать Referer реально прокатит. Но если у него «пустой Referer режем всегда» — у тебя, наоборот, всё порвётся. Приём ненадёжный, за правильное решение его не держи.
Q: Я тяну картинку кодом (Python / Node) и тоже ловлю 403, что делать?
Как и у браузера — твоя программа не несёт нужный Referer. Сначала curl-ом выясни, какой Referer принимает источник, потом добавь тот же заголовок в свой HTTP-запрос. Но учти: обход чужой защиты от хотлинка ради выкачивания картинок может нарушать условия сервиса, решай сам.
Q: Как быстро понять, можно ли с хостинга дать внешнюю ссылку?
Залей тестовую картинку, возьми её прямую ссылку, прогони curl -I -H "Referer: https://google.com/". Вернул 200 — внешние ссылки разрешены, вернул 403 — есть защита от хотлинка, для чужих сайтов не бери. Тридцать секунд на проверку.
Источники
- MDN Web Docs — заголовок Referrer-Policy (дата обращения 2026-06-26, значения политик и современный дефолт
strict-origin-when-cross-origin) - AWS Security Blog — как предотвратить хотлинкинг проверкой referer, AWS WAF и Amazon CloudFront (дата обращения 2026-06-26, механизм проверки Referer на уровне CDN)
- Alibaba Cloud CDN — настройка белого/чёрного списка Referer для защиты от хотлинка (дата обращения 2026-06-26, логика пропуска/блока пустого Referer)
- KeyCDN Support — создание Zone Referrer (Hotlink Protection) (дата обращения 2026-06-26, настройка белого списка защиты на CDN)
- ProxiesAPI — исправление ошибок 403 Forbidden для запросов картинок в коде (дата обращения 2026-06-26, 403 при выкачивании кодом и разница заголовка Referer)
- Patchstack — как предотвратить хотлинкинг картинок в WordPress (дата обращения 2026-06-26, правила защиты через .htaccess mod_rewrite)
Автор
Harvey ZhangСооснователь и технический директор
Бэкенд-инженер, ставший архитектором, предлагает глубокий технический анализ инфраструктуры хостинга изображений.