본문으로 건너뛰기
개발 머꼬
개발 노트HTML
hohyeon.dev42

새 탭으로 여는 외부 링크에 rel을 붙여야 하는지 다시 확인한 이유

  • #Engineering Note
  • #HTML
  • #Security

문제 발생

보안 점검에서 외부 링크에 rel="noopener"가 없다는 지적을 받았습니다. 그런데 최신 브라우저에서는 기본으로 막힌다는 이야기도 있어서, 붙여야 하는지 판단이 서지 않았습니다.

<a href="https://external.example.com" target="_blank">외부 문서</a>

원인 분석

target="_blank"로 열린 페이지는 예전에 window.opener로 원래 탭에 접근할 수 있었습니다. 링크된 페이지가 이렇게 할 수 있었다는 뜻입니다.

// 악의적인 페이지에서
window.opener.location = "https://phishing.example.com";

원래 탭을 피싱 사이트로 바꿔치기하는 공격(탭내빙)이 여기서 나옵니다. 사용자는 새 탭을 닫고 원래 탭으로 돌아왔을 때 주소가 바뀐 것을 눈치채기 어렵습니다.

지금은 기본 동작이 바뀌었습니다. MDN에 따르면 <a>, <area>, <form>에 target="_blank"를 지정하면 rel="noopener"를 지정한 것과 같은 동작이 암묵적으로 적용되어 window.opener가 설정되지 않습니다.

그래서 최신 브라우저만 대상이라면 기술적으로는 필요 없습니다. 다만 명시하면 의도가 드러나고 구형 브라우저에서도 안전합니다.

noreferrer는 다른 것을 막습니다.

속성window.openerReferer 헤더
noopener차단전송됨
noreferrer차단전송 안 됨
둘 다차단전송 안 됨

해결 방안

  1. 신뢰할 수 없는 외부 링크에는 명시합니다. 비용이 없고 의도가 드러납니다.
<a href="https://external.example.com" target="_blank" rel="noopener">외부 문서</a>
  1. 유입 경로를 숨겨야 하면 noreferrer를 더합니다. 반대로 파트너 사이트에 유입 통계를 남겨야 한다면 noreferrer는 빼야 합니다 — 목적이 서로 다릅니다.
  2. window.open()에도 적용합니다. 스크립트로 여는 경우에는 자동으로 적용되지 않으므로 직접 지정합니다.
window.open(url, "_blank", "noopener");
  1. 새 탭으로 여는 것 자체를 신중히 결정합니다. 접근성 관점에서는 사용자가 기대하지 않은 창 전환이 혼란을 줄 수 있습니다. 새 탭으로 연다면 그 사실을 시각적으로나 스크린리더용 텍스트로 알려 주는 편이 좋습니다.
  2. 내부 링크에는 필요 없습니다. 같은 출처끼리는 이 공격이 성립하지 않고, 이 저장소도 앱 내부 이동은 새 탭을 쓰지 않습니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.