본문 바로가기
카테고리 없음

외부 링크 보안 설정: rel="noopener noreferrer" 속성으로 보안과 SEO 동시에 잡기

by BOOST YOUR INFORMATION 2026. 5. 7.

rel="noopener noreferrer" 속성으로 보안과 참조 이미지
외부 링크 보안 설정: rel="noopener noreferrer" 속성

 

외부 링크에 target="_blank"를 쓰면서 rel="noopener noreferrer"를 빠뜨리는 것, 이게 얼마나 위험한 일인지 대부분의 개발자가 모른다. 아니, 알면서도 그냥 넘어간다. 나도 그랬다. 별일 있겠냐 싶었다. 그런데 실제로 해당 취약점을 통한 공격 사례를 접하고 나서 생각이 완전히 바뀌었다. 잠그지 않은 자동차 문에 현금 다발을 올려두는 것과 같은 일이었다.

이 속성을 처음 알게 된 경위가 부끄럽다. 코드 리뷰에서 동료가 지적해서였다. 몇 년 동안 target="_blank"를 쓰면서 rel 속성 없이 넘어가 왔다. 그 동안 운이 좋았던 것이다. 보안 취약점이라는 게 그렇다. 문제가 생기기 전까지는 존재하지 않는 것처럼 느껴진다. 그런데 한 번 당하면 그때서야 속성 두 개의 무게가 실감된다.

target="_blank"의 숨겨진 위험: window.opener 취약점

target="_blank"로 외부 링크를 열면 새 탭이 생성된다. 여기까지는 누구나 안다. 그런데 이때 새로 열린 탭은 원래 페이지에 대한 참조를 window.opener를 통해 갖게 된다. 이 말은 새로 열린 외부 사이트가 원래 페이지를 제어하거나 리디렉션할 수 있다는 뜻이다.

실제 공격 시나리오는 이렇다. 내 블로그에서 어떤 외부 링크를 target="_blank"로 연결해뒀다고 하자. 그 외부 사이트가 악의적이거나 해킹당한 상태라면, 사용자가 외부 사이트를 보는 동안 window.opener.location을 조작해 원래 페이지, 즉 내 블로그 탭을 피싱 사이트로 바꿔치기할 수 있다. 사용자는 외부 탭을 보다가 돌아왔더니 로그인 화면이 나타나 있는 걸 보게 된다. 자신이 보던 사이트 주소가 그대로이므로 의심 없이 아이디와 비밀번호를 입력한다. 이 공격 기법은 Reverse Tabnabbing이라 불리며 OWASP에서도 공식적으로 문서화된 취약점이다.

내가 이 취약점에 대해 처음 들었을 때 솔직히 반신반의했다. 설마 그런 식으로 공격이 가능하냐고. 그런데 직접 로컬에서 테스트해보니 정말 됐다. 그 이후로 코드 리뷰할 때 이 속성이 빠진 링크를 발견하면 반드시 지적한다.

noopener와 noreferrer 각각의 역할

두 속성이 하는 일이 다르다. noopener는 새 탭에서 window.opener를 null로 만들어버린다. 새로 열린 페이지가 원래 페이지를 참조하지 못하게 막는 것이다. noreferrer는 여기에 더해 HTTP Referer 헤더도 전송하지 않는다. 즉 외부 사이트에서 방문자가 어디서 왔는지 알 수 없게 된다.

대부분의 경우 두 속성을 함께 쓰는 게 맞다. noopener만 쓰면 Referer는 여전히 전송된다. noreferrer만 쓰면 오래된 브라우저에서 호환성 문제가 생길 수 있다. 현대 브라우저에서는 noreferrer가 noopener를 겸하지만, 안전을 위해 함께 쓰는 습관을 들이는 게 좋다.

한 가지 덧붙이고 싶은 것은, 이 속성을 아이콘 링크에 달 때 접근성까지 함께 챙기면 좋다는 것이다. aria-label에 "(새 탭에서 열림)"을 명시하면 스크린 리더 사용자가 새 탭이 열린다는 사실을 미리 알 수 있다. 보안, 접근성, SEO를 동시에 고려하는 방식이다. 작업 하나에 세 가지 효과를 챙길 수 있는 기회를 놓칠 이유가 없다.

SEO에 미치는 영향: 링크 주스와 rel 속성

SEO 관점에서 rel 속성은 단순 보안 이슈를 넘어선다. 구글은 링크를 통해 페이지 간 신뢰도와 권위를 전달하는 개념인 링크 주스를 분석한다. 외부 링크에 rel 속성이 없으면 구글이 이 링크를 일반적인 do-follow 링크로 처리한다. 즉 내 사이트의 신뢰도를 외부 사이트로 전달하는 셈이다.

주의할 것이 있다. rel="noreferrer"는 nofollow와 다르다. noreferrer는 Referer 헤더를 차단하는 것이고, nofollow는 크롤러에게 이 링크를 따라가지 말라고 신호를 보내는 것이다. 만약 외부 링크가 광고이거나 신뢰할 수 없는 사이트라면 nofollow도 함께 추가해야 한다. 사용자 생성 콘텐츠의 링크라면 ugc 속성을 사용하는 것이 구글 권고 방식이다. 이 구분을 모르고 무작정 noreferrer만 달면 SEO 처리가 의도와 다르게 동작할 수 있다.

CMS와 동적 콘텐츠에서 일괄 처리하는 접근법

개별 링크마다 수동으로 rel 속성을 추가하는 것은 비현실적이다. 특히 글이 많은 블로그나 CMS 기반 사이트에서는 JavaScript로 페이지 로드 시 자동으로 외부 링크를 감지하고 속성을 추가하거나, 워드프레스라면 functions.php에 필터를 추가해서 일괄 처리하는 방법이 현실적이다. 이런 자동화 처리 없이 관리하다가 새 글을 올릴 때마다 빠뜨리는 경우가 생긴다. 사람이 반복 작업을 하면 반드시 실수한다. 자동화하는 것이 맞다.

단, JavaScript로 일괄 처리할 때 주의할 점이 있다. 기존에 rel 속성이 이미 있는 링크에 덮어쓰면 의도한 값이 사라질 수 있다. 기존 rel 값을 읽어서 noopener와 noreferrer가 없는 경우에만 추가하는 방식으로 처리해야 한다.

현장에서 느낀 장단점

장점은 명확하다. 보안 취약점 하나를 간단하게 막을 수 있고, SEO 링크 구조도 명확해진다. 코드 한 줄 추가로 얻는 효과치고는 손익 비율이 압도적으로 좋다. 구글 Search Console에서 외부 링크 품질 평가도 개선된다.

단점은 Analytics 트래픽 추적이 달라질 수 있다는 점이다. noreferrer를 쓰면 외부 사이트에서 방문자가 어디서 왔는지 그쪽 Analytics에서 직접 확인이 어려워진다. 파트너 사이트와 트래픽을 공유해야 하는 경우라면 UTM 파라미터를 URL에 직접 추가하는 방식으로 대응해야 한다. 이 부분을 모르고 noreferrer를 무작정 달았다가 파트너 측에서 유입 데이터가 안 잡힌다고 문의가 온 적이 있었다. 미리 이 차이를 알고 처리하는 것이 중요하다.

마무리: 링크 하나에도 책임이 있다

개발을 오래 하다 보면 사소한 것들이 실은 사소하지 않다는 걸 알게 된다. target="_blank" 하나에도 보안 설계가 들어가야 하고, 외부 링크 하나에도 SEO 전략이 담겨야 한다. rel="noopener noreferrer"는 그냥 속성 두 개가 아니라, 내 사이트를 방문하는 사람들을 보호하겠다는 의지의 표현이다.

현장에서 수년간 코드 리뷰를 하면서 이 속성이 빠진 링크를 수도 없이 발견했다. 그때마다 왜 빠뜨렸냐고 물으면 대부분 몰랐거나 귀찮았다는 대답이 돌아왔다. 이 글을 읽는 분이라면 이제 몰라서는 아닐 것이고, 귀찮음이라는 핑계도 자동화로 해결된다. 외부 링크를 달 때 target="_blank"를 쓴다면 반드시 rel="noopener noreferrer"를 함께 쓰는 습관을 들이자. 이건 선택이 아니라 기본이다.

보안 취약점은 대부분 거창한 해킹 기술에서 오지 않는다. 이런 작은 설정 하나 빠뜨린 곳에서 온다. 내가 만드는 페이지의 모든 외부 링크를 지금 당장 점검해보길 권한다. 아마 생각보다 많은 링크가 rel 속성 없이 있을 것이다. 발견할 때마다 고치는 게 아니라, 처음부터 올바른 습관으로 만드는 것이 개발자로서 성장하는 방식이다.


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 ⚡ 정보 부스터 🚀