이미지를 다른 사이트에 붙였더니 깨진다? 403·핫링크 방지 완전 해결 트리 (2026 최신)
이미지 링크를 블로그에 붙였는데 내 로컬 미리보기는 멀쩡합니다. 발행하고 나니 남들이 보는 건 깨진 아이콘 틀 하나. 더 나쁘면 이미지 자리가 통째로 백지가 되고 아무것도 안 뜨죠.
이 함정, 저도 한두 번 밟은 게 아닙니다. 온라인에서 한 번 터진 건 친구 커뮤니티 이미지를 옮겨줄 때였어요. 로컬은 다 초록불, 배포하니 첫 페이지 썸네일의 3분의 1이 죄다 깨졌습니다. 당시엔 캐시를 안 비운 줄 알았어요. 사흘 디버깅하고서야 제 문제가 아니란 걸 깨달았죠. 이미지 출처 사이트가 핫링크 방지(hotlink protection)를 켜둬서, 자기 도메인에서 나온 요청이 아니면 무조건 차단하고 있었던 겁니다.
구조 관점에서 보면 "이미지가 다른 사이트에서 안 뜬다"는 건 사실 완전히 다른 세 가지 실패가 뒤섞여 불리는 겁니다. 제대로 고치려면 첫 단계가 지금 겪는 게 어느 종류인지 먼저 가려내는 거예요.
먼저 가리자: 403, 깨짐, 200 백지는 서로 다른 세 가지
많은 분이 이미지가 안 보이면 뭉뚱그려 "깨짐"이라 부르고 이것저것 막 시도합니다. 까놓고 말해 이 세 증상은 근본 원인이 크게 다르고 대응 경로도 다릅니다.
| 증상 | HTTP 상태 코드 | 가장 유력한 근본 원인 | 해결 방향 |
|---|---|---|---|
| 깨진 아이콘 틀(아이콘 갈라짐) | 403 / 404 | 핫링크 방지 차단, 또는 링크 자체 오류 | Referer와 주소 정확성 확인 |
| 깨진 아이콘 틀(아이콘 갈라짐) | 200이지만 이미지 아님 | 받은 게 HTML 오류 페이지지 이미지 파일이 아님 | Content-Type 확인 |
| 백지(갈라진 아이콘 없음) | 200 | CSS가 덮음, 또는 CSP가 로드 차단 | DevTools Console과 CSP 확인 |
| 아이콘 돌다가 사라짐 | 타임아웃 / CORS | 교차 도메인 정책 또는 서버 타임아웃 | Network 요청 세부 확인 |
먼저 상태 코드, 그다음 Content-Type, 마지막에 화면. 이 순서를 뒤집으면 헛돕니다.
밑바닥 원리: Referer와 핫링크 방지는 어떻게 작동하나
다른 사이트 이미지가 왜 막히는지 이해하려면, 브라우저가 이미지를 로드할 때 몰래 뭘 하는지부터 알아야 합니다.
웹페이지 A가 <img src="https://B.com/photo.jpg">로 B 사이트 이미지를 로드하면, 브라우저가 보내는 요청엔 Referer 헤더가 딸려갑니다(맞아요, 이 단어는 역사적으로 철자가 틀려서 r이 하나 빠졌는데 그대로 굳었어요). 이 헤더가 B 사이트에 알려줍니다. "이 이미지는 A 사이트 페이지가 요청한 거야."
밑바닥 원리는 이렇습니다. B 사이트 서버나 CDN이 요청을 받으면 Referer의 도메인을 화이트리스트와 대조합니다. 대략 이런 로직이에요.
1. Referer가 비어 있음(이미지 직접 열기, 북마크) → 설정에 따라 허용 또는 차단
2. Referer 도메인이 화이트리스트에 있음 → 허용
3. Referer 도메인이 화이트리스트에 없음 → 403 Forbidden 반환
이게 핫링크 방지입니다. 목적은 단순해요. 남이 자기 대역폭을 공짜로 빨아먹는 걸 막는 거죠. 여러분이 자기 사이트에 B 사이트 이미지를 임베드하면, 남이 여러분 페이지를 볼 때마다 트래픽 청구서가 B 사이트로 가니 B 사이트가 당연히 언짢죠.
여기 많은 분이 모르는 디테일. 현대 브라우저의 기본 Referrer-Policy는 strict-origin-when-cross-origin입니다. 교차 도메인 요청 시 "출처 도메인"만 보내고(예: https://a.com/) 전체 경로는 안 보내요. 그래서 핫링크 방지는 여러분 도메인 이름을 알아내고, 그걸로 화이트리스트 대조도 하고 여러분을 막기도 충분합니다. 이게 핫링크 방지가 hotlink를 제압하는 이유예요.
왜 내 이미지가 다른 사이트에선 깨지나: 해결 트리 하나
위 원리를 펼치면, 깨짐의 근본 원인은 사실 트리 하나로 수렴됩니다. 따라 내려가기만 하세요.
분기 1: 상태 코드가 403인가?
그렇다면 90%는 핫링크 방지입니다. B 사이트가 여러분 Referer가 화이트리스트에 없는 걸 보고 바로 거절한 거예요. 이 경우 B 사이트 설정은 못 바꾸니, 유일한 해법은 그 이미지를 더는 hotlink 하지 않는 겁니다(정답은 뒤에서).
분기 2: 상태 코드가 200인데 화면은 깨짐?
이 "이미지"의 원본 내용을 열어보세요. 받은 게 HTML 한 페이지일 가능성이 큽니다. 어떤 사이트는 403 대신 "핫링크 금지" 안내 페이지를 반환하는데 상태 코드는 200이에요. 브라우저가 HTML을 이미지로 파싱하니 당연히 갈라져 보이죠. Content-Type을 보면 들통납니다. 정상 이미지는 image/jpeg, image/png, 오류 페이지는 text/html이에요.
분기 3: 붙인 게 '페이지 링크'지 '이미지 직링크'가 아닌가?
신입이 제일 자주 밟는 지뢰. https://imgur.com/aBcDeFg는 페이지이고, https://i.imgur.com/aBcDeFg.jpg가 이미지 파일 자체입니다. 앞 것을 <img src>로 로드하면 HTML 한 페이지를 받지 이미지가 아니에요. i. 하나와 확장자 차이인데 결과는 천지 차이입니다.
분기 4: Referrer-Policy가 나를 스스로 해쳤나?
좀 은밀한 경우. 여러분 페이지가 Referrer-Policy: no-referrer로 설정돼 있으면 브라우저가 이미지 로드 시 Referer를 아예 안 보냅니다. 어떤 핫링크 방지 설정은 "빈 Referer 무조건 차단"이라, 오히려 자기 프라이버시 설정에 스스로 막히죠. 실측해 보면 이런 사례는 프라이버시에 아주 민감해 meta referrer를 완전히 꺼둔 사이트에서 잘 나옵니다.
직접 진단: DevTools와 curl 두 수로 위치 잡기
이론은 끝났고 실제로 어떻게 보느냐. 저는 도구 두 개를 고정으로 씁니다. 5분 안에 깨짐의 90%를 잡아요.
첫째 수: DevTools Network 패널
브라우저 개발자 도구(F12)를 열어 Network로 가고, 페이지 새로고침 후 필터에 이미지 파일명을 칩니다. 그 요청을 눌러 세 가지를 봐요.
- Status: 403인가, 404인가, 200인가?
- Response Headers의
Content-Type:image/*인가text/html인가? - Request Headers의
Referer: 실제로 보낸 게 뭔가? 비었나, 내 도메인인가?
셋을 다 보면 근본 원인이 거의 떠오릅니다.
둘째 수: 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(화이트리스트 가능) | 켜고 끄기 가능 | 허용/차단 설정 가능 | 제대로 설정하면 됨 |
| 일부 무료 이미지 호스팅 | 자주 켜짐 | 자주 차단 | 자주 막힘 |
| 소셜 플랫폼 이미지 도메인 | 거의 다 켜짐 | 거의 다 차단 | 불가, 꿈도 꾸지 마세요 |
| 공유 특화 이미지 호스팅 | 보통 꺼짐 | 허용 | 가능, 이게 존재 이유 |
핵심은 마지막 줄입니다. 소셜 플랫폼(그 SNS들의 CDN 도메인) 이미지는, 복사한 주소가 거의 100% 외부 링크가 안 됩니다. 비즈니스 모델이 여러분을 사이트 안에 가두는 거니까요. 그 이미지를 다른 데 붙이려는 건 막다른 길이에요.
반대로 "공유"를 내세운 이미지 호스팅은 핫링크 방지가 기본 꺼짐입니다. 존재 이유가 여러분 이미지를 외부에서 안정적으로 로드하게 하는 거거든요. 이 두 부류를 절대 헷갈리지 마세요.
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를 목 조른 거였음을 발견했죠. 이 지뢰는 떠올리기 어렵습니다. "프라이버시 강화"가 어떻게 자기를 해치겠어요?
올바른 방법: 남의 이미지를 hotlink 하지 마세요
해결을 끝까지 하면 잔혹한 사실을 마주합니다. 이미지가 내가 호스팅한 게 아니면, 어떤 "다른 사이트 이미지"든 내가 통제 못 하는 순간에 사라질 수 있어요. 상대가 핫링크 방지를 바꾸고, 주소를 바꾸고, 파일을 지우고, 심지어 사이트를 통째로 닫으면 여러분 페이지도 같이 깨집니다.
진짜 안정적인 방법은 딱 둘입니다.
첫째, 이미지를 내가 통제 가능한 곳에 다시 호스팅하세요. 남의 주소를 직접 임베드하지 마세요. 이미지를 내려받아 내 공간이나 외부 링크를 허용하는 이미지 호스팅에 올리고, 그 안정적 주소로 바꿔 쓰세요. 구조 관점에서 이 한 걸음의 본질은, 페이지의 가용성을 남의 서버 손에서 내 손으로 되찾는 겁니다. 출처가 내가 못 잡는 곳이면 상대의 핫링크 방지 조정, 주소 구조 개편, 심지어 사이트 폐쇄가 곧장 페이지 깨짐으로 반영되고, 예고도 못 받아 대개 독자 제보로 알게 돼요. 이미 남의 도메인에 흩어진 옛 링크를 한 번에 옮겨야 한다면, 제가 따로 쓴 이미지 링크 일괄 교체 완전 SOP에서 스크립트로 전체 옛 주소를 훑어 한 번에 바꾸는 법을 다뤘습니다. 손으로 한 장씩 바꾸는 것보다 훨씬 편해요. 통제 가능한 출처가 곧 안정적인 출처입니다.
둘째, 핫링크 방지가 기본 꺼진 이미지 호스팅을 고르세요. 많은 무료 이미지 호스팅이 대역폭 아끼려고 외부 링크를 막아, 커뮤니티나 블로그에 붙이면 깨져 보입니다. 외부 링크가 필요하면 직링크를 명시적으로 허용하는 서비스를 고르세요.
이건 저희가 lpic.cc를 만들 때의 원칙이기도 합니다. 업로드 후 안정적인 이미지 직링크 주소를 주고, 외부 사이트를 기본 차단하지 않아 커뮤니티, 블로그, Discord에 붙여도 정상 표시되고 뜬금없이 403이 안 뜹니다. 사적인 이미지는 비밀번호 보호로 누가 볼지 통제할 수 있어요. 궁금하면 이미지 한 장 무료 업로드해서 링크를 다른 페이지에 붙여 안정적인지 바로 테스트해 보세요.
솔직히 한계도 말할게요. 현재 무료 플랜 이미지는 30일 보관이라 영구 저장이 아니고, 서비스는 광고 매출로 지탱합니다. 장기 소장이나 상업용 대량 이미지 라이브러리라면 유료 전문 플랜을 평가하거나, 백업 있는 스토리지를 직접 구축해야 해요. 툴은 상황에 맞게 골라야 의미가 있죠. 이건 저도 지뢰 밟고 배웠습니다.
자주 묻는 질문 FAQ
Q: 왜 같은 이미지 링크가 저는 열리는데 다른 사이트에 붙이면 깨지나요?
여러분이 "이미지 직접 열기"를 할 땐 Referer가 비었거나 허용된 출처라 핫링크 방지가 통과시켜요. 다른 사이트에 붙이면 Referer가 그 외부 도메인이 되고, 화이트리스트에 없어 403으로 막힙니다. 같은 주소, 다른 Referer, 완전히 다른 결과죠.
Q: 403과 깨짐은 같은 건가요?
아니요. 403은 서버의 명확한 거절(상태 코드 403)이고, 깨짐은 브라우저가 "이미지를 못 그리는" 화면 표현입니다. 403이 깨짐을 유발하지만, 깨짐은 주소 오류, Content-Type 오류, CSP 로드 차단 등 다른 원인에서도 옵니다. 먼저 상태 코드를 봐야 어느 종류인지 알아요.
Q: 페이지를 Referrer-Policy: no-referrer로 하면 핫링크 방지를 우회하나요?
될 때도 있고 오히려 더 나쁠 때도 있어요. 상대 핫링크 방지가 "빈 Referer 허용"이면 안 보내는 게 통과됩니다. 근데 "빈 Referer 무조건 차단"이면 오히려 전부 깨져요. 이 수는 미덥지 않으니 정답으로 쓰지 마세요.
Q: 프로그램(Python / Node)으로 이미지를 긁어도 403인데 어쩌죠?
브라우저와 같은 이치예요. 프로그램이 맞는 Referer를 안 실은 겁니다. curl로 상대가 어느 Referer를 인정하는지 먼저 테스트하고, HTTP 요청에 같은 헤더를 채우세요. 단, 남의 핫링크 방지를 우회해 이미지를 긁는 건 상대 서비스 약관 위반일 수 있으니 알아서 판단하세요.
Q: 한국에서 이미지 호스팅이 외부 링크 되는지 빨리 판단하는 법은?
테스트 이미지 한 장 올려 직링크 주소를 받고, curl -I -H "Referer: https://google.com/"로 한 번 돌려보세요. 200이면 외부 링크 허용, 403이면 핫링크 방지라 외부에 붙이면 안 됩니다. 참고로 네이버 블로그, 티스토리, 카카오 계열 도메인의 이미지 주소도 외부 임베드가 자주 막히니, 안정적 외부 링크가 필요하면 처음부터 직링크를 명시 허용하는 이미지 호스팅에 올리는 게 30초 만에 끝나는 정답입니다.
References
- MDN Web Docs — Referrer-Policy header(접속일: 2026-06-26, 각 policy 값과
strict-origin-when-cross-origin현대 기본 동작 설명) - AWS Security Blog — How to help prevent hotlinking using referer checking, AWS WAF, and Amazon CloudFront(접속일: 2026-06-26, CDN 계층 Referer 검사 메커니즘)
- Alibaba Cloud CDN — Configure a Referer whitelist or blacklist to enable hotlink protection(접속일: 2026-06-26, 빈 Referer 허용 / 차단 판단 로직)
- KeyCDN Support — Create a Zone Referrer (Hotlink Protection)(접속일: 2026-06-26, CDN 핫링크 방지 화이트리스트 설정)
- ProxiesAPI — Fixing 403 Forbidden Errors for Image Requests in Code(접속일: 2026-06-26, 프로그램 이미지 수집 403과 Referer 헤더 차이)
- Patchstack — How To Prevent Image Hotlinking in WordPress(접속일: 2026-06-26, .htaccess mod_rewrite 핫링크 방지 규칙)