fix(server): 권장 JDK 상세 릴리스명 XSS escape + 문서 갱신

- 편집기 "자세히 보기" 에서 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 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 14:47:49 +09:00
parent fefa2dcdd2
commit 812cabd405
2 changed files with 17 additions and 7 deletions

View File

@@ -28,10 +28,10 @@
### 3-2. JDK 확인 ### 3-2. JDK 확인
- 각 음악퀴즈(pack)는 사이트 편집기에서 **권장 JDK 버전**(예: Java 25)을 지정합니다. 설치기는 이 권장 버전을 기준으로 동작합니다. - 각 음악퀴즈(pack)는 사이트 편집기에서 **권장 JDK 버전**(예: Java 25)을 지정합니다. 편집기 목록은 Adoptium(Temurin)에서 실제 배포되는 버전을 불러오며, "자세히 보기"로 비-LTS·스냅샷까지 확인할 수 있습니다. 설치기는 이 권장 버전을 기준으로 동작합니다.
- 탐색 순서: **권장 JDK 설치 위치(`%APPDATA%\jdk\temurin-<권장>`) 를 가장 먼저** 확인 → 없으면 **② 컴퓨터의 JDK(`JAVA_HOME` / `JDK_HOME` / `C:\Program Files\Java`)** 를 확인. - 탐색 순서: **기본 설치 위치 `C:\Program Files\Java` → ② 환경변수(`JAVA_HOME` / `JDK_HOME`) → ③ 설치기 자동 설치 위치(`%APPDATA%\.mc_custom\jdk`, 구버전 `%APPDATA%\jdk` 호환)** 순으로 훑어, **권장 버전과 정확히 일치하는 JDK 를 우선 선택**합니다.
- 최신 마인크래프트 서버는 특정 자바 버전 이상을 요구합니다(예: 서버 번들러 class file 69.0 = Java 25). 그보다 낮은 자바는 있어도 `UnsupportedClassVersionError` 로 서버가 뜨지 않으므로, 자동 탐색은 **권장 버전 미만을 "없음"으로 처리**해 자동 설치로 유도합니다. 직접 선택/입력한 경로도 "다음" 에서 버전을 검증해 미만이면 진행을 막습니다. - 권장 버전이 없으면 컴퓨터에 있는 **다른 JDK(가장 높은 버전)** 를 대신 고르되, "권장 버전과 달라 서버가 정상 실행되지 않을 수 있다"는 **경고**를 함께 띄웁니다. 직접 선택/입력한 경로도 "다음" 에서 검증해, 권장과 다르면 경고 후 동의(확인) 시에만 진행합니다(무조건 차단이 아니라 경고+동의).
- **자동 설치** 버튼을 누르면 Adoptium Temurin(권장 버전) Windows x64 zip 을 받아 `%APPDATA%\jdk\temurin-<권장>\` 에 풀어 사용합니다. - **자동 설치** 버튼을 누르면 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%` 전개형 경로라 한글 사용자명에도 안전). - 서버 zip 의 `run.bat` 이 시스템 PATH 의 `java` 를 그대로 쓰면 낡은 자바로 실행돼 실패할 수 있어, 설치기가 준비/선택한 JDK 의 `java` 를 쓰도록 `run.bat` 을 자동으로 수정합니다(자동 설치 JDK 는 `%APPDATA%` 전개형 경로라 한글 사용자명에도 안전).

View File

@@ -175,16 +175,26 @@
sel.value = String(current) sel.value = String(current)
} }
function escHtml(s) {
return String(s).replace(/[&<>"']/g, function (c) {
return c === '&' ? '&amp;' : c === '<' ? '&lt;' : c === '>' ? '&gt;' : c === '"' ? '&quot;' : '&#39;'
})
}
function detailRow(label, names) {
return '<div><strong>' + escHtml(label) + ':</strong> ' +
names.slice(0, 6).map(escHtml).join(', ') + '</div>'
}
function loadDetails(major) { function loadDetails(major) {
details.hidden = false details.hidden = false
details.textContent = JDK.detailsLoading details.textContent = JDK.detailsLoading
fetch('/op/jdk-versions/' + major) fetch('/op/jdk-versions/' + major)
.then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json() }) .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json() })
.then(function (d) { .then(function (d) {
// release_name 은 외부 API 값이라 반드시 escape 후 삽입(관리 페이지 XSS 방지).
var html = '' var html = ''
if (d.ga && d.ga.length) html += '<div><strong>' + JDK.detailsGa + ':</strong> ' + d.ga.slice(0, 6).join(', ') + '</div>' if (d.ga && d.ga.length) html += detailRow(JDK.detailsGa, d.ga)
if (d.ea && d.ea.length) html += '<div><strong>' + JDK.detailsEa + ':</strong> ' + d.ea.slice(0, 6).join(', ') + '</div>' if (d.ea && d.ea.length) html += detailRow(JDK.detailsEa, d.ea)
details.innerHTML = html || JDK.detailsNone details.innerHTML = html || escHtml(JDK.detailsNone)
}) })
.catch(function () { details.textContent = JDK.detailsNone }) .catch(function () { details.textContent = JDK.detailsNone })
} }