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

새 탭으로 여는 외부 링크에 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

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