
DX Security — Plugin Isolation 방어 v1.0.0 안내서
PHP 5.6+ · IIS / Apache / Nginx 완전 호환 코어 수정 없음 — 훅으로만 동작
목차
- Plugin Isolation이란 무엇인가
- DXCMS 코어의 현재 방어 수준
- PHP 환경의 현실적인 한계
- 이 플러그인의 역할
- 설치 방법
- 방어층 상세 설명
- 보안 로그 읽는 법
- 보안 강점 요약
- 개발자 API 가이드
1. Plugin Isolation이란 무엇인가
하나의 Plugin이 침해되거나 오작동하더라도 다른 Plugin, Core, 관리자 기능으로 피해가 확산되지 않도록 하는 보안 체계입니다.
문제 시나리오:
Plugin A (취약)
↓
공격자 코드 실행
↓
Plugin B 데이터 읽기
Core 설정 변경
관리자 권한 획득
다른 Plugin 파일 수정
↓
전체 시스템 침해
핵심 목표
Plugin A가 침해되었다.
↓ 그래도
Plugin B 데이터 접근 불가
Core 조작 불가
Admin 권한 획득 불가
다른 Plugin 파일 수정 불가
전체 시스템 피해 확산 차단
2. DXCMS 코어의 현재 방어 수준
| 항목 | 코어 구현 | 평가 |
|---|---|---|
| Plugin 디렉토리명 | preg_replace('/[^a-zA-Z0-9\-_]/') |
✅ |
| Plugin 로딩 경로 | DX_PLUGINS . '/' . $dir 고정 기반 |
✅ |
| Plugin 비활성화 | DB status=0 | ✅ |
| Plugin 삭제 | 자신의 디렉토리 내 파일만 삭제 | ✅ |
| Plugin 권한 시스템 | 없음 | ❌ |
| 위험 함수 사용 탐지 | 없음 | ❌ |
| Hook 호출자 추적 | 없음 | ❌ |
| Plugin Integrity 검사 | 없음 | ❌ |
| Plugin 감사 로그 | 없음 | ❌ |
3. PHP 환경의 현실적인 한계
일반 PHP Plugin 구조에서 완벽한 프로세스 수준 Sandbox는 불가능합니다.
같은 PHP 프로세스 내에서:
Plugin A
Plugin B
Core
가 함께 실행됨 → PHP 런타임 자체를 완전히 분리 불가
이 플러그인의 접근:
Level 1 — Logical Isolation (이 플러그인)
Permission + API Boundary + Audit Log
Level 2 — Filesystem Isolation (이 플러그인)
파일 영역 경계 검증
Plugin 전용 데이터 디렉토리 API
Level 3 — Detection
위험 함수 사용 탐지
Integrity 변조 탐지
Level 4 이상 — Process/Container Isolation
별도 프로세스/컨테이너 → 운영 환경에서 선택적 적용
4. 이 플러그인의 역할
코어를 수정하지 않고 탐지·로그·경계 검증으로 Isolation을 보강합니다.
5. 설치 방법
(DXCMS 루트)/
└── plugins/
└── dx-security-plugin/
├── manifest.php
└── plugin.php
관리자 → 플러그인 → dx-security-plugin → 활성화
6. 방어층 상세 설명
PI1. Plugin 권한 Logical Isolation
각 Plugin이 자신의 영역을 벗어나지 않도록 논리적 경계를 설정합니다.
Plugin 허용 영역:
plugins/{plugin_id}/ Plugin 코드 파일
data/plugin/{plugin_id}/ Plugin 데이터 파일
접근 금지:
plugins/{other_plugin}/ 다른 Plugin 파일
core/ Core 파일
admin/ 관리자 파일
data/plugin/{other}/ 다른 Plugin 데이터
PI2. Plugin 파일 영역 경계 검증
Plugin이 자신의 영역 밖에 파일을 쓰려 할 때 탐지/차단합니다.
dx_before_plugin_file_write 훅:
요청된 파일 경로 검증
→ Plugin 자신의 영역 밖 → FILE_WRITE_OUTSIDE_BOUNDARY 로그 + 차단
코어 dx_path_inside() 재사용 — Path Traversal (10번) 연계
PI3. 위험 함수 사용 탐지
Plugin 파일에서 위험 함수 사용을 탐지합니다.
탐지 대상:
shell_exec, exec, system, passthru
proc_open, popen, pcntl_exec
eval
처리:
→ DANGEROUS_FUNCTION 로그
→ 위반 횟수 카운터 증가
탐지 시점: 서버 시작 시 1회 스캔 (static 캐시 사용)
PI4. Hook 호출자 추적
관리자 Plugin 작업이 비정상 경로에서 호출되는 것을 탐지합니다.
탐지 조건:
관리자 URL이 아닌 곳에서
plugin_install, plugin_delete, plugin_activate 파라미터 포함
→ PLUGIN_ACTION_FROM_NON_ADMIN 로그
PI5. Plugin Integrity 검사
Plugin 파일이 설치 후 변조되지 않았는지 확인합니다.
검사 시점: 관리자 플러그인 페이지(/admin/plugins) 진입 시
검사 방법:
plugin.php + manifest.php MD5 해시 계산
이전 해시와 비교
→ 변경 시 INTEGRITY_CHANGED 로그
해시 저장: data/cache/plugin_hashes.php
PI6. 반복 위반 자동 비활성화 검토
동일 Plugin의 위반이 반복되면 단계적으로 경고합니다.
위반 카운터 (data/cache/pi_violations.php):
10회 이상 → REPEATED_VIOLATION 로그
20회 이상 → AUTO_DEACTIVATE_RECOMMENDED 로그
→ 관리자가 수동 검토 필요
완전 자동 비활성화는 하지 않음
이유: 운영 장애 가능성
→ 관리자에게 검토를 권고하는 방식
PI7. Plugin 감사 로그
Plugin 생명주기 전체를 기록합니다.
| 이벤트 | 기록 시점 |
|---|---|
PLUGIN_INSTALLED |
설치 시 |
PLUGIN_ACTIVATED |
활성화 시 |
PLUGIN_DEACTIVATED |
비활성화 시 |
PLUGIN_UPDATED |
업데이트 시 |
PLUGIN_UNINSTALLED |
삭제 시 |
7. 보안 로그 읽는 법
이벤트 타입
| 타입 | 의미 |
|---|---|
PI:PLUGIN_INSTALLED |
Plugin 설치 |
PI:PLUGIN_ACTIVATED |
Plugin 활성화 |
PI:PLUGIN_DEACTIVATED |
Plugin 비활성화 |
PI:PLUGIN_UPDATED |
Plugin 업데이트 |
PI:PLUGIN_UNINSTALLED |
Plugin 삭제 |
PI:DANGEROUS_FUNCTION |
위험 함수 탐지 |
PI:FILE_OUTSIDE_BOUNDARY |
Plugin 경계 밖 파일 |
PI:FILE_WRITE_OUTSIDE_BOUNDARY |
영역 밖 파일 쓰기 시도 |
PI:PLUGIN_ACTION_FROM_NON_ADMIN |
비관리자 경로에서 Plugin 작업 |
PI:INTEGRITY_CHANGED |
Integrity 해시 변경 탐지 |
PI:PLUGIN_PATH_CHECK_FAILED |
경로 검증 실패 |
PI:REPEATED_VIOLATION |
반복 위반 경고 |
PI:AUTO_DEACTIVATE_RECOMMENDED |
비활성화 검토 권고 |
로그 예시
# 위험 함수 탐지
[2026-09-03 09:00:01][PI:DANGEROUS_FUNCTION][IP:-][...][UID:0][URI:-]
plugin_id=unknown-plugin function=shell_exec
# Integrity 변조
[2026-09-03 14:22:10][PI:INTEGRITY_CHANGED][IP:121.131.x.x][...][UID:1][URI:/admin/plugins]
plugin_id=forum-plugin
# 파일 영역 밖 쓰기 시도
[2026-09-03 16:45:03][PI:FILE_WRITE_OUTSIDE_BOUNDARY][IP:45.33.x.x][...][UID:0][URI:/api/upload]
plugin_id=my-plugin path=/var/www/core/config.php
# Plugin 활성화 감사
[2026-09-03 20:11:44][PI:PLUGIN_ACTIVATED][IP:121.131.x.x][...][UID:1][URI:/admin/plugins]
plugin_id=board-plugin
8. 보안 강점 요약
| 위협 | 결과 | 방어 레이어 |
|---|---|---|
| 악성 Plugin에 shell_exec 포함 | DANGEROUS_FUNCTION 탐지 | PI3 |
| Plugin 파일 변조 | INTEGRITY_CHANGED 탐지 | PI5 |
| 다른 Plugin 영역 파일 쓰기 시도 | 차단 + 로그 | PI2 |
| 비관리자 경로에서 Plugin 조작 | 탐지 로그 | PI4 |
| Plugin 반복 위반 | 단계적 경고 로그 | PI6 |
| Plugin 설치/삭제/업데이트 | 감사 로그 | PI7 |
| 정상 Plugin 동작 | 영향 없음 | ✅ |
9. 개발자 API 가이드
Plugin 파일 경로 검증
// 파일 접근 전 경로 검증
$filePath = DX_ROOT . '/data/plugin/my-plugin/config.json';
if (!dx_plugin_check_path('my-plugin', $filePath)) {
// 영역 밖 경로 — 접근 거부
exit;
}
// 안전하게 파일 읽기
$content = file_get_contents($filePath);
Plugin 전용 데이터 디렉토리 사용
// 올바른 방법 — 전용 디렉토리 사용
$dir = dx_plugin_data_dir('my-plugin');
if ($dir) {
file_put_contents($dir . '/config.json', json_encode($config));
}
// 잘못된 방법 (금지)
// file_put_contents(DX_ROOT . '/core/config.php', $evil);
// file_put_contents(DX_PLUGINS . '/other-plugin/plugin.php', $evil);
Plugin Integrity 해시
// 설치 시 해시 저장
$hash = dx_plugin_integrity_hash('my-plugin');
// → DB나 설정에 저장
// 실행 시 검증
$current = dx_plugin_integrity_hash('my-plugin');
if ($current !== $storedHash) {
dx_plugin_log('INTEGRITY_MISMATCH', 'my-plugin', 'hash changed');
}
Plugin 감사 로그 기록
// Plugin에서 직접 감사 로그 기록
dx_plugin_log('MY_SENSITIVE_ACTION', 'my-plugin',
'action=delete_all user_id=' . $userId);
DX Security — Plugin Isolation 방어 v1.0.0 — DesignOneX https://designonex.com
라이선스
디자인원엑스 라이선스 참고
https://designonex.com/notice/view/1787577858493247