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 연계 응답 보안 새니타이저. * *

보안 불변 규칙: 서버 자격증명(IP/SSH 계정/비밀번호 등)을 API 응답에 절대 노출하지 않는다. * ITSM/Mall/CRM/OCR/BI 연계 응답을 CMS로 반환하기 전 반드시 {@link #clean(Object)}를 호출한다. * *

Map/List 구조를 재귀적으로 순회하며 민감 필드를 제거한다. */ public final class ItsmSecuritySanitizer { private static final Set 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 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 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()); } }