refactor(WEB): Server Action 공통화 및 보안 강화

- executeServerAction 공통 유틸 도입으로 actions.ts 대폭 간소화 (50+개 파일)
- sanitize 유틸 추가 (XSS 방지)
- middleware CSP 헤더 추가 및 Open Redirect 방지
- 프록시 라우트 로깅 개발환경 한정으로 변경
- 프로덕션 불필요 console.log 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-09 16:14:06 +09:00
parent d014227e9c
commit 55e0791e16
85 changed files with 7211 additions and 17638 deletions

View File

@@ -48,6 +48,28 @@ export default function FileUpload({
return;
}
// 위험한 확장자 차단
const dangerousExtensions = ['.exe', '.bat', '.cmd', '.sh', '.js', '.jsx', '.ts', '.tsx', '.mjs', '.jar', '.app', '.scr', '.vbs', '.ps1', '.htm', '.html', '.svg', '.swf'];
const fileExtension = '.' + (file.name.split('.').pop()?.toLowerCase() || '');
if (dangerousExtensions.includes(fileExtension)) {
setError('보안상 허용되지 않는 파일 형식입니다.');
return;
}
// accept가 지정된 경우 확장자 검증
if (accept !== '*/*') {
const allowedExtensions = accept.split(',').map(ext => ext.trim().toLowerCase());
const isAllowed = allowedExtensions.some(ext => {
if (ext.startsWith('.')) return fileExtension === ext;
if (ext.endsWith('/*')) return file.type.startsWith(ext.replace('/*', '/'));
return file.type === ext;
});
if (!isAllowed) {
setError(`허용되지 않은 파일 형식입니다. (${accept})`);
return;
}
}
// 파일 크기 검증
const fileSizeMB = file.size / (1024 * 1024);
if (fileSizeMB > maxSize) {