SNS 관련 프로젝트를 진행하던 도중 Twitter와 Facebook에서 공통적으로 발견한 코드가 있었다. 새 창을 띄우기 위해 target="_blank"를 사용할 경우 rel="noopenner"
과 같은 속성을 추가하여 사용하고 있다. 이는 보안 취약성을 해결하고자 함이다. target="_blank"사용시에 어떠한 문제가 야기되며 그에 대한 대응방안은 무엇이 있는지 알아보도록 하겠다.
새 창 띄우기
혹시 아래와 같이 여러개의 창들을 띄워본적이 있는가?
대부분의 인터넷 유저는 한개의 페이지만을 오픈하여 사용하지는 않는다. 대신에 아래와 같이 여러개의 tab을 동시다발로 열어놓은 채 사용할 것이다. 유저가 직접 새 창을 띄워 탭을 늘리는 경우도 있지만 페이지 상의 특정 링크를 클릭할 시 새 탭이 열리게 되는 경우도 있다.
유저가 link를 클릭 했을시 현재의 창이 아닌 새로운 창으로 띄워주기 위해 사용할 수 있는 HTML 속성은 target 속성이다. 예를들어 만약 당신이 '행복해하는 강아지'의 이미지를 구글링된 새 화면으로 보여주고 싶다면 아래와 같이 코드를 작성할 수 있겠다.
<a href="https://www.google.com/search?q=happy+dog&source=lnms&tbm=isch&sa= X&ved=0ahUKEwik9P7GmPLjAhWBHKYKHWvTDggQ_AUIECgB&biw=740&bih=665#imgrc=_" target="_blank">Happy dog</a> |
a
태그에 href
로 링크를 걸어주었고 target
속성의 _blank
를 이용하여 새 창에 띄우도록 하였다. 위의 Happy dog 링크를 누르면 구글 이미지 검색창으로 순조롭게 이동 될 것이다. 하지만 이는 보안성을 생각하지 않은 코드이다. 그 누구도 자신이 작성해놓은 코드로 인하여 유저의 정보를 위험에 빠트리기 원치 않을 것이다. 여기서 문제점이 되는 코드는 target="_blank"
이다. 해커는 _blank
속성값으로 인해 새롭게 열린 창을 이용하여 피싱(phishing)공격을 감행한다. 해커가 이용하는 이 특정 피싱 공격의 명칭은 Tabnabbing 이라고 불리운다.
Phishing: Private Data와 Fishing의 합성어. 온라인상에서 개인정보를 악용하기 위해 불법적으로 취득하는 것을 말한다.
Phishing 언어의 유래: 1996년 해커 뉴스그룹 alt.2600에서 첫 사용.
Tabnabbing
Tabnabbing은 피싱공격의 일종.
2010년, 보안전문가 Aza Raskin이 피싱공격에 붙인 단어이다. 단어가 내포하고 있는 의미처럼 공격은 새 창(새 탭)을 통해 이루어 진다.
해커는 유저가 target
속성으로 열게 된 새 창의 페이지를 window.opener 속성을 이용하여 미리 준비해둔 피싱 사이트로 바꾼다. 이를 코드를 통해 보면 아래와 같다.
파란색 박스는 유저가 보는 페이지의 HMTL소스이다. 분홍 박스는 해커가 작성한 페이지이다. 조건문을 통해 window.opener 속성에 접근하여 피싱 사이트로 바꾸어 주었다. 보통의 유저는 새롭게 뜬 창이 해커가 바꾼 악성사이트인지를 알아차리기가 힘들다. 악성사이트 상에서 자신의 정보를 입력하게 되고 그 정보는 고스란히 해커에게 전달된다.
* target 속성은 링크된 문서를 어디서 어떻게 열 것인가를 지정해주는 기능을 갖고있다.
새 창에서 열린 부모에 접근하려 할 때 opener 속성을 통해서 한다.
- opener.closed
- opener.frames
- opener.length
- opener.opener
- opener.parent
- opener.self
- opener.top
해결 방안
1. noopener | noreferrer 사용하기
noopener와 noreferrer 키워드를 이용함으로써 웹사이트의 보안성을 높여줄 수 있다.
실제로 Facebook 과 Twitter는 위의 두 방법을 사용하고 있다.
위에서 코드로 보았듯이, 해커는 window.opener로 접근하여 새창의 주소를 악성 사이트로 바꾸는 방법을 사용했다. 그렇다면 해커가 해당 속성에 접근하지 못하도록 설정을 해놓아 버리자. 이는 noopener 와 noreferrer을 이용하여 window.opener가 가리키는 값을 null로 확정지어 버리면 된다. 코드는 rel
속성을 이용하여 작성해주면 된다.
위에서 보았던 보안이 취약한 코드를 고친다면 아래와 같다.
<a href="https://www.google.com/search?q=happy+dog&source=lnms&tbm=isch&sa= X&ved=0ahUKEwik9P7GmPLjAhWBHKYKHWvTDggQ_AUIECgB&biw=740&bih=665#imgrc=_" target="_blank" rel="noopener">Happy dog</a> |
보다시피 rel 속성을 붙여준것을 알 수 있다.
rel="noopener noreferrer"
오래전에 발견된 이 피싱공격에 대해 Google, Facebook, Twitter와 같은 해외의 기업들은 tabnabbing에 대한 대응을 잘 하고 있다. 하지만 9년이 지난 현재까도 국내의 유명 포털사이트들의 소스코드를 열어본다면 이 위험에 대해 예방해 놓지 않고 있다는 것을 알 수 있다.
*이 기능을 알면서도 SEO 순위를 우려하여 사용하지 않는 개발자들도 있다. 하지만 rel="noopener"
을 사용하더라도 SEO에 대한 영향을 주지는 않으니 안전성을 위해 사용하도록 하자!! SEO와 효율성에 관한 글은 여기서 읽어보길
예방된 사이트와 그렇지 않은 사이트
브라우저 콘솔창에서 rel 속성을 사용한것과 그렇지 않았을때의 차이점을 비교해보도록 하자.
첫번째 예는 rel="noopener noreferrer"
속성을 주지 않은 case이다. '코스피' 라는 텍스트를 클릭하면 새 창으로 이동된다. 새롭게 열린 창에서 Developer console을 이용하여 window.opener
에 접근 가능한지 시도해 보았다.
window.opener의 접근이 정말 잘 된다...해당 URL을 replace 하여 피싱 공격을 시도할 수 있다.
두번째 예는 예방을 잘 해놓은 case이다. 첫번째 case 처럼 window.opener
에 접근 시도를 해 보았으나 null
의 값이 찍히면서 접근이 막힌 것을 볼 수 있다.
* 만약 새 창 띄우기를 한다면 rel="noopener noreferrer"
을 이용하여 유저의 정보를 보호하기 위해 예상되는 tabnabbing의 위험성을 미리 제거하도록 하자 *
Reference
- 피싱(Phishing) 위협 및 대응 방안
- What all Developers need to know about: Reverse Tabnabbing
- About rel=noopener
- Window.opener
- noopener and browser compatibility
- Reverse Tabnabbing
- rel="noopener"을 사용하여 외부 앵커를 여는 사이트
- The performance benefits of rel=noopener
- Firefox 54 finally goes multiprocess, eight years after work began
- Electrolysis