Network

예시로 이해하는 CSRF Attack

ju_young 2024. 1. 10. 09:48
728x90

다음과 같이 어떤 은행에 1000원을 이체하는 GET 요청이 있다고 해보자.

GET http://netbank.com/transfer.do?acct=PersonB&amount=1000 HTTP/1.1

 

한 해커는 위와 같은 요청을 수정하여 다음과 같이 자신의 계좌로 이체하도록 만들 수 있다.

GET http://netbank.com/transfer.do?acct=AttackerA&amount=1000 HTTP/1.1

 

그리고 이렇게 수정한 링크를 하이퍼링크로 삽입하여 여러 사용자들에게 메일을 보낼 수 있게된다.

<a href="http://netbank.com/transfer.do?acct=AttackerA&amount=1000">Read more!</a>

 

이런 메일을 받은 어떤 사람이 은행 계정에 로그인된 상태로 클릭하게되면 해커의 계좌로 이체하게 되는 것이다.

POST 요청으로 이체를 수행하는 은행은 위와같이 <a> 태그를 사용할 수 없다. 하지만 embedded javascript를 사용하여 <form> 를 전송하도록 실행하게 만들 수 있다.

 <body onload="document.forms[0].submit()">
   <form action="http://netbank.com/transfer.do" method="POST">
     <input type="hidden" name="acct" value="AttackerA"/>
     <input type="hidden" name="amount" value="$100"/>
     <input type="submit" value="View my pictures!"/>
   </form>
 </body>

 

이러한 CSRF Attack을 방어하기위해 악의적인 요청인지 아닌지를 판단할 수 있는 방법이 CSRF token이다. 예를 들어 POST 요청을 하는 <form>은 다음과 같이 _csrf라는 값이 랜덤으로 생성된다.

<form method="post"
    action="/transfer">

    <input type="hidden"
        name="_csrf"
        value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>

    <input type="text"
        name="amount"/>
    <input type="text"
        name="routingNumber"/>
    <input type="hidden"
        name="account"/>
    <input type="submit"
        value="Transfer"/>
</form>

 

따라서 정상적인 루트로 요청한 것들만 정상적으로 처리되게 한다. 요청을 할 때마다 CSRF token이 필요한데 사용자만 알 수 있는 CSRF token을 해커가 알 수 없으니 앞서 살펴본 방법으로 공격할 수가 없는 것이다.


[reference]
https://docs.spring.io/spring-security/reference/features/exploits/csrf.html
https://www.imperva.com/learn/application-security/csrf-cross-site-request-forgery/

728x90

'Network' 카테고리의 다른 글

HTTP 버전별 특징  (0) 2023.05.25
[웹 브라우저의 동작] 4. 프로토콜 스택  (0) 2021.05.16
[웹 브라우저의 동작] 3. DNS  (0) 2021.05.15
[웹 브라우저의 동작] 2. IP  (0) 2021.05.14
[웹 브라우저의 동작] 1. HTTP  (0) 2021.05.12