마루옵스서버 · 네트워크 · AI 기술 노트

소개문의

OpenJDK 최신 CVE: Windows·Linux 점검과 조치

Virginia Tech 데이터센터의 서버 랙 사이 통로

참고 사진 · Virginia Tech 데이터센터의 서버 랙 사이 통로 · 사진: Christopher Bowns / 원본 / CC BY-SA 2.0 · 목록용 크기 조정

2026년 10월 OpenJDK 보안 이슈를 점검할 때에는 분기 업데이트와 eMudhra 인증서 신뢰 문제를 함께 확인해야 합니다. Windows와 Linux 모두 대상이 될 수 있어요. 터미널의 기본 Java뿐 아니라 업무 서비스, 개발 도구, 제품에 내장된 JDK·JRE와 컨테이너까지 찾아야 합니다.

이 글은 2026년 10월 26일 확인한 공식 공지를 기준으로 합니다. 점검 명령은 설치 형태별 예시이며, Linux 확인 절차 일부는 별도 Ubuntu 컨테이너에서 검증했습니다. Windows 명령과 운영 서비스의 업데이트·재시작은 실제 장비에서 실행한 결과가 아닌 문서 기반 절차입니다.

이 글의 목차

최근 OpenJDK CVE는 무엇인가

OpenJDK는 Java 실행 환경과 개발 도구의 오픈소스 구현입니다. JDK는 개발 도구를 포함하고, JRE는 실행 환경을 뜻합니다. CVE는 보안 취약점이나 노출 문제를 구분하는 식별자이고, CVSS는 심각도를 나타내는 점수입니다. 점수만으로 개별 시스템의 침해 여부를 판단하지는 않습니다.

이번 점검에서는 다음 세 공지를 구분하면 편해요.

공지확인할 문제조치 판단
10월 20일 분기 업데이트네트워크·이미지·XML·보안 구성 요소 등의 여러 CVE해당 배포사의 분기 수정 패키지 적용
10월 21일 CVE-2026-91403eMudhra 관련 중간 CA 인증서 신뢰 문제, OpenJDK CVSS 3.1 9.1인증서 차단 수정과 실제 신뢰 저장소 확인
10월 24일 CVE-2026-114820관련 루트 CA 인증서 제거를 제공하는 추가 긴급 업데이트, Oracle CVSS 3.1 9.1앞선 업데이트 후에도 추가 공지 대조

OpenJDK 10월 20일 공지와 10월 21일 공지, Oracle 10월 24일 긴급 공지를 대조했습니다. Oracle의 분기 공지는 Java SE 보안 패치 55개를 안내하지만, 이를 모든 OpenJDK 배포판의 동일한 CVE 수로 해석하면 안 됩니다. Oracle 10월 CPU의 제품·버전·적용 조건을 구분해 읽습니다.

영향도: HTTPS를 사용하는 Java 클라이언트도 확인

인증 기관(CA)은 접속 상대의 인증서를 신뢰할 수 있는지 판단하는 연결 고리입니다. eMudhra 이슈는 중간 CA 인증서 8개의 개인 키가 유출되어, 공격자가 위조 인증서를 만들 수 있다는 문제에서 시작됐습니다. Java가 관련 인증서 체인을 계속 신뢰하면 정상 서버라고 판단해 잘못된 상대와 TLS 통신을 할 수 있습니다. Oracle의 eMudhra 안내와 Red Hat 보안 공지에 배경과 조건이 설명되어 있습니다.

이 인증서 문제의 주요 영향은 통신 상대 사칭과 데이터의 기밀성·무결성 훼손입니다. 공격자가 통신 경로를 가로채거나 연결을 조작할 수 있는 조건이 필요합니다. Java가 설치되어 있다는 사실만으로 원격 명령 실행이나 침해가 확인되는 것은 아닙니다.

운영에서는 다음 대상을 먼저 점검하는 편이 좋습니다. 아래 우선순위는 공식 공지의 공격 조건을 운영 환경에 적용한 판단입니다.

대상우선 확인할 이유점검 지점
외부 API·HTTPS에 접속하는 Java 서비스신뢰하지 말아야 할 인증서 체인을 받아들일 가능성실행 JVM, truststore, 외부 접속 경로
CI 서버·에이전트, 아티팩트 다운로드 작업외부 파일과 배포 경로에 접근컨트롤러·에이전트별 Java, 서명 검증
업무 제품의 내장 JavaOS 기본 Java와 다른 패치 경로 사용제품 보안 공지, 번들 JRE 경로
개발 PC·컨테이너ZIP 설치본·이미지 안의 Java가 목록에서 빠지기 쉬움IDE 설정, 이미지, 중지된 작업

인터넷에서 접속할 수 없는 내부 서버도 외부 저장소나 API를 호출하면 검토 대상입니다. 정적 파일만 서비스하는 프록시나 웹 서버의 인증서 갱신만으로 Java 클라이언트의 신뢰 저장소가 바뀌지는 않습니다.

영향 버전과 수정 버전을 읽는 방법

다음은 공지가 영향 대상으로 명시한 버전입니다. 설치할 수정 버전 목록이 아닙니다. 더 오래된 버전도 영향을 받을 수 있으며, 배포판의 백포트와 인증서 저장소 상태를 함께 확인해야 합니다.

계열OpenJDK 10월 21일 공지의 영향 버전Oracle 10월 24일 공지의 영향 버전
88u504 및 이전8u511-b32
1111.0.32.1 및 이전11.0.33.0.2
1717.0.21 및 이전17.0.21.0.2
2121.0.13 및 이전21.0.13.0.2
2525.0.5 및 이전25.0.5.0.2
2727.0.1 및 이전27.0.1.0.2

두 열은 서로 다른 배포·공개 시점의 표기입니다. OpenJDK 8의 업데이트 번호를 Oracle JDK 8에 그대로 대응시키지 않습니다. Oracle의 10월 21일 공지도 별도로 확인하면 분기 버전 이후 추가 업데이트가 나온 흐름을 볼 수 있습니다.

독립 설치한 OpenJDK는 배포사 릴리스 노트에 CVE-2026-114820 또는 JDK-8395690 수정이 포함됐는지 확인합니다. OpenJDK의 통합 대응 안내가 제시한 기준입니다. 단순히 “21.0.13 이상”, “10월 최신판”이라는 표현만으로 완료 처리하지 마세요. OS 패키지는 해당 배포판의 보안 공지와 패키지 릴리스를 비교하고, 제품 내장 Java는 제품 공급사의 지원 업데이트를 확인합니다.

Windows에서 Java 설치 위치 찾기

기본 Java와 실제 실행 프로세스

PowerShell에서 다음 명령으로 현재 계정의 기본 Java를 확인합니다. java를 찾지 못하면 뒤의 버전 명령은 건너뛰고 설치 폴더와 서비스 설정을 조사합니다.

Get-Command java -All -ErrorAction SilentlyContinue |
    Select-Object Source
where.exe java
$env:JAVA_HOME
java -XshowSettings:properties -version 2>&1

java.home, java.vendor, java.runtime.version을 기록합니다. JAVA_HOME은 환경 변수이고, 현재 서비스가 실제 사용하는 Java라는 보장은 없습니다. Windows Update와 Windows 인증서 저장소 업데이트만으로 독립 JDK의 cacerts까지 갱신됐다고 판단하지 않습니다.

관리자 PowerShell에서는 실행 중인 Java 프로세스와 관련 서비스를 살펴봅니다.

Get-CimInstance Win32_Process |
    Where-Object { $_.Name -in @('java.exe', 'javaw.exe') } |
    Select-Object ProcessId, Name, ExecutablePath, CommandLine

Get-CimInstance Win32_Service |
    Where-Object { $_.PathName -match 'java|tomcat|jenkins|elastic' } |
    Select-Object Name, State, ProcessId, PathName

프로세스의 ExecutablePath가 기본 Java 경로와 다르면 별도 항목으로 관리합니다. 서비스 필터는 후보를 좁히는 예시입니다. 이름에 Java가 없는 서비스 래퍼도 있으므로 업무 서비스 목록과 대조하고, 래퍼의 JVM 경로·jvm.dll 설정도 확인합니다. 속성 의미는 Microsoft의 Win32_Process와 Win32_Service 문서를 참고했습니다.

ZIP 설치본과 제품 내장 JRE

아래 검색 경로는 예시입니다. 실제 제품 폴더로 범위를 좁혀 실행하고, 사용자 프로필의 개발 도구·예약 작업·IDE의 런타임 설정도 확인합니다.

$roots = @('C:\Program Files', 'C:\Program Files (x86)', 'C:\apps')
Get-ChildItem -Path $roots -Filter java.exe -File -Recurse `
    -ErrorAction SilentlyContinue |
    Select-Object FullName

파일 검색만으로 JVM을 내장한 모든 프로그램을 찾을 수는 없습니다. 제품이 jvm.dll을 직접 불러오거나 별도 런타임 디렉터리를 쓰는 경우에는 제품 설정을 확인해야 합니다. 명령줄에 비밀번호나 토큰이 포함될 수 있으므로 결과를 공유할 때에는 민감한 값을 가립니다.

Linux에서 설치 패키지와 서비스 JVM 찾기

기본 실행 경로와 패키지 목록

먼저 다음을 확인합니다. command -v java에 결과가 없더라도 /opt 등의 수동 설치본이나 컨테이너가 없는 것은 아닙니다.

command -v java

Java가 검색되면 실제 링크 대상과 버전 정보를 확인합니다.

readlink -f "$(command -v java)"
java -XshowSettings:properties -version 2>&1

RHEL·Rocky Linux 계열은 RPM 패키지의 전체 버전과 릴리스를 기록합니다.

rpm -qa 'java*openjdk*' 'ca-certificates*'

Ubuntu·Debian 계열은 패키지 목록과 대체 실행 경로를 확인합니다.

dpkg-query -W -f='${binary:Package}\t${Version}\n' \
  'openjdk-*' ca-certificates ca-certificates-java
update-alternatives --list java

패키지 검색 결과에 미설치 항목이 섞이거나 일부 이름이 없다는 오류가 나면 실제 설치 상태를 추가 확인합니다. 백포트는 기존 버전에 보안 수정을 반영하는 방식입니다. 따라서 상위 버전 문자열만 보고 취약하다고 확정하지 않고, 배포판 보안 공지의 수정 패키지와 비교합니다. Red Hat의 CVE 설명에도 백포트와 배포 형태에 따른 차이가 안내되어 있습니다.

실행 중인 서비스와 수동 설치본

아래 myapp.service와 PID 1234는 실제 대상 값으로 바꿉니다. Environment와 프로세스 명령줄에는 민감한 설정이 포함될 수 있습니다.

pgrep -a java
systemctl show myapp.service -p MainPID -p ExecStart -p Environment
sudo readlink /proc/1234/exe
sudo cat /proc/1234/cmdline | tr '\0' '\n'

업데이트 뒤에도 /proc/1234/exe가 이전 경로나 (deleted) 파일을 가리키면 기존 프로세스가 남아 있는지 확인합니다. 서비스 래퍼가 JVM을 직접 불러오면 실행 파일 이름만으로 구분하기 어렵습니다. 이때에는 제품 설정과 프로세스의 libjvm.so 로딩 경로를 확인합니다.

sudo find /opt /usr/local /srv -type f \
  \( -name java -o -name libjvm.so \) -print 2>/dev/null

검색 범위 밖의 경로, 마운트된 볼륨, 중지된 컨테이너는 별도 점검이 필요합니다. 찾은 Java마다 설치 경로·공급사·전체 버전·사용 서비스·신뢰 저장소를 한 행씩 기록하면 누락을 줄일 수 있어요.

인증서 저장소를 확인하는 방법

Java가 신뢰하는 CA 목록을 저장하는 곳을 truststore라고 합니다. 기본값은 보통 JDK 11 이상에서 lib/security/cacerts, JDK 8에서 jre/lib/security/cacerts입니다. 애플리케이션이 -Djavax.net.ssl.trustStore=..., jssecacerts 또는 자체 TrustManager를 사용하면 실제 선택이 달라집니다. JSSE 공식 문서의 저장소 선택 규칙을 함께 확인합니다.

Oracle 안내는 위험한 루트의 잔존 여부를 확인하는 CheckCerts.java를 제공합니다. 공식 주소에서 소스를 내려받아 내용을 검토한 뒤, 점검 대상 JDK로 컴파일·실행합니다. 다음 예시는 JDK 8 이상에서 사용할 수 있으며, 현재 폴더에 소스 파일이 있어야 합니다.

Linux에서는 /opt/jdk를 대상 JDK의 실제 경로로 바꿉니다.

/opt/jdk/bin/javac CheckCerts.java
/opt/jdk/bin/java -cp . CheckCerts

Windows에서는 C:\apps\jdk를 대상 경로로 바꿉니다.

& 'C:\apps\jdk\bin\javac.exe' .\CheckCerts.java
& 'C:\apps\jdk\bin\java.exe' -cp . CheckCerts

BAD ROOT:가 나오면 검사한 기본 신뢰 목록에 관련 루트가 남아 있다는 뜻이며, 프로그램은 종료 코드 1을 반환합니다. No bad root certificates found는 그 검사 범위에서 관련 루트를 찾지 못했다는 뜻입니다. 중간 인증서 차단 패치의 존재나 모든 CVE 해결 여부를 판정하는 도구는 아닙니다.

소스는 유출된 중간 인증서와 연결된 루트 두 개 외에 다른 eMudhra 루트 두 개도 검사합니다. 별도 Ubuntu 24.04 컨테이너에서 CA 패키지를 설치하고 Java 저장소를 재생성한 전후 모두 emSign Root CA - G1이 BAD ROOT로 표시되는 것을 확인했습니다. 이 출력만으로 특정 CVE가 미조치되었다고 확정하지 않고, 공급사의 제거 범위와 실제 저장소를 대조해야 합니다.

이 프로그램은 새 JVM의 기본 TrustManager를 검사합니다. 서비스의 별도 truststore나 자체 인증서 검증 로직, 이미 실행 중인 JVM의 상태까지 자동으로 검사하지는 않습니다. JRE만 설치되어 javac가 없다면 호환되는 JDK로 컴파일한 뒤 대상 JRE로 실행하거나 공급사 점검 도구를 사용합니다.

Windows 조치: 같은 Java 계열의 수정 빌드 적용

설치한 공급사와 제품이 지원하는 Java 계열을 유지하면서 보안 수정 빌드를 적용합니다. Java 8에서 21로 옮기는 작업은 호환성 검토가 필요한 별도 변경입니다. 제품 내장 JRE를 임의로 덮어쓰기보다 제품 공급사의 패치나 지원 절차를 따릅니다.

WinGet으로 관리하는 Temurin 21의 예시는 다음과 같습니다. 먼저 표시되는 버전의 릴리스 노트가 이번 인증서 수정까지 포함하는지 확인한 뒤 업그레이드합니다. 다른 공급사·계열의 Java에는 해당 패키지 ID를 사용해야 합니다.

winget list --id EclipseAdoptium.Temurin.21.JDK --exact
winget show --id EclipseAdoptium.Temurin.21.JDK --exact
winget upgrade --id EclipseAdoptium.Temurin.21.JDK --exact

설치 방식은 Adoptium 설치 안내와 릴리스 목록을 참고합니다. OS·CPU 아키텍처별 배포 시점이 다를 수 있으며, WinGet에 업데이트가 없다는 결과가 안전하다는 뜻은 아닙니다. MSI·ZIP 설치본도 공식 수정 빌드를 확인해 각각 교체합니다.

변경 전에는 서비스 설정, JVM 옵션, 사용자 정의 CA와 truststore를 보관합니다. 변경 후에는 서비스가 새 경로를 쓰도록 설정하고 승인된 작업 시간에 재시작합니다. 새 PowerShell에서 기본 Java와 실제 서비스 프로세스의 경로·버전을 다시 대조합니다.

Linux 조치: OpenJDK와 CA 패키지를 함께 확인

RHEL·Rocky Linux 계열

다음 명령은 저장소 메타데이터와 보안 공지 정보를 확인합니다. Rocky Linux의 수정 패키지는 Rocky 저장소와 해당 공지를 기준으로 판단하며, RHEL의 RHSA 패키지 번호를 그대로 대입하지 않습니다.

sudo dnf makecache --refresh
dnf updateinfo list --security
dnf list --installed 'java*openjdk*' ca-certificates

아래는 이미 설치된 Java 21 패키지를 갱신하는 예시입니다. 실제 설치한 계열과 패키지명으로 바꾸고, 트랜잭션에 표시되는 변경 내용을 검토합니다. 여러 Java 계열이 설치되어 있으면 각각 갱신합니다.

sudo dnf upgrade --refresh ca-certificates 'java-21-openjdk*'

Red Hat은 일반 RHEL OpenJDK RPM의 기본 인증서 저장소가 OS의 ca-certificates를 사용한다고 설명합니다. 반면 Windows·Linux용 portable 빌드는 자체 저장소를 포함합니다. Red Hat CVE-2026-91403과 CA 저장소 공지를 구분해서 확인하세요. CA 갱신만으로 분기 업데이트의 다른 CVE까지 해결되는 것은 아닙니다.

Ubuntu·Debian 계열

다음은 이미 설치한 OpenJDK 21 실행 패키지의 갱신 예시입니다. JDK나 다른 계열을 사용한다면 설치 목록에서 확인한 패키지명으로 바꿉니다. 배포판이 지원하는 저장소와 수정 버전을 확인한 뒤 적용합니다.

sudo apt update
apt-cache policy openjdk-21-jre-headless ca-certificates ca-certificates-java
sudo apt install --only-upgrade \
  openjdk-21-jre-headless ca-certificates ca-certificates-java

이번 이슈에는 추가 확인이 필요합니다. Ubuntu와 OpenJDK 공식 안내는 ca-certificates-java의 동기화 문제 때문에 패키지 업데이트만으로 Java 저장소의 관련 인증서가 제거되지 않을 수 있다고 설명합니다. OS 패키지가 관리하는 Java 저장소를 재생성하는 우회 절차가 제시되어 있습니다. Ubuntu 대응 안내를 적용 전에 다시 확인합니다.

다음 절차는 /etc/ssl/certs/java/cacerts가 실제 대상인 OS 패키지 설치에만 적용합니다. 기존 Java 저장소에만 넣어 둔 사내 CA는 재생성 뒤 사라질 수 있습니다. 먼저 저장소와 사용자 정의 CA를 보관하고 복원·재등록 방법을 확인합니다. 백업 명령이 성공한 것을 확인한 뒤 다음 블록을 실행합니다.

backup_dir="/root/java-ca-backup-$(date +%Y%m%d-%H%M%S)"
sudo install -d -m 700 "$backup_dir"
sudo cp -aL /etc/ssl/certs/java/cacerts "$backup_dir/cacerts"

이어서 기존 OS Java 저장소를 제거하고 재생성합니다.

sudo rm -f /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh

재생성 성공과 필요한 사내 CA의 존재를 확인한 뒤 서비스를 재시작합니다. ZIP·tar로 따로 설치한 JDK나 애플리케이션 전용 truststore에는 이 경로를 그대로 적용하지 않습니다.

바로 업데이트할 수 없다면

독립 JDK의 수정 빌드가 아직 없다면 관련 루트 CA 제거 또는 인증서 폐지 확인이 공식 임시 대응입니다. OpenJDK 대응 안내와 Oracle 절차를 해당 배포판·저장소에 맞춰 적용합니다. 별칭은 배포판마다 다를 수 있으므로 다른 JDK의 keytool로 임의 삭제하지 않습니다.

루트 제거는 정상적인 상대 서비스의 인증서 체인에도 영향을 줄 수 있어요. 실제 저장소를 먼저 백업하고, 공급사가 지정한 별칭·인증서를 확인한 뒤 변경합니다. 폐지 확인은 CRL·OCSP 접근성과 실패 처리, 애플리케이션의 검증 방식까지 검토해야 하므로 옵션만 추가하고 완료 처리하지 않습니다.

TLS 인증서 검증이나 호스트 이름 검증을 끄는 방식은 조치가 아닙니다. 패치 뒤 접속 오류가 생기면 상대 서버의 인증서 체인과 정상 신뢰 경로를 확인하고, 제거된 루트를 근거 없이 다시 넣지 않습니다.

컨테이너와 재시작 후 완료 기준

호스트 Java를 갱신해도 컨테이너 이미지 안의 Java와 CA 저장소는 그대로일 수 있습니다. my-java-app은 실제 컨테이너 이름으로 바꿉니다. java가 PATH에 없는 제품은 Dockerfile과 제품 문서에서 실제 경로를 확인합니다.

docker inspect --format '{{.Config.Image}} {{.Image}}' my-java-app
docker exec my-java-app java -XshowSettings:properties -version

수정된 베이스 이미지와 패키지로 이미지를 다시 빌드하고 배포합니다. 이미지 안에 CA 파일을 따로 복사했거나 기존 truststore를 볼륨으로 마운트했다면 그 파일도 확인해야 합니다. 실행 중인 컨테이너 안에서만 수동 수정하면 다음 배포 때 변경이 사라질 수 있습니다.

완료 여부는 설치 프로그램의 성공 화면보다 실제 서비스 상태로 확인합니다.

  • 관리 대상의 Java 경로·공급사·전체 버전과 사용 서비스가 기록되어 있습니다.
  • 분기 CVE 수정과 10월 인증서 추가 조치가 각각 공급사 공지에 따라 확인되었습니다.
  • 기본·사용자 정의 truststore와 컨테이너·내장 Java의 누락이 없습니다.
  • 재시작 후 실제 서비스 JVM이 수정된 설치 경로를 사용합니다.
  • 외부 API·저장소·DB TLS 연결과 업무 기능을 확인했습니다.
  • 점검 시각, 수정 패키지·이미지 식별자, 재시작 결과와 재점검 기록을 남겼습니다.

실행 중인 HotSpot JVM은 대상과 호환되는 JDK의 jcmd로 VM.version과 VM.system_properties를 확인할 수도 있습니다. 해당 프로세스와 같은 실행 계정 및 필요한 권한을 사용하며, 컨테이너는 네임스페이스 안에서 확인합니다. jcmd 공식 문서에 실행 조건이 나와 있습니다.

먼저 서비스가 실제로 쓰는 Java 한 개를 찾아 공급사와 전체 버전, truststore를 기록하세요. 그 항목의 조치·재시작·업무 연결 확인을 마친 뒤 같은 방식으로 나머지 설치본을 점검하면 됩니다.