운영에서만 데이터가 안 쌓이는 일이 생겼다. 황당하다. 분명 로컬과 개발에도 잘 되었었는데... 심지어 개발서버에서 조차 멀쩡한데 운영에 올리니 특정 테이블만 안 생겼다(이런 게 제일 무섭다). XML 쪽은 평소에 깊게 안 다뤄봐서, 검색해가며 더듬더듬 잡은 거라 기록해둔다.
증상
외부에서 받아온 데이터를 XML로 만들어 DB에 적재하는 배치였는데:
- 메타 테이블 ○ / 이력 테이블 ○ / 본문 테이블만 0건
- 앞단(메타 저장)은 됐는데, XML을 만들어 본문을 넣는 단계에서 조용히 깨진 모양이었다.
원인 찾기
로그를 까보니 이 에러가 있었다.
Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD
문제 코드는 이 부분.
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
검색해보니 XXE(외부 엔티티 주입) 막으려고 외부 DTD·스타일시트 접근을 차단하는 보안 설정이란다. 그런데 운영 JBoss에선 이 setAttribute에서 예외가 나면서 XML 생성이 통째로 멈춰 있었다.
로컬은 멀쩡한데 운영만 깨지길래 더 찾아봤더니, 이런 얘기더라.
- 로컬은 Tomcat이라 JDK에 기본으로 든 XML 구현체를 쓰는데, 그건 이 속성을 지원한다고.
- 운영은 JBoss라 자체 XML 모듈에 든 구현체가 대신 올라오는데, 그게 이 속성을 안 받는다고 한다.
즉 같은 코드라도 클래스패스에 어떤 TransformerFactory가 로딩되냐에 따라 갈리는 거라더라.
"Tomcat에선 되는데 JBoss에 올리니 깨진다"는 게 이래서 나오는 듯하다(WebLogic 같은 WAS도 비슷하게 당한다고 한다).
왜 JBoss 구현체만 유독 이 속성을 안 받는지, 그 안쪽까지는 솔직히 모르겠다. 일단 원인 위치는 잡혔으니 넘어갔다.
흐름은 이렇게 무너진 듯하다: XML 생성 실패 → 문서 객체가 null → DB insert 실패 → 본문 테이블 안 생김. 앞단은 이미 저장돼서 "반쪽"만 남는다.
해결
급하면 그 두 줄 주석 처리하면 돌아가긴 하더라. 근데 보안 설정을 통째로 버리는 거라 찝찝했다. 검색해보니 환경마다 구현체가 다르니 "지원하면 적용, 아니면 넘어가게" try-catch로 감싸라길래, 그렇게 했더니 운영에서도 멀쩡히 돌았다.
try {
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
} catch (IllegalArgumentException e) {
logger.warn("이 환경 TransformerFactory는 ACCESS_EXTERNAL_DTD 미지원, 건너뜀: {}",
transformerFactory.getClass().getName());
}
try {
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
} catch (IllegalArgumentException e) {
logger.warn("이 환경 TransformerFactory는 ACCESS_EXTERNAL_STYLESHEET 미지원, 건너뜀: {}",
transformerFactory.getClass().getName());
}
- ACCESS_EXTERNAL_SCHEMA는 TransformerFactory보다 SchemaFactory/Validator 쪽에 맞는 속성이라더라. 여기선 빼는 게 낫다고 해서 뺐다.
- FEATURE_SECURE_PROCESSING은 대부분 구현체가 지원한다길래, 보안 기본기는 챙기는 셈 치고 그건 살려뒀다.
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
남는 메모
- 운영에서만 터지는 XML 에러는 WAS에 딸려온 XML 구현체 차이부터 의심하면 되는 듯하다. 로컬 Tomcat → 운영 JBoss(또는 WebLogic)처럼 실행 환경이 바뀔 때 잘 생긴다더라.
- 보안 설정은 "되면 적용, 아니면 통과"로 방어적으로 거는 게 안전한 것 같다(한 줄 때문에 기능 전체가 멈추면 곤란하니까).
끝.
보안 설정 한 줄이 운영 데이터 절반을 날릴 줄은 몰랐다(다음에 운영만 비는 데이터 있으면 XML 구현체부터 의심할 것).
'IT 웹개발 > WEB WAS' 카테고리의 다른 글
| 웹서버 취약점으로 Apache2.4.46 에서 2.4.58로 버전 업그레이드 (0) | 2023.10.31 |
|---|---|
| [Ubuntu] 리눅스 우분투에 Apache 2.4.46 수동 설치 방법 (0) | 2023.10.30 |
| Apache 아파치 웹서버 다운로드 링크 (최신버전, 이전버전 ) (0) | 2023.10.30 |
| [TOMCAT] 톰캣 특정 IP(아이피)만 접근 허용 및 제한 (0) | 2023.01.04 |
| 웹접근성 진단규칙 (0) | 2022.12.29 |