본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


웹 취약점(Web vulnerability)

14. 크로스 사이트 리퀘스트 변조(CSRF)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 12. 6.

크로스 사이트 리퀘스트 변조는 사이트간 요청위조를 의미 합니다.

피해자의 권한으로 피해자 모르게 해커가 요청을 수행 하도록 만드는 것을 의미 합니다.

웹 취약점에서 자주 언급되면서 반드시 조치가 되어야 합니다.

특히 "결재"와 관련된 웹 어플리케이션에서는 필수이며 가장 강력한 수준의 조치가 요구 됩니다.

* 해커가 악성스크립트를 통하여 원치않는 결재, 결재정보노출 등을 할 수 있기 때문 입니다.

 

 

#방법1

가장 첫번째 방지는 크로스 사이트 스크립팅(XS)이 되지 않도록 조치하는 것 입니다.

크로스 사이트 리퀘스트 변조(CSRF)도 결국엔 크로스 사이트 스크립팅(XS)을 통해 실행되는 취약점이기 때문 입니다.

* 참고 : 크로스 사이트 스크립팅(XS) 대비

https://lts0606.tistory.com/545

 

11. 크로스 사이트 스크립팅(XS, XSS, Cross Site Scripting)

취약점에서 가장 많이 시도되며 유명한 크로스 사이트 스크립팅 입니다. 웹 환경에서 다른 최종 사용자의 클라이언트에서 임의의 스크립트가 실행되는 취약점 입니다. 웹 사이트 게시판, 댓글 ,

lts0606.tistory.com

 

#방법2

CSRF를 방지하는 방법은 특정 값을 통하여 요청(Request) 값의 상태를 결과여부에 따라 만료시키는 것 입니다.

예를들어 사용자가 결재를 진행한다고 가정 합니다.

사용자가 상품을 결재하기위해 결재 패이지로 이동하면 사용자에게 특정 값을 발행합니다.

아래는 설명을 위한 Spring 인터셉터 메소드의 모습 입니다.


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class CSRFInterceptor extends HandlerInterceptorAdapter {
    @Override
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        final HttpSession session = request.getSession();
        String _random = RandomStringUtils.randomAlphabetic(20);  //랜덤한 값을 발행 합니다.
        session.setAttribute("내가만든CSRF키값", _random);  //세션에 추가합니다.
        return true;
    }
}

 

이렇게 추가된 값을 브라우저에서 사용할 파일에 추가하여 줍니다.

아래 코드는 ajax함수에서 헤더에 위 인터셉터가 발행한 키 값을 붙이는 모습 입니다.

이렇게 붙여진 키 값은 이제 다시 결재 요청시 인터셉터에게 발행되게 됩니다.

<script>

function 결제함수(params){
    $.ajax({
        url: '결제주소',
        beforeSend : function(xhr){
            xhr.setRequestHeader("내가만든CSRF키값", "${sessionScope.내가만든CSRF키값}")  //요렇게 담습니다
        },		
        data: params,
        type: 'POST',
        success: function (res) {
        
        },
        error : function(err){
            console.log('error');
        }
    })
}
</script>

 

이렇게 한 뒤에 결재요청이 성공 및 실패 여부와 상관없이 결재행동이 이루어지게되면 해당 CSRF키 값을 새로운 값으로 교체를 하게 합니다.

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class CSRFInterceptor extends HandlerInterceptorAdapter {
    @Override
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        final HttpSession session = request.getSession();
        
        final String REQUEST_URL = request.getRequestURL().toString();  //URL검사
        
        if(REQUEST_URL.equals("결재요청주소")) {  //만약 결재요청이면,
            String csrf_key = request.getHeader("내가만든CSRF키값");  //해더에 담긴 키
            
            if(!csrf_key.equals(session.getAttribute("내가만든CSRF키값").toString())){  //헤더와 세션의값이 다르면!
                _random = RandomStringUtils.randomAlphabetic(20);  //랜덤한 값을 발행 합니다.
                session.setAttribute("내가만든CSRF키값", _random);
                return false;  //같지않는 CSRF값으로 요청이 들어왔으므로 거짓을 반환 합니다.
            }

            //같은 CSRF값으로 요청이 들어왔으므로 값을 초기화합니다.(이해를위해 추가한 부분 입니다)
            String random = RandomStringUtils.randomAlphabetic(20);  
            session.setAttribute("내가만든CSRF키값", random);            
            return true;
        }
        
        String _random = RandomStringUtils.randomAlphabetic(20);  //랜덤한 값을 발행 합니다.
        session.setAttribute("내가만든CSRF키값", _random);  //세션에 추가합니다.        
        
        return true;
    }
}

 

이러한 패턴으로 사용자에게 전달한 키 값이 변조가 되었는지를 확인하고, 요청이 완료되었으면 해당 값을 갱신하여 새로운 값을 사용자가 쓰도록 하게 해 주는 것이 크로스 사이트 리퀘스트 변조(CSRF) 방지방법 입니다.

 

#방법3

프레임워크의 기반의로의 조치가 필요하다면 Spring Security를 통하여 해당 조치를 하는 것 입니다.

Spring security를 활용하면 위 단계를 조금 더 CSRF값을 편리하게 사용할 수 있게 해 줍니다.

하지만 Spring 시큐리티에서도 발행하는 값과 검증을 쉽게 해 주는 것일뿐 결국 클라이언트(jsp, html, js 등)에서 해당 CSRF값을 포함하여 서버로 전송해야되는 기능이 존재 해야됩니다.

 

 

이상으로 크로스 사이트 리퀘스트 변조(CSRF) 조치 방법에 대해서 간단하게 살펴보았습니다.

궁금한점 또는 틀린 부분은 언제든 연락주세요! 👻

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글