installer: escape agreement tab labels (XSS hardening)

RP installer already escapes k.tab; main installer was injecting it raw.
Add escapeHtml helper and apply to tab id/label so admin-supplied
agreement labels can't break the HTML.
This commit is contained in:
2026-05-20 10:29:06 +09:00
parent 38df72e4f6
commit c580a50fd4

View File

@@ -208,7 +208,7 @@ function renderAgreementWithKinds(KINDS) {
'<p class="formMessage">' + tt('agreement.intro') + '</p>' + '<p class="formMessage">' + tt('agreement.intro') + '</p>' +
'<div class="tabBar" id="agTabs">' + '<div class="tabBar" id="agTabs">' +
KINDS.map(function (k, i) { KINDS.map(function (k, i) {
return '<button type="button" class="tabBtn' + (i === 0 ? ' active' : '') + '" data-ag="' + k.id + '">' + k.tab + '</button>' return '<button type="button" class="tabBtn' + (i === 0 ? ' active' : '') + '" data-ag="' + escapeHtml(k.id) + '">' + escapeHtml(k.tab) + '</button>'
}).join('') + }).join('') +
'</div>' + '</div>' +
'<div class="agreementBody" id="agBody">' + tt('agreement.loading') + '</div>' + '<div class="agreementBody" id="agBody">' + tt('agreement.loading') + '</div>' +
@@ -960,6 +960,12 @@ function renderStep5() {
}) })
} }
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, function (c) {
return c === '&' ? '&amp;' : c === '<' ? '&lt;' : c === '>' ? '&gt;' : c === '"' ? '&quot;' : '&#39;'
})
}
// 시작 진입점: 사전을 먼저 받아서 정적 텍스트 갱신 후 첫 페이지 렌더. // 시작 진입점: 사전을 먼저 받아서 정적 텍스트 갱신 후 첫 페이지 렌더.
;(async function () { ;(async function () {
try { try {