Spring Security : 세션 고정 보호

    이 글은 인프런 정수원님의 강의를 복습하며 작성한 글입니다. 

    세션 고정 보호

    세션 고정은 사용자를 공격하는 한 방법 중 하나다. 공격자가 서버에게서 먼저 세션 ID를 받은 후, 세션 ID를 사용자에게 심어두어 사용자가 그 세션 ID로 인증하도록 유도하는 방법이다. 그림과 함께 아래에서 좀 더 자세히 살펴볼 수 있다. 

    1. 공격자가 서버에 접속한다. 서버는 공격자를 위한 세션을 만들고, SESSION ID = 123456을 응답해준다.
    2. 공격자는 응답받은 123456을 사용자에게 심어둔다. (사용자에게 세션 고정)
    3. 사용자는 SESSION ID = 123456을 헤더에 싣고, 서버에게 인증 요청을 한다.
    4. 서버는 인증을 하고, 인증 객체를 SESSION ID = 123456인 세션에게 담아주고, 응답을 내려준다. 
    5. 공격자가 SESSION ID = 123456으로 자원에 접근시도하면, 5에서 인증이 되었기 때문에 원하는 자원에 접근이 가능해짐. 

    손쉽게 접근할 수 있는 아주 쉬운 공격인데, 효과는 정말 굉장할 것 같다. 여튼 이런 보안적인 문제를 해결하기 위해 Spring Security는 '세션고정' 공격을 보호할 수 있는 방안을 몇 가지 제공해준다. 

     

    세션고정 보호 API : HttpSecurity 객체에서 처리 

    • http.sessionManagement() : 세션 관리 설정 모드 사용. 
    • sessionFixation().changeSessionId() : 사용자가 인증 성공하면, 기존 사용자의 세션에 Session ID만 변경됨.
    • sessionFixation().none() : 세션 고정 보호를 하지 않음. 
    • sessionFixation().newSession() : 사용자가 인증 성공하면 새로운 세션이 생성된다. 이 때, 이전 세션에서 사용하던 세션 정보를 사용할 수 없음.
    @Override
    protected void configure(HttpSecurity http) throws Exception {}

    위 메서드를 Override하면서 HttpSecurity 객체의 API를 적용하면서 처리할 수 있다. 

     

    세션 고정 보호 관련 코드로 확인해보기

    Controller 작성

    @GetMapping("/")
    public String index (HttpSession session){
        log.info("Session id = {}", session.getId());
        log.info("Session = {}", session);
        return "None";
    }
    
    @GetMapping("/user")
    public String user(HttpSession session){
        log.info("Login Success");
        log.info("Session id = {}", session.getId());
        log.info("Session = {}", session);
        return "user";
    }

    다음과 같이 Controller를 만들 수 있다. 이 때 목적은 Session Fixation 정책을 바꿔봤을 때, Session Id가 바뀌는지와 Session 객체가 아예 바뀌는지를 살펴보기 위함이다. 

     

    로그인마다 새로운 세션 생성

    http
            .sessionManagement()
            .sessionFixation()
            .newSession();

    SessionManagement().sessionFixation().newSession()을 이용해서 로그인마다 새로운 세션을 만드는지 확인한다. 

    localhost:8080으로 접근해서 먼저 Session Id와 객체의 주소를 확인했다. 이후 로그인을 처리했는데, 로그인 처리 후 Session Id와 Session 객체가 모두 바뀌는 것을 확인했다. 

     

    로그인마다 Session Id 변경

    http
            .sessionManagement()
            .sessionFixation()
            .changeSessionId();

    changeSessionId()로 로그인할 때 마다 세션은 유지, 새로운 Session ID로 바뀌는 전략을 사용했다.

    루트로 로그인 한 후, Session ID와 Session 객체의 주소를 확인한 후 로그인 처리했다. 로그인 처리 후, Session ID는 바뀌지만 Session 객체의 주소값은 바뀌지 않는 것을 확인했다. 

     

    세션고정 보호하지 않음.

    http
            .sessionManagement()
            .sessionFixation()
            .none();

    none()을 통해 세션 고정 보호를 하지 않는 것으로 설정했다. 

    루트로 로그인 한 후, Session ID와 Session 객체의 주소를 확인한 후 로그인 처리했다. 로그인 처리 전/후로 Session Id과 Session 객체의 주소가 같은 것을 확인했다. 

    댓글

    Designed by JB FACTORY