From 812cabd405b792179b80bd55aee79847caabe0e1 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Fri, 17 Jul 2026 14:47:49 +0900 Subject: [PATCH] =?UTF-8?q?fix(server):=20=EA=B6=8C=EC=9E=A5=20JDK=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=A6=B4=EB=A6=AC=EC=8A=A4=EB=AA=85=20XSS?= =?UTF-8?q?=20escape=20+=20=EB=AC=B8=EC=84=9C=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 편집기 "자세히 보기" 에서 Adoptium release_name 을 escape 없이 innerHTML 에 넣던 부분을 escHtml 처리(외부 API 값 → 관리 페이지 XSS 방지). - docs/installer.md 의 JDK 탐색 순서/자동 설치 경로를 실제 코드(C:\Program Files\Java → 환경변수 → .mc_custom\jdk, 불일치 경고)와 일치하도록 갱신. exe 산출물은 변경 없음(사이트/문서 수정) → 재빌드/재릴리스 없음. Co-Authored-By: Claude Opus 4.7 --- docs/installer.md | 8 ++++---- views/op/editor.ejs | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/installer.md b/docs/installer.md index 12e13e4..dc27186 100644 --- a/docs/installer.md +++ b/docs/installer.md @@ -28,10 +28,10 @@ ### 3-2. JDK 확인 -- 각 음악퀴즈(pack)는 사이트 편집기에서 **권장 JDK 버전**(예: Java 25)을 지정합니다. 설치기는 이 권장 버전을 기준으로 동작합니다. -- 탐색 순서: **① 권장 JDK 자동 설치 위치(`%APPDATA%\jdk\temurin-<권장>`) 를 가장 먼저** 확인 → 없으면 **② 컴퓨터의 JDK(`JAVA_HOME` / `JDK_HOME` / `C:\Program Files\Java`)** 를 확인. -- 최신 마인크래프트 서버는 특정 자바 버전 이상을 요구합니다(예: 서버 번들러 class file 69.0 = Java 25). 그보다 낮은 자바는 있어도 `UnsupportedClassVersionError` 로 서버가 뜨지 않으므로, 자동 탐색은 **권장 버전 미만을 "없음"으로 처리**해 자동 설치로 유도합니다. 직접 선택/입력한 경로도 "다음" 에서 버전을 검증해 미만이면 진행을 막습니다. -- **자동 설치** 버튼을 누르면 Adoptium Temurin(권장 버전) Windows x64 zip 을 받아 `%APPDATA%\jdk\temurin-<권장>\` 에 풀어 사용합니다. +- 각 음악퀴즈(pack)는 사이트 편집기에서 **권장 JDK 버전**(예: Java 25)을 지정합니다. 편집기 목록은 Adoptium(Temurin)에서 실제 배포되는 버전을 불러오며, "자세히 보기"로 비-LTS·스냅샷까지 확인할 수 있습니다. 설치기는 이 권장 버전을 기준으로 동작합니다. +- 탐색 순서: **① 기본 자바 설치 위치 `C:\Program Files\Java` → ② 환경변수(`JAVA_HOME` / `JDK_HOME`) → ③ 설치기 자동 설치 위치(`%APPDATA%\.mc_custom\jdk`, 구버전 `%APPDATA%\jdk` 호환)** 순으로 훑어, **권장 버전과 정확히 일치하는 JDK 를 우선 선택**합니다. +- 권장 버전이 없으면 컴퓨터에 있는 **다른 JDK(가장 높은 버전)** 를 대신 고르되, "권장 버전과 달라 서버가 정상 실행되지 않을 수 있다"는 **경고**를 함께 띄웁니다. 직접 선택/입력한 경로도 "다음" 에서 검증해, 권장과 다르면 경고 후 동의(확인) 시에만 진행합니다(무조건 차단이 아니라 경고+동의). +- **자동 설치** 버튼을 누르면 Adoptium Temurin(권장 버전) Windows x64 zip 을 받아 **`%APPDATA%\.mc_custom\jdk\temurin-<권장>\`** 에 풀어 사용합니다. (`.mc_custom` 안에 두므로 "음악퀴즈 파일제거" 도구로 한 번에 정리됩니다. `MC_CUSTOM_DIR` 로 폴더명을 바꾼 경우 그 폴더 아래 `jdk`.) - 설치 중 같은 버튼이 "설치 취소" 로 바뀌고, 누르면 다운로드를 즉시 중단하고 부분 파일을 정리합니다. - 서버 zip 의 `run.bat` 이 시스템 PATH 의 `java` 를 그대로 쓰면 낡은 자바로 실행돼 실패할 수 있어, 설치기가 준비/선택한 JDK 의 `java` 를 쓰도록 `run.bat` 을 자동으로 수정합니다(자동 설치 JDK 는 `%APPDATA%` 전개형 경로라 한글 사용자명에도 안전). diff --git a/views/op/editor.ejs b/views/op/editor.ejs index 1fedae0..ac691b0 100644 --- a/views/op/editor.ejs +++ b/views/op/editor.ejs @@ -175,16 +175,26 @@ sel.value = String(current) } + function escHtml(s) { + return String(s).replace(/[&<>"']/g, function (c) { + return c === '&' ? '&' : c === '<' ? '<' : c === '>' ? '>' : c === '"' ? '"' : ''' + }) + } + function detailRow(label, names) { + return '
' + escHtml(label) + ': ' + + names.slice(0, 6).map(escHtml).join(', ') + '
' + } function loadDetails(major) { details.hidden = false details.textContent = JDK.detailsLoading fetch('/op/jdk-versions/' + major) .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json() }) .then(function (d) { + // release_name 은 외부 API 값이라 반드시 escape 후 삽입(관리 페이지 XSS 방지). var html = '' - if (d.ga && d.ga.length) html += '
' + JDK.detailsGa + ': ' + d.ga.slice(0, 6).join(', ') + '
' - if (d.ea && d.ea.length) html += '
' + JDK.detailsEa + ': ' + d.ea.slice(0, 6).join(', ') + '
' - details.innerHTML = html || JDK.detailsNone + if (d.ga && d.ga.length) html += detailRow(JDK.detailsGa, d.ga) + if (d.ea && d.ea.length) html += detailRow(JDK.detailsEa, d.ea) + details.innerHTML = html || escHtml(JDK.detailsNone) }) .catch(function () { details.textContent = JDK.detailsNone }) }