fix(security): 스케줄러 Shell/Artisan 명령 실행 하드닝

미출시 예약 작업 기능에서 스케줄 권한만 위임받은 계정이 Shell/Artisan
명령으로 임의 코드를 실행할 수 있던 문제를 선제적으로 차단(KVE-2026-1567).
Shell 은 기본 차단 + 실행 파일 화이트리스트 + 셸 미경유 인자배열 실행,
Artisan 은 차단목록. 저장 시점(FormRequest)과 실행 시점(Service) 이중 검증.

아울러 공개 release 보다 앞선 미출시 버전들의 CHANGELOG 출시 날짜를
2026-07-14 로 통일.
This commit is contained in:
HeuJung
2026-07-14 14:48:33 +09:00
parent 4c73db2e91
commit ce8e55b390
23 changed files with 957 additions and 25 deletions
+2
View File
@@ -29,6 +29,8 @@ return [
'shell_command_failed' => 'Shell command execution failed.',
'http_request_failed' => 'HTTP request failed with status: :status',
'url_not_public' => 'Internal network addresses (private IPs, localhost, etc.) cannot be called. To call an address inside your network, enable "Allow internal network addresses" under Settings > Security.',
'shell_not_allowed' => 'This shell command is not allowed. Only executables registered on the server can be run as a schedule.',
'artisan_not_allowed' => 'This Artisan command cannot be run as a schedule for security reasons.',
// Task types
'type' => [
+6
View File
@@ -510,6 +510,12 @@ return [
'internal_not_allowed' => 'Internal network addresses (private IPs, localhost, etc.) are not allowed. Enter a publicly reachable address.',
],
// Schedule command (shell/Artisan) validation messages — these run on the server
'schedule_command' => [
'shell_not_allowed' => 'This shell command is not allowed. Only executables registered on the server may be used, and special characters such as pipes (|) or semicolons (;) are not permitted.',
'artisan_denied' => 'This Artisan command cannot be run as a schedule for security reasons.',
],
// Component existence validation messages
'component' => [
'template_id_required' => 'template_id is required for component validation.',
+2
View File
@@ -29,6 +29,8 @@ return [
'shell_command_failed' => '쉘 명령 실행에 실패했습니다.',
'http_request_failed' => 'HTTP 요청 실패 (상태: :status)',
'url_not_public' => '내부 네트워크 주소(사설 IP·localhost 등)는 호출할 수 없습니다. 사내 주소를 호출해야 한다면 환경설정 > 보안에서 "내부 네트워크 주소 호출 허용"을 켜주세요.',
'shell_not_allowed' => '허용되지 않은 쉘 명령입니다. 서버에 등록된 실행 파일만 스케줄로 실행할 수 있습니다.',
'artisan_not_allowed' => '이 Artisan 명령은 보안상 스케줄로 실행할 수 없습니다.',
// 작업 유형
'type' => [
+6
View File
@@ -509,6 +509,12 @@ return [
'internal_not_allowed' => '내부 네트워크 주소(사설 IP·localhost 등)는 사용할 수 없습니다. 외부에서 접속 가능한 주소를 입력해 주세요.',
],
// 서버에서 실행되는 스케줄 command(쉘·Artisan) 검증 메시지
'schedule_command' => [
'shell_not_allowed' => '허용되지 않은 쉘 명령입니다. 서버에 등록된 실행 파일만 사용할 수 있으며, 파이프(|)·세미콜론(;) 등 특수문자는 쓸 수 없습니다.',
'artisan_denied' => '이 Artisan 명령은 보안상 스케줄로 실행할 수 없습니다.',
],
// 컴포넌트 존재 여부 검증 메시지
'component' => [
'template_id_required' => '컴포넌트 검증을 위해서는 template_id가 필요합니다.',