[HTTP 로깅 개선] HttpLoggingFilter에서 password 파라미터 및 cookie, Set-Cookie 헤더의 민감 정보를 마스킹하는 기능을 추가하여 보안성을 강화
This commit is contained in:
		@@ -112,6 +112,8 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
 | 
				
			|||||||
                .replaceAll("(?i)(\"AccessToken\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3")
 | 
					                .replaceAll("(?i)(\"AccessToken\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3")
 | 
				
			||||||
                .replaceAll("(?i)(\"RefreshToken\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3")
 | 
					                .replaceAll("(?i)(\"RefreshToken\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3")
 | 
				
			||||||
                .replaceAll("(?i)(\"authorization\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3");
 | 
					                .replaceAll("(?i)(\"authorization\"\\s*:\\s*\")([^\"]+)(\")", "$1***$3");
 | 
				
			||||||
 | 
					        // x-www-form-urlencoded 형태의 password 파라미터 마스킹
 | 
				
			||||||
 | 
					        masked = masked.replaceAll("(?i)(^|[&])password=([^&]*)", "$1password=***");
 | 
				
			||||||
        return masked;
 | 
					        return masked;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,11 +122,18 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
 | 
				
			|||||||
        // 필요한 헤더만 추리거나, 전부 찍고 민감한 건 마스킹
 | 
					        // 필요한 헤더만 추리거나, 전부 찍고 민감한 건 마스킹
 | 
				
			||||||
        Collections.list(request.getHeaderNames()).forEach(name -> {
 | 
					        Collections.list(request.getHeaderNames()).forEach(name -> {
 | 
				
			||||||
            String value = request.getHeader(name);
 | 
					            String value = request.getHeader(name);
 | 
				
			||||||
            if ("authorization".equalsIgnoreCase(name) && value != null) {
 | 
					            if (value == null) {
 | 
				
			||||||
                headers.put(name, value.startsWith("Bearer ") ? "Bearer ***" : "***");
 | 
					                headers.put(name, null);
 | 
				
			||||||
            } else {
 | 
					                return;
 | 
				
			||||||
                headers.put(name, value);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ("cookie".equalsIgnoreCase(name)) {
 | 
				
			||||||
 | 
					                headers.put(name, maskCookieHeader(value));
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 기타 헤더는 그대로 기록 (요구사항에 따라 최소 마스킹 적용)
 | 
				
			||||||
 | 
					            headers.put(name, value);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        return headers.toString();
 | 
					        return headers.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -132,11 +141,17 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
 | 
				
			|||||||
    private String getResponseHeaders(HttpServletResponse response) {
 | 
					    private String getResponseHeaders(HttpServletResponse response) {
 | 
				
			||||||
        Map<String, String> headers = new LinkedHashMap<>();
 | 
					        Map<String, String> headers = new LinkedHashMap<>();
 | 
				
			||||||
        for (String name : response.getHeaderNames()) {
 | 
					        for (String name : response.getHeaderNames()) {
 | 
				
			||||||
            if ("authorization".equalsIgnoreCase(name)) {
 | 
					            if ("set-cookie".equalsIgnoreCase(name)) {
 | 
				
			||||||
                headers.put(name, "***");
 | 
					                List<String> values = new ArrayList<>(response.getHeaders(name));
 | 
				
			||||||
            } else {
 | 
					                List<String> masked = new ArrayList<>();
 | 
				
			||||||
                headers.put(name, String.join(",", response.getHeaders(name)));
 | 
					                for (String v : values) {
 | 
				
			||||||
 | 
					                    masked.add(maskSetCookieHeader(v));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                headers.put(name, String.join(",", masked));
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            headers.put(name, String.join(",", response.getHeaders(name)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (response.getContentType() != null) {
 | 
					        if (response.getContentType() != null) {
 | 
				
			||||||
            headers.putIfAbsent("Content-Type", response.getContentType());
 | 
					            headers.putIfAbsent("Content-Type", response.getContentType());
 | 
				
			||||||
@@ -144,6 +159,24 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
 | 
				
			|||||||
        return headers.toString();
 | 
					        return headers.toString();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Cookie 헤더: "a=1; AccessToken=xxx; RefreshToken=yyy" 형태 중 AccessToken/RefreshToken만 마스킹
 | 
				
			||||||
 | 
					    private String maskCookieHeader(String cookieHeader) {
 | 
				
			||||||
 | 
					        if (cookieHeader == null || cookieHeader.isEmpty()) return cookieHeader;
 | 
				
			||||||
 | 
					        String masked = cookieHeader
 | 
				
			||||||
 | 
					                .replaceAll("(?i)(^|;\\s*)(AccessToken)=([^;]*)", "$1$2=***")
 | 
				
			||||||
 | 
					                .replaceAll("(?i)(^|;\\s*)(RefreshToken)=([^;]*)", "$1$2=***");
 | 
				
			||||||
 | 
					        return masked;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set-Cookie: "AccessToken=xxx; Path=/; HttpOnly; ..." 형태 중 AccessToken/RefreshToken만 마스킹
 | 
				
			||||||
 | 
					    private String maskSetCookieHeader(String setCookie) {
 | 
				
			||||||
 | 
					        if (setCookie == null || setCookie.isEmpty()) return setCookie;
 | 
				
			||||||
 | 
					        String masked = setCookie
 | 
				
			||||||
 | 
					                .replaceAll("(?i)^(AccessToken)=([^;]*)", "$1=***")
 | 
				
			||||||
 | 
					                .replaceAll("(?i)^(RefreshToken)=([^;]*)", "$1=***");
 | 
				
			||||||
 | 
					        return masked;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected boolean shouldNotFilter(HttpServletRequest request) {
 | 
					    protected boolean shouldNotFilter(HttpServletRequest request) {
 | 
				
			||||||
        String path = request.getRequestURI();
 | 
					        String path = request.getRequestURI();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user