Jenkins 취약점 이슈 해결하기 (CVE-2023-25765)

하루는 클라우드 서비스의 CWPP(Cloud Workload Protection Platform)에서 Jenkins 서버가 떠 있는 인스턴스에 심각한 취약점이 발견되었다는 알람이 왔어요.

2023-10-14-image1 CWPP에서 받은 보안 취약점 알람

확인한 대상은 Jenkins 본체가 아니라 Email Extension 플러그인(email-ext)이었습니다. 이 구분이 해결 방법을 결정해요. Jenkins 본체 버전만 올리고 취약한 플러그인이 그대로 남아 있으면 이 문제는 해결되지 않습니다.

CVE가 말하는 범위부터 확인하기

Jenkins의 2023-02-15 보안 권고문에 따르면 내용은 다음과 같습니다.

항목확인한 내용
식별자CVE-2023-25765 / SECURITY-2939
대상Email Extension Plugin 2.93 이하
문제폴더 안에 정의한 이메일 템플릿에 Script Security 보호가 적용되지 않음
공격 전제공격자가 폴더 안에 이메일 템플릿을 정의할 수 있어야 함
영향Jenkins 컨트롤러 JVM 권한으로 임의 코드 실행 가능
이 CVE의 최초 수정 버전2.93.1

단순히 Jenkins 로그인 화면이 인터넷에 노출되어 있다는 이유만으로 누구나 바로 실행할 수 있는 취약점이라고 설명하면 공격 조건을 과장하게 됩니다. 반대로 템플릿 권한이 제한되어 있어도 취약한 버전을 계속 유지할 근거가 되지는 않아요.

심각도도 출처를 함께 봐야 합니다. Jenkins 권고문은 High로 표기하고, NVD는 NIST의 CVSS 3.1 점수를 9.9, Critical로 제시합니다. 서로 다른 평가를 한 숫자로 합치지 않고, 실제 권한과 노출 범위를 함께 판단하는 게 좋습니다.

업데이트 전에 남길 것

알람에서 지적한 경로, 설치된 플러그인 버전, Jenkins 본체와 실행 Java 버전을 기록합니다. 파일 스캐너가 발견한 패키지가 현재 실행 중인 Jenkins의 플러그인인지도 확인해요. 오래된 백업 파일과 실제 로딩된 플러그인을 구분해야 조치 후 재탐지 이유를 설명할 수 있습니다.

업데이트는 다음 순서로 진행할 수 있습니다.

  1. 진행 중인 빌드를 정리하고 JENKINS_HOME과 설정·플러그인 목록을 복구 가능한 형태로 백업합니다.
  2. 설치하려는 플러그인의 Jenkins 최소 버전과 의존 플러그인을 확인합니다.
  3. 필요할 때만 Jenkins 본체와 실행 Java를 호환되는 조합으로 먼저 준비합니다.
  4. 플러그인 관리 화면에서 Email Extension을 수정된 지원 버전으로 업데이트하고 필요한 재시작을 수행합니다.
  5. 실제 로딩된 버전, 빌드, 메일 알림, 템플릿 동작을 확인한 뒤 CWPP를 다시 검사합니다.

2.93.1은 이 CVE가 처음 수정된 2023년 버전입니다. 지금 새로 설치할 목표 버전을 뜻하지는 않아요. 새 환경에서는 플러그인 페이지의 요구사항과 후속 보안 공지도 함께 확인합니다.

Java 업데이트에서 헷갈리기 쉬운 점

당시 글에는 CentOS에서 Jenkins 본체를 업데이트하는 경우를 위한 Java 호환성 안내도 함께 적었습니다. 다만 그때 사용하던 Java 11 설치 명령이나 오래된 저장소 서명 키를 오늘의 설치 안내처럼 그대로 실행해서는 안 됩니다.

Jenkins Java 지원 정책은 Jenkins를 실행하는 Java와 빌드 대상 애플리케이션의 Java를 구분합니다.

Jenkins 기준실행 Java 지원 범위
LTS 2.361.1부터 적용된 당시 기준Java 11 또는 17
LTS 2.555.1부터 적용된 기준(2026년 4월)Java 21 또는 25

설치한 Jenkins 버전에 대응하는 행을 확인해야 하며, 위 두 행이 모든 중간 버전의 지원 범위를 나타내는 것은 아닙니다. 에이전트의 Jenkins 실행 Java도 함께 확인합니다. 애플리케이션을 빌드하는 JDK는 별도로 유지할 수 있지만, 빌드 도구·플러그인별 추가 조건이 있을 수 있어요.

systemd로 운영하는 Linux 환경이라면 다음은 문제를 확인하는 읽기 전용 명령입니다.

1
2
3
4
java -version
sudo systemctl status jenkins --no-pager
sudo systemctl cat jenkins
sudo journalctl -u jenkins -n 100 --no-pager

첫 명령은 현재 셸의 Java 버전입니다. Jenkins 서비스가 다른 실행 경로나 환경변수를 사용하면 결과가 다를 수 있으니, Jenkins의 System Information과 서비스 설정에서 실제로 사용한 Java를 확인해야 해요. 로그·서비스 설정을 외부에 공유할 때는 토큰과 자격 증명을 제거합니다.

무엇을 확인해야 해결됐다고 할 수 있을까

플러그인 업데이트 화면에 다운로드가 완료됐다는 표시만으로 마무리하지 않습니다.

검증확인하려는 것
재시작 후 설치·로딩된 email-ext 버전취약한 코드가 실행 대상에서 교체됐는지
대표 빌드와 정상 이메일 템플릿 실행의존 플러그인·메일 알림 기능 회귀 여부
Script Security 관련 오류 검토기존 템플릿이 새 보호 규칙에 맞는지
같은 범위의 CWPP 재검사지적된 파일·인스턴스의 조치 반영 여부

템플릿이 막힌다고 sandbox를 통째로 해제하거나 스크립트를 무심코 승인하면 패치의 목적을 잃을 수 있습니다. 필요한 동작을 확인하고 최소한으로 수정하는 편이 맞아요.

또한 취약점 탐지와 실제 침해는 다른 사실입니다. 이번 글의 알람만으로 공격 성공을 주장할 수 없고, 패치만으로 과거 침해가 없었다고 증명할 수도 없습니다. 의심스러운 템플릿 변경·스크립트 승인·계정 사용 기록이 발견된다면 그때는 업데이트와 별도로 조사하고, 노출이 확인된 자격 증명을 교체해야 합니다.

이번 일에서 배운 것은 “Jenkins를 최신으로 올리자”보다 구체적이었습니다. 알람의 패키지를 실제 실행 구성에 연결하고, 수정 버전으로 바꾼 뒤 기능과 탐지 결과까지 확인하는 것이 보안 패치의 완료 조건입니다.

참고 자료