April 11, 2020
eslint가 설정된 jsx파일에서 a태그
에 target=”_blank”
속성을 주게되면 react/jsx-no-target-blank 경고를 보게된다.
경고 내용을 살펴보면 target=”_blank”
속성이 있을 경우, rel=”noreferrer”
속성을 추가하지 않으면 보안 문제(security risk)가 생길 수 있다고 알려준다.
응? 어떤 보안 문제일까 궁금해졌다.
target
속성에 “_blank”
값이 있는 a태그의 경우 새로운 탭에서 페이지가 열린다. 이 때 a태그가 있는 기존 페이지를 parent
, 링크로 인해 새롭게 열린 페이지는 child
라고 하자. 이 때 child
에서 window.opener
속성으로 parent
를 컨트롤 할 수 있다.
// child에서 사용되는 js파일
window.opener.location = "https://coupamg.com";
위 코드로 사용자가 눈치채지 못하게 parent 페이지를 다른 도메인으로 유도 할 수 있다.
위에서 알아본 child
에서 parent
를 조작할 수 있는 기술을 피싱 사기에 사용할 수 있다. 이 수법이 Tab nabbing 기술이다.
https://cgm.example.com
이라는 서비스 페이지가 있다고 가정하자. 해커는 불특정 사용자의 username과 password를 가로채려고 한다. 그러기위해 해커는 서비스의 게시물에 특정 링크(해커가 만든 페이크 페이지로 이동)를 게시한다. 이 때 전제는 링크(a태그)가 target="_blank"
로 마크업 되어있어야 한다.
https://cgm.example.com
에 접속 ⇒ (parent 페이지)
https://happy.example.com
로 이동하는 링크를 클릭해당 사이트는 새 탭으로 페이지가 열림 ⇒ (child 페이지)
happy.example.com
)는 해커가 만든 페이지로, 이 페이지의 스크립트에서 parent
의 url을 cgn.example.com/login
으로 변경 ⇒ 이 페이지 역시 해커가 만든 fake페이지cgm.example.com
vs cgn.example.com
)
두뇌 풀가동해서 위 사항들을 모두 인지하고 항상 의심하면서 웹서비스를 이용하자..
⇒ 나도 인식하지 하지 못하고(?) 피싱에 걸렸을 듯?… 🥺
tabnabbing
을 방지할 수 있는 방법이 rel="noreferrer"
혹은 rel="noopener"
속성을 적용하는 것이다.
rel="noopener"
[rel="noopener"](https://html.spec.whatwg.org/#link-type-noopener)
속성을 추가하면 child에서 window.opener
를 통해 기존 탭(parent)를 참조할 수 없게 된다. 그렇기 때문에 기존 탭(parent)의 location을 변경하는 등의 조작을 방지할 수 있다.
rel="noreferrer"
rel="noopener"
와 유사하게 새로 열린 탭의 페이지에서 window.open
를 통해 기존 탭을 참조 할 수 없게 한다. noopener
가 있는데 이 속성을 사용한 이유는 이전에는 Chorme, Opera 이외에 다른 브라우저가 noopener
속성을 지원하지 않아, 지원 범위가 상대적으로 더 넓은 referer
을 사용한 걸로 추측된다. (두 속성을 깊게 digging하여 차이점을 파악해야 하지만 이번 TIL에서는 여기까지만…⭐️)
이전에는 브라우저 지원 범위가 noopener
속성에 제약이 있어, 지원 범위가 상대적으로 더 넓은 noreferrer
속성을 사용했지만, 최근에는 대다수 브라우저가 두 속성 모두 지원하고 있다.
noopner 속성 브라우저 지원 범위
noreferrer 속성 브라우저 지원 범위
불안하다면 두 속성 모두 사용하는 방법이 주로 쓰인다. (개인적으로는 noreferrer
속성만 사용하여도 무방할 것 같다고 생각)
target="_blank"
쓸 경우, tabnabbing
공격 문제가 생길 수 있음.rel="noopener noreferrer"
속성 추가하자.target="_blank"
가 아니라면 해당 속성(noopner
, noreferrer
)을 줄 필요가 없음