guardia-cms/backend/src/main/java/com/zioinfo/cms/integration/ItsmSecuritySanitizer.java

63 lines
2.0 KiB
Java

package com.zioinfo.cms.integration;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* GUARDiA 연계 응답 보안 새니타이저.
*
* <p>보안 불변 규칙: 서버 자격증명(IP/SSH 계정/비밀번호 등)을 API 응답에 절대 노출하지 않는다.
* ITSM/Mall/CRM/OCR/BI 연계 응답을 CMS로 반환하기 전 반드시 {@link #clean(Object)}를 호출한다.
*
* <p>Map/List 구조를 재귀적으로 순회하며 민감 필드를 제거한다.
*/
public final class ItsmSecuritySanitizer {
private static final Set<String> SENSITIVE_KEYS = Set.of(
"ip_addr", "ipaddr", "ssh_user", "sshuser", "os_pw_enc", "ospwenc",
"password", "password_enc", "passwordenc", "ssh_key", "sshkey",
"secret", "token", "private_key", "credential"
);
private ItsmSecuritySanitizer() {
}
/**
* 응답 데이터에서 민감 필드를 재귀 제거한다.
*
* @param data Map(필터링), List(각 원소 적용), 그 외(그대로 반환)
* @return 민감 필드가 제거된 데이터
*/
public static Object clean(Object data) {
if (data instanceof Map<?, ?> map) {
Map<String, Object> cleaned = new LinkedHashMap<>();
for (Map.Entry<?, ?> entry : map.entrySet()) {
String key = String.valueOf(entry.getKey());
if (isSensitive(key)) {
continue;
}
cleaned.put(key, clean(entry.getValue()));
}
return cleaned;
}
if (data instanceof List<?> list) {
List<Object> cleaned = new ArrayList<>(list.size());
for (Object item : list) {
cleaned.add(clean(item));
}
return cleaned;
}
return data;
}
private static boolean isSensitive(String key) {
if (key == null) {
return false;
}
return SENSITIVE_KEYS.contains(key.toLowerCase());
}
}