diff --git a/build.gradle b/build.gradle index 90b7ea6..e0ffd74 100644 --- a/build.gradle +++ b/build.gradle @@ -80,9 +80,10 @@ dependencies { // exclude group: 'commons-collections', module: 'commons-collections' } implementation 'org.mapstruct:mapstruct:1.5.5.Final' - implementation 'com.fasterxml.jackson.core:jackson-core:2.15.3' - implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.3' - implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3' + // WS-2026-0003 (jackson-core async parser DoS, CVSS 7.5) — 2.18.6 에서 수정. JDK8 호환. + implementation 'com.fasterxml.jackson.core:jackson-core:2.18.6' + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.18.6' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.6' implementation group: 'org.apache.velocity', name: 'velocity-engine-core', version: '2.3' diff --git a/src/main/java/com/eactive/apim/portal/apps/apis/filter/ApiTesterFilter.java b/src/main/java/com/eactive/apim/portal/apps/apis/filter/ApiTesterFilter.java index 6899963..c7dfd23 100644 --- a/src/main/java/com/eactive/apim/portal/apps/apis/filter/ApiTesterFilter.java +++ b/src/main/java/com/eactive/apim/portal/apps/apis/filter/ApiTesterFilter.java @@ -203,6 +203,14 @@ public class ApiTesterFilter implements Filter { } proxyTarget = targetUri; + if (logger.isDebugEnabled()) { + // GW SERVICE_NOT_FOUND(어댑터 URI 미등록)·AUTH_FAIL 진단용: + // 스펙 식별/응답유형, 실제 forward 대상, 전달 헤더(민감값 마스킹), 본문 길이를 남긴다. + logger.debug("{} forward - auditId={}, apiId={}, apiUrl={}, apiMethod={}, responseType={}, originalUrl={}, target={}, bodyLen={}, headers={}", + auditType, auditId, apiSpecInfoDto.getApiId(), apiSpecInfoDto.getApiUrl(), + apiSpecInfoDto.getApiMethod(), responseType, url, targetUri, + requestBody == null ? 0 : requestBody.length(), maskHeaders(headers)); + } APISender apiSender = ApplicationContextUtil.getContext().getBean(APISender.class); String responseStr; if ("post".equalsIgnoreCase(apiSpecInfoDto.getApiMethod())) { @@ -210,6 +218,11 @@ public class ApiTesterFilter implements Filter { } else { responseStr = apiSender.requestGet(targetUri, headers, paramMap); } + if (logger.isDebugEnabled()) { + logger.debug("{} response - auditId={}, target={}, respLen={}, preview={}", + auditType, auditId, targetUri, + responseStr == null ? 0 : responseStr.length(), previewOf(responseStr)); + } response.setContentType("application/json"); response.getWriter().println(responseStr); } @@ -308,6 +321,27 @@ public class ApiTesterFilter implements Filter { } /** 상태코드 + JSON 본문 응답. */ + /** forward 헤더 debug 출력용 — 민감 헤더(토큰/쿠키 등)는 StringMaskingUtil 로 마스킹. */ + private String maskHeaders(Map headers) { + StringBuilder sb = new StringBuilder("{"); + for (Map.Entry e : headers.entrySet()) { + if (sb.length() > 1) { + sb.append(", "); + } + sb.append(e.getKey()).append(':').append(StringMaskingUtil.maskHeaderValue(e.getKey(), e.getValue())); + } + return sb.append('}').toString(); + } + + /** 응답 body debug 프리뷰 — 앞 300자까지만 (개행 제거). */ + private String previewOf(String body) { + if (body == null) { + return "null"; + } + String flat = body.replaceAll("\\s+", " ").trim(); + return flat.length() > 300 ? flat.substring(0, 300) + "…" : flat; + } + private void writeJson(ServletResponse response, int status, String json) throws IOException { ((HttpServletResponse) response).setStatus(status); response.setContentType("application/json");