요즘 스프링 시큐리티를 적용한 뒤로 자꾸 CSRF 관련으로 문제가 생겼어요. 얘가 대체 뭐길래!! 저를 이렇게 고통스럽게 하는지 궁금해서 오늘은 CSRF 공격에 대해서 다뤄보겠습니다.
CSRF란?
Cross-site request forgery 줄여서 CSRF는 사이트 사이의 위조 요청이라는 뜻을 가지고 있습니다. 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 웹사이트에 요청하게 하는 공격을 말합니다.
공격자는 웹사이트가 신뢰하고 있는 사용자의 권한을 이용해서 중요 행동을 실행합니다. 웹사이트 입장에서는 출처가 신뢰할 만한 곳이기 때문에 공격에 노출된다고 합니다.
CSRF 동작 방식
일단 아래와 같은 전제사항이 충족해야 된다고 합니다.
1. 공격자가 유도해야 할 이유가 있는 응용 프로그램 내의 작업이 있습니다. 개인정보에 접근할 수 있고, 혹은 글을 작성하는 등 권한을 통해서 공격자가 취하고 싶은 행동이 공격의 배경 이유가 되겠습니다.
2. 쿠키 기반 세션 처리 : 작업을 수행하려면 하나 이상의 HTTP 요청을 발급해야 하며, 응용 프로그램은 요청을 작성한 사용자를 식별하기 위해 세션 쿠키에만 의존합니다. 세션을 추적하거나 사용자 요청을 검증하기 위한 다른 메커니즘은 없습니다.
3. 예측할 수 없는 요청 매개 변수가 없습니다. 액션을 수행하는 요청에는 공격자가 결정하거나 추측할 수 없는 값을 가진 매개 변수가 포함되어 있지 않습니다. 예를 들어 사용자가 암호를 변경하도록 할 때 공격자가 기존 암호의 값을 알아야 하는 경우에는 기능이 취약하지 않습니다.
예전 옥션 해킹 사건을 기준으로 예시를 들어보겠습니다.
...
<img src="http://auction.com/changeUserAcoount?id=admin&password=admin" width="0" height="0">
...
- 옥션 관리자가 관리 권한을 가지고(이미 유효한 쿠키 발급된 상태로) 메일을 조회합니다.
- 해커는 위와 같이 태그가 들어간 코드가 담긴 이메일을 보낸다. 단, 관리자는 이미지 크기가 0이므로 이미지가 있는지 눈치를 채지 못합니다.
- 관리자가 메일을 열면 이미지 파일을 받아오기 위해 URL이 열리게 됩니다.
- 그렇게 되면 해커가 원하는 대로 관리자의 계정이 id와 pw 모두 admin인 계정으로 변경된다고 합니다.
혹은 다음과 같은 예시도 있네요.
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
취약한 웹사이트에서 쿠키를 보유중인 사용자가 트리거 행위를 합니다. 그러면 바로 hidden 타입으로 값을 해커 마음대로 변경해서 권한을 탈취할 수 있습니다.
겉으로 보면 쉬워보이는데 그래서 더더욱 조심해야되는 취약점이라고 생각합니다.
방어 방법
Referrer 검증
request header에 있는 요청을 한 페이지의 정보가 담긴 referrer 속성을 검증하여 차단을 합니다. 옥션이 아닌 개인 이메일에서 요청이 들어오는 것처럼 같은 도메인 상에서 요청이 들어오지 않는다면 차단하도록 합니다.
CSRF Token 사용
랜덤값을 사용자의 세션에 저장하고 모든 요청을 다 이 토큰을 이용해서 검증을 합니다. 스프링 시큐리티를 사용하면서 저는 이 방식으로 POST 요청마다 토큰을 같이 보냈습니다.
CAPTCHA 사용
로봇인지 아닌지 체크하는 바로 그 CAPTCHA가 맞습니다. 이걸로 사용자가 의도한 요청인지 아니면 트리거로 동작하는지 걸러낼 수 있겠네요.
출처
옥션 예시
https://sj602.github.io/2018/07/14/what-is-CSRF/
csrf에 대해 더 깊게 다루는 해외 문서
https://portswigger.net/web-security/csrf
'TechTalk' 카테고리의 다른 글
Kafka vs RabbitMQ (3) | 2021.05.25 |
---|---|
[책 리뷰] RESTful Web API (1) | 2021.05.24 |
[IntelliJ] Java file outside of source root 에러 해결법 (1) | 2021.05.07 |
네이버 블로그 구글 검색 등록하기 (0) | 2021.04.29 |
2021 LINE 라인 코딩테스트 후기 (0) | 2021.03.20 |