fix: 보안 취약점 수정 및 XSS 방지 적용

## 백엔드 보안 수정
- 하드코딩된 비밀번호 및 JWT 시크릿 폴백 제거
- SQL Injection 방지를 위한 화이트리스트 검증 추가
- 인증 미적용 API 라우트에 requireAuth 미들웨어 적용
- CSRF 보호 미들웨어 구현 (csrf.js)
- 파일 업로드 보안 유틸리티 추가 (fileUploadSecurity.js)
- 비밀번호 정책 검증 유틸리티 추가 (passwordValidator.js)

## 프론트엔드 XSS 방지
- api-base.js에 전역 escapeHtml() 함수 추가
- 17개 주요 JS 파일에 escapeHtml 적용:
  - tbm.js, daily-patrol.js, daily-work-report.js
  - task-management.js, workplace-status.js
  - equipment-detail.js, equipment-management.js
  - issue-detail.js, issue-report.js
  - vacation-common.js, worker-management.js
  - safety-report-list.js, nonconformity-list.js
  - project-management.js, workplace-management.js

## 정리
- 백업 폴더 및 빈 파일 삭제
- SECURITY_GUIDE.md 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-02-05 06:33:10 +09:00
parent 7c38c555f5
commit 36f110c90a
97 changed files with 2523 additions and 24267 deletions

View File

@@ -1,21 +1,38 @@
// 작업장 관리 페이지 JavaScript
//
// 참고: 이 파일은 점진적 마이그레이션 중입니다.
// 새로운 모듈 시스템: /js/workplace-management/
// - state.js: 전역 상태 관리
// - utils.js: 유틸리티 함수
// - api.js: API 클라이언트
// - index.js: 메인 컨트롤러
// 전역 변수
let categories = [];
let workplaces = [];
let currentCategoryId = '';
// 전역 변수 (모듈 시스템이 없을 때만 사용)
let categories = window.WorkplaceState?.categories || [];
let workplaces = window.WorkplaceState?.workplaces || [];
let currentCategoryId = window.WorkplaceState?.currentCategoryId || '';
let currentEditingCategory = null;
let currentEditingWorkplace = null;
// 페이지 초기화
// 페이지 초기화 (모듈 시스템이 없을 때만)
document.addEventListener('DOMContentLoaded', function() {
console.log('🏗️ 작업장 관리 페이지 초기화 시작');
// 모듈 시스템이 이미 로드되어 있으면 초기화 건너뜀
if (window.WorkplaceController) {
console.log('[workplace-management.js] 모듈 시스템 감지 - 기존 초기화 건너뜀');
return;
}
console.log('🏗️ 작업장 관리 페이지 초기화 시작 (레거시)');
loadAllData();
});
// 모든 데이터 로드
async function loadAllData() {
// 모듈 시스템이 있으면 위임
if (window.WorkplaceController) {
return window.WorkplaceController.loadAllData();
}
try {
await Promise.all([
loadCategories(),
@@ -35,6 +52,13 @@ async function loadAllData() {
// 카테고리 목록 로드
async function loadCategories() {
// 모듈 시스템이 있으면 위임
if (window.WorkplaceAPI) {
const result = await window.WorkplaceAPI.loadCategories();
categories = window.WorkplaceState?.categories || result;
return result;
}
try {
const response = await window.apiCall('/workplaces/categories', 'GET');
@@ -934,27 +958,30 @@ function showToast(message, type = 'info') {
}
// 전역 함수 및 변수로 노출 (다른 모듈에서 접근 가능하도록)
// getter/setter를 사용하여 항상 최신 값을 반환
Object.defineProperty(window, 'categories', {
get: function() {
return categories;
}
});
// 모듈 시스템이 이미 정의했으면 건너뜀
if (!window.WorkplaceState) {
// getter/setter를 사용하여 항상 최신 값을 반환
Object.defineProperty(window, 'categories', {
get: function() {
return categories;
}
});
Object.defineProperty(window, 'workplaces', {
get: function() {
return workplaces;
}
});
Object.defineProperty(window, 'workplaces', {
get: function() {
return workplaces;
}
});
Object.defineProperty(window, 'currentCategoryId', {
get: function() {
return currentCategoryId;
},
set: function(value) {
currentCategoryId = value;
}
});
Object.defineProperty(window, 'currentCategoryId', {
get: function() {
return currentCategoryId;
},
set: function(value) {
currentCategoryId = value;
}
});
}
// ==================== 작업장 지도 관리 ====================