fix: [approval] 결재선 요약 카드 XSS 방어 추가

- updateApprovalLineSummary의 innerHTML에 escapeHtml 함수 적용
- user_name, position, stepLabel 출력 시 HTML 이스케이프 처리
This commit is contained in:
김보곤
2026-03-04 14:21:07 +09:00
parent c314715008
commit 18c44f3a1c
2 changed files with 20 additions and 6 deletions

View File

@@ -172,6 +172,13 @@ class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm fon
const formBodyTemplates = @json($forms->pluck('body_template', 'id'));
const linesData = @json($lines);
function escapeHtml(str) {
if (!str) return '';
const div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
function toggleEditor() {
const useEditor = document.getElementById('useEditor').checked;
const textarea = document.getElementById('body');
@@ -274,9 +281,9 @@ function updateApprovalLineSummary() {
cards.push(
'<div class="step-card text-center px-3 py-2 rounded-lg border ' + bg + '" data-index="' + i + '" style="min-width: 72px;">' +
'<div class="text-xs font-medium ' + labelColor + '">' + stepLabel + '</div>' +
(position ? '<div class="text-xs text-gray-400 mt-0.5">' + position + '</div>' : '') +
'<div class="text-sm font-semibold text-gray-800 mt-0.5">' + s.user_name + '</div>' +
'<div class="text-xs font-medium ' + labelColor + '">' + escapeHtml(stepLabel) + '</div>' +
(position ? '<div class="text-xs text-gray-400 mt-0.5">' + escapeHtml(position) + '</div>' : '') +
'<div class="text-sm font-semibold text-gray-800 mt-0.5">' + escapeHtml(s.user_name) + '</div>' +
'</div>'
);
});

View File

@@ -206,6 +206,13 @@ class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm fon
const formBodyTemplates = @json($forms->pluck('body_template', 'id'));
const linesData = @json($lines);
function escapeHtml(str) {
if (!str) return '';
const div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
function toggleEditor() {
const useEditor = document.getElementById('useEditor').checked;
const textarea = document.getElementById('body');
@@ -308,9 +315,9 @@ function updateApprovalLineSummary() {
cards.push(
'<div class="step-card text-center px-3 py-2 rounded-lg border ' + bg + '" data-index="' + i + '" style="min-width: 72px;">' +
'<div class="text-xs font-medium ' + labelColor + '">' + stepLabel + '</div>' +
(position ? '<div class="text-xs text-gray-400 mt-0.5">' + position + '</div>' : '') +
'<div class="text-sm font-semibold text-gray-800 mt-0.5">' + s.user_name + '</div>' +
'<div class="text-xs font-medium ' + labelColor + '">' + escapeHtml(stepLabel) + '</div>' +
(position ? '<div class="text-xs text-gray-400 mt-0.5">' + escapeHtml(position) + '</div>' : '') +
'<div class="text-sm font-semibold text-gray-800 mt-0.5">' + escapeHtml(s.user_name) + '</div>' +
'</div>'
);
});