개요
기존에는 BlackList의 TTL을 대강 AccessToken의 Exp기간과 똑같이 잡았었는데,
유저가 만료시간 직전에 로그아웃을 하는 경우 Redis에 불필요하게 오랫동안 BlackList를 저장하게 된다.
30분짜리 AccessToken의 만료시간이 1분 남았을 때,
블랙리스트로 30분간 저장해놓게 된다면 29분간 쓸모없는 데이터가 생기는 것이다.
솔직히 블랙리스트 하나 당 216B밖에 되지 않아서 무시해도 될 수준 아닌가? 싶지만, 100만건이 한번에 몰리면 216MB가 된다.
거기다 우리는 RefreshToken도 Redis로 관리하므로 함께 생각하는 편이 좋다.
해결
public void addToBlackList(String token) {
String blackPrefix = jwtSecurityProperties.token().blackListPrefix();
String key = blackPrefix + token;
Claims claims = jwtUtil.extractClaims(token);
long expirationMillis = claims.getExpiration().getTime() - System.currentTimeMillis();
if (expirationMillis > 0) {
redisTemplate.opsForValue().set(key, "blackList", expirationMillis + 1000, TimeUnit.MILLISECONDS);
}
}
BlackList의 TTL을 현재 AccessToken의 만료까지 걸리는 시간 + 1초로 설정했다.
관리해야 할 properties도 줄고 편한 구조를 갖게 되었다.
SecurityConfig headers
이번에 새로운 프로젝트를 진행하게 되면서 Spring security와 jwt를 함께 사용하게 됐는데, security의 header들이 각각 어떤 역할을 하는지 짚어보자.
.headers(headers -> headers
.xssProtection(xss -> xss.headerValue(XXssProtectionHeaderWriter.HeaderValue.from("1; mode=block"))) //XSS 공격 방지
.contentTypeOptions(HeadersConfigurer.ContentTypeOptionsConfig::disable) //MIME 스니핑 방지
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) //ClickJacking 방지
.referrerPolicy(referrer -> referrer.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)) //Referrer 비활성화
.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'; script-src 'self' 'nonce-randomValue'"))//XSS 방지
);
1.MIME Sniffing
브라우저가 Content-Type과 실제 내용이 다를 때, 내용을 보고 파일 타입을 추측해서 실행하는 현상이다.
예를 들어 Type은 text/plain인데 실제는 HTML이면, 브라우저가 "이거 HTML이구나" 하고 HTML로 실행해버린다.
해커가 이미지 파일로 위장한 HTML/JS파일을 업로드하면 브라우저가 HTML로 실행하게 되고, XSS공격이 이루어진다.
contentTypeOptions.. 헤더를 추가해주면, Content-Type 값만 믿도록 강제할 수 있다.
2. Clickjacking
해커가 iframe안에 내 페이지를 몰래 넣고, 유저 클릭을 유도해서 의도치 않은 행동을 유도하는 공격이다.
예를 들어 로그인 버튼 위에 투명한 공격용 버튼을 덮는 것이다.
frameOptions...헤더를 추가해주면, 내 사이트는 나랑 같은 origin에서만 iframe으로 렌더링될 수 있다. 즉, 다른 도메인에서 iframe으로 불러오면 차단된다.
3. Referrer Policy
브라우저가 요청을 보낼 때 Referer헤더에 어디서 왔는지(URL)를 같이 보낸다.
민감한 페이지 이동 시, 이게 노출된다면 정보 유출이 가능하기 때문에
referrerPolicy... 헤더를 추가해서, 어디서 왔는지 절대 노출이 안되게끔 해준다.
4. XSS
xss헤더가 두개인데, 위의 헤더는 옛날 브라우저(인터넷익스플로어)를 위한 기본적인 XSS 방어 헤더다. 그냥 보완용이라고 보면 되고,
아래(.contentSecurityPolicy...)가 핵심이다. 허용된 스크립트만 실행 가능하게 하고, inline script를 차단해준다.
'사이드 프로젝트 > co-op.project' 카테고리의 다른 글
알림 구현(1) Kafka + Redis Pub/Sub + WebSocket MVP (0) | 2025.04.07 |
---|