Reverse Tabnabbing
Introduction
Reverse tabnabbing은 특정 조건에서 a, iframe 및 window.open() 등으로 생성된 child page가 parents page를 일부 제어할 수 있는 특성을 이용해 피싱 사이트로 parents page를 변경하는 취약점을 의미합니다.
target blank
보통 가장 흔한 경우가 a 등의 태그에서 target="_blank"
를 사용한 경우입니다. 특히 사용자가 html 태그를 직접 사용할 수 있는 서비스(메일, 마크업을 포함한 게시판 등)에선 쉽게 공격에 성공할 수 있기 떄문에 중요도에 따라 XSS와 유사하게 _blank
에 대한 제한도 필요합니다.
<a href="https://bad.example.com" target="_blank" rel=opener>Click</a>
단 최근에 브라우저(크롬/파폭/사파리)사에서 rel=noopener
를 기본값으로 가져가는 패치를 적용했습니다. 그래서 아래와 같은 코드는 취약하지 않습니다.
<a href="https://bad.example.com" target="_blank">Click</a>
별도로 rel=opener
처럼 명시해주지 않는 한 opener를 사용할 수 없어졌습니다.
window.open
window.open()
과 같이 javascript 단에서 child page를 여는 경우 _blank
와 동일하게 부모창에 대한 일부 제어권을 얻을 수 있습니다.
<html>
<body>
<button onclick="window.open('https://bad.example.com')">Click</button>
</body>
</html>
Offensive techniques
Detect
reverse tabnabbing을 확인하기 위해선 서비스에서 이미 존재하는 rel="opener"
가 명시된 앵커태그(a tag)를 찾거나 HTML 코드를 사용할 수 있는 영역이 있다면 XSS와 비슷하게 확인할 수 있습니다.
Exploitation
parents page를 제어할 수 있기 때문에 parents page의 document.locaion
등을 변경하여 공격자가 의도한 피싱 사이트로 이동시켜 사용자의 중요 정보를 탈취하는데 사용할 수 있습니다.
제가 테스트를 위해 만들어서 사용하는 페이지를 예시로 들어보면 아래 코드와 같이 _blank
인 경우 child 에서 parents의 일부를 제어할 수 있는 상태가 되며 클릭 시 reverse-tabnabbing-1 페이지는 부모 페이지를 제어할 수 있어집니다.
<a href="https://www.hahwul.com/phoenix/reverse-tabnabbing-1" rel=opener target="_blank">Click me</a>
https://www.hahwul.com/phoenix/reverse-tabnabbing
child page인 reverse-tabnabbing-1 로 접근해보면 소스코드단에 아래와 같이 opener
의 location을 변경하는 코드가 있습니다.
이로인해 해당 코드가 실행되는 순간 parent page의 document.location
이 //www.hahwul.com/phoenix/reverse-tabnabbing-2
로 변경되며 피싱 페이지로 이동하게 됩니다.
MITM
보통은 피싱에 많이 사용되지만 만약 child page가 http를 사용하는 경우 공격자가 쉽게 response 내용을 수정하여 parents page를 일부 제어할 수 있게 됩니다. 공격 시나리오 중 하나 정도로 생각해두면 좋습니다.
Defensive techniques
대응은 간단합니다. a 태그와 같은 링크등에서 target=_blank
를 사용하지 못하도록 제한하거나 rel 속성으로 따로 제한할 수 있습니다.
rel=noopener
rel=noreferrer
rel=noopener noreferrer
다만 noopener가 각 브라우저사에서 기본값으로 변경되면서 rel을 지정하지 않아도 noopener를 사용한 것과 동일하기 떄문에 rel=opener 로 명시하지 못하도록 제한하는 방식으로 대응할 수 있습니다.
https://chromium-review.googlesource.com/c/chromium/src/+/1630010
window.open의 경우 javascript 단에서 이루어지는 형태이기 떄문에 사용자가 스크립트를 사용할 수 없는 환경이라면 취약점이 발생한 window.open의 링크 부분이 신뢰받는 도메인인지 체크가 필요하며, 사용자가 스크립트를 사용할 수 있는 경우 window.open 등 일부 리스크가 있는 메소드는 제한하는 형태로 대응할 수 있습니다.
또한 Referrer-Policy: no-referrer
헤더 등을 통해서 HTTP 프로토콜단에서도 제한할 수 있습니다.