크로스사이트 요청위조

From IT위키
(Redirected from CSRF)

분류:보안분류:보안 공격분류:정보보안기사 CSRF : Cross-Site Request Forgery

개요[edit | edit source]

  • 특정 웹사이트에 대해서 사용자가 인지하지 못한 상황에서 사용자의 의도와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 요청하게 하는 공격
  • 웹 응용프로그램이 사용자로부터 받은 요청에 대해서 사용자가 의도한 대로 작성되고 전송된 것인지 확인하지 않는 경우 발생 가능
    • 특히 해당 사용자가 관리자인 경우 사용자 권한관리, 게시물삭제, 사용자 등록 등 관리자 권한으로만 수행 가능한 기능을 공격자의 의도대로 실행시킬 수 있게 됨
  • 공격자는 사용자가 인증한 세션이 특정 동작을 수행하여도 계속 유지되어 정상적인 요청과 비정상적인 요청을 구분하지 못하는 점을 악용
  • 웹 응용프로그램에 요청을 전달할 경우, 해당 요청의 적법성을 입증하기 위하여 전달되는 값이 고정되어 있고 이러한 자료가 GET 방식으로 전달된다면 공격자가 이를 쉽게 알아내어 원하는 요청을 보냄으로써 위험한 작업을 요청할 수 있게 됨

보안 대책[edit | edit source]

  • 입력화면 폼 작성시 GET 방식보다는 POST 방식을 사용하고 입력화면 폼과 해당 입력을 처리하는 프로그램 사이에 토큰을 사용하여, 공격자의 직접적인 URL 사용이 동작하지 않도록 처리
  • 중요한 기능에 대해서는 사용자 세션검증·재인증 유도

안전한 코드 예제[edit | edit source]

// 입력화면이 요청되었을 때, 임의의 토큰을 생성한 후 세션에 저장한다.
session.setAttribute(SESSION_CSRF_TOKEN, UUID.randomUUID().toString());

// 입력화면에 임의의 토큰을 HIDDEN 필드항목의 값으로 설정해 서버로 전달되도록 한다.
<input type=hidden name=param_csrf_token value=${SESSION_CSRF_TOKEN}/>

// 요청 파라미터와 세션에 저장된 토큰을 비교해서 일치하는 경우에만 요청을 처리한다.
String pToken = request.getParameter(param_csrf_token);
String sToken = (String)session.getAttribute(SESSION_CSRF_TOKEN);

if (pToken != null && pToken.equals(sToken) {
 // 일치하는 토큰이 존재하는 경우 -> 정상 처리
 ......

} else {
 // 토큰이 없거나 값이 일치하지 않는 경우 -> 오류 메시지 출력
 ......

}

출처[edit | edit source]