DXCMS v8.1.0 종합 평가 보고서
작성일: 2026-05-31 평가 대상: DXCMS_v8_1_0.zip (DesignOneX CMS v8.1.0) 제조사: designonex [디자인원엑스] 라이선스: GNU Lesser General Public License v3.0 (LGPL-3.0) 평가 범위: 시스템 아키텍처 · 보안 · 성능 · 코드 품질 · 데이터베이스 스키마
목차
- 개요
- 아키텍처 분석
- 2.1 부트스트랩 및 초기화
- 2.2 의존성 주입(DI) 컨테이너
- 2.3 라우팅 및 디스패칭
- 2.4 데이터베이스 추상화
- 보안 평가
- 3.1 입력값 검증 및 필터링
- 3.2 잠재적 보안 고려사항
- 성능 평가
- 코드 품질 및 유지보수성
- 데이터베이스 스키마
- 결론
1. 개요
본 보고서는 제공된 DXCMS_v8_1_0.zip 패키지에 포함된 DXCMS v8.1.0 버전에 대한 종합적인 기술 평가를 목적으로 합니다. 평가는 시스템 아키텍처, 보안, 성능, 코드 품질 및 유지보수성, 데이터베이스 스키마를 중심으로 진행되었습니다.
2. 아키텍처 분석
DXCMS v8.1.0은 PHP 기반의 콘텐츠 관리 시스템(CMS)으로, 단일 부트스트랩 파일(dx_load.php)을 통해 전체 환경을 초기화하는 방식으로 설계되었습니다. 주요 아키텍처 구성 요소는 다음과 같습니다.
2.1 부트스트랩 및 초기화
dx_load.php 파일은 그누보드의 _common.php와 동일한 역할을 하는 단일 진입 부트스트랩으로, 이 파일 하나만 require하면 DXCMS 전체 환경이 활성화됩니다. 초기화 순서는 다음과 같습니다.
- 출력 버퍼링:
ob_start()를 사용하여 헤더 전송 오류를 방지합니다. - PHP 설정 조정:
pcre.backtrack_limit,memory_limit(256M)등 공유 호스팅 호환 설정을 적용합니다. - 루트 자동 탐색:
__DIR__에서 시작하여 상위 디렉토리를 순회하며dx_load.php를 찾아DX_ROOT를 동적으로 결정합니다. 어느 하위 폴더에서 호출해도 정상 동작합니다. - 핵심 상수 정의:
DX_VERSION(8.1.0),DX_ROOT,DX_CORE,DX_DATA,DX_THEMES,DX_PLUGINS,DX_BOARDS,DX_EXTEND등 경로 상수를 일괄 정의합니다. - 설치 여부 확인:
data/config.php파일 존재 여부로 설치 상태를 판단합니다. - HTTPS 감지: IIS, 리버스 프록시, Cloudflare(
HTTP_CF_VISITOR) 등 다양한 환경에서 HTTPS 여부를 정확히 감지합니다. - 보안 경로 파싱:
DX_SECURITY_PATH를config.php에서 미리 파싱하여 설치 시 생성된 고유 경로의Secure.php를 로드합니다. 해당 파일이 없을 경우 원본core/Secure.php로 폴백합니다. - 핵심 클래스 로드:
functions.php,DxCache.php,Secure.php,Database.php,HookManager.php,PluginRegistry.php,Auth.php,DxContainer.php순으로 로드합니다. - 보안 초기화:
Secure클래스 인스턴스를 생성하고 세션 설정, 세션 시작, 보안 헤더 전송, CSRF 토큰 발급을 처리합니다. - DB 연결 및 설정 로드:
config.php를 로드하여 DB 연결을 설정하고,secret_key를 주입하여 세션/CSRF/RateLimit 키 이름을 동적으로 도출합니다. - 서비스 초기화:
HookManager,PluginRegistry,DxSite,DxTheme,Auth,DxContainer,DxExtend등 주요 서비스 인스턴스를 초기화하고 훅을 등록합니다.
dx_load.php 초기화 흐름
─────────────────────────────────────────────
ob_start()
→ PHP 설정 조정 (pcre, memory)
→ DX_ROOT 자동 탐색
→ data/config.php 존재 확인
→ HTTPS 감지 (IIS·Nginx·CF 포함)
→ DX_SECURITY_PATH → Secure.php 로드
→ functions.php / DxCache.php / Database.php
→ HookManager / PluginRegistry / Auth
→ DxContainer (핵심 서비스 등록)
→ DxExtend::runTop() ← extend/top/ 실행
→ Router::resolve()
→ Dispatcher::dispatch()
→ DxExtend::runBottom() ← extend/bottom/ 실행
→ ob_end_flush()
2.2 의존성 주입(DI) 컨테이너
DXCMS는 DxContainer 클래스를 통해 경량화된 의존성 주입(DI) 컨테이너를 구현합니다. Laravel의 서비스 컨테이너와 유사한 철학을 가지며, PHP 5.6 환경에서 동작하도록 설계되었습니다.
- 바인딩:
bind(),singleton(),instance()메서드를 통해 서비스 팩토리 또는 인스턴스를 등록합니다. - 해석(Resolve):
make()메서드를 통해 등록된 서비스를 가져오며,alias()를 통한 별칭을 지원합니다. 바인딩이 없는 경우 클래스명으로 직접 인스턴스화를 시도합니다. - 컨트롤러 자동 의존성 주입:
call()메서드를 통해ClassName@method형식의 컨트롤러 메서드를 호출할 때, 컨트롤러 클래스를 자동으로 로드·인스턴스화하며 생성자 파라미터에 대한 의존성 주입을 시도합니다. - 핵심 서비스 등록:
registerCoreServices()메서드를 통해db,auth,secure,cache,hook,seo,site,theme등 CMS의 핵심 서비스를 컨테이너에 등록합니다.
php
// 사용 예시
dx_app()->bind('mailer', function($c) {
return new DxMailer($c->make('db'));
});
dx_app()->singleton('sms', function($c) {
return new DxSms();
});
$mailer = dx_make('mailer'); // 또는 dx_app()->make('mailer')
dx_app()->call('BoardController@index', ['slug' => 'free']);
2.3 라우팅 및 디스패칭
Router 클래스는 요청 URI를 분석하여 적절한 핸들러로 연결하는 역할을 담당합니다.
URI 파싱 및 세그먼트 정제
IIS, Apache, Nginx, 서브디렉토리 설치 환경 등 다양한 웹서버에서 REQUEST_URI를 정규화하고 베이스 경로를 제거합니다. XSS 및 경로 순회 공격을 방지하기 위해 sitemap*.xml, robots.txt 같은 예외를 제외하고는 영문자·숫자·하이픈·언더스코어만 허용하도록 세그먼트를 정제합니다.
라우트 타입 결정
resolve() 메서드는 URI 세그먼트를 기반으로 라우트 타입을 결정합니다.
| 타입 상수 | 매핑 조건 | 설명 |
|---|---|---|
TYPE_HOME |
URI가 비어 있거나 / |
홈 페이지 |
TYPE_SEARCH |
첫 세그먼트 search |
검색 결과 |
TYPE_ADMIN |
첫 세그먼트 admin |
관리자 패널 |
TYPE_AUTH |
첫 세그먼트 auth |
인증 (로그인·회원가입·마이페이지) |
TYPE_API |
첫 세그먼트 api 또는 core/api |
Ajax API |
TYPE_BOARD |
dx_boards에서 board_key 매칭 |
게시판 |
TYPE_PAGE |
dx_pages에서 slug 매칭 |
커스텀 페이지 |
TYPE_404 |
위 조건 모두 불일치 | 404 |
게시판 및 페이지 조회 시 site_domain 컬럼의 존재 여부를 SHOW COLUMNS 쿼리로 자동 감지(결과 캐싱)하여 멀티사이트 환경을 지원합니다.
Dispatcher
Router에 의해 해석된 라우트 정보를 바탕으로 실제 액션을 실행합니다. 주요 특징은 다음과 같습니다.
extend/middle훅을 라우트 확정 직후, 핸들러 실행 전에 실행합니다.- 페이지 파일 로드 시
dx_path_inside()경로 포함 여부 검사로 디렉토리 트래버설을 방지합니다. set_error_handler()를 이용한 오류 격리(renderPageWithLayout,renderStandalone)로 단일 페이지 오류가 전체 응답을 중단시키지 않도록 합니다.- 접근 권한 검사(
checkPageAccess,checkBoardAccess)를 디스패치 단계에서 일괄 처리합니다.
2.4 데이터베이스 추상화
Database 클래스는 PDO를 래핑하여 데이터베이스 연결 및 쿼리 실행을 추상화합니다.
PDO 설정
| PDO 옵션 | 설정값 | 이유 |
|---|---|---|
ERRMODE |
EXCEPTION |
오류를 예외로 전환 |
DEFAULT_FETCH_MODE |
FETCH_ASSOC |
연관 배열 기본 반환 |
EMULATE_PREPARES |
true |
32비트 PHP BIGINT 오버플로우 방지 |
STRINGIFY_FETCHES |
true |
모든 숫자형 값을 문자열로 수신 |
편의 메서드
기본 쿼리 실행 메서드(row(), rows(), value(), query(), insert())와 빌더 스타일 편의 메서드(find(), findAll(), insertRow(), updateRow(), deleteRow(), exists(), count())를 제공합니다. 트랜잭션은 begin(), commit(), rollback()으로 지원합니다.
Microtime ID 생성
posts, comments 테이블의 BIGINT PK는 generateMicrotimeId() 메서드가 생성하는 문자열 기반 ID를 사용합니다.
ID 구조: [10자리 초 타임스탬프] + [3자리 밀리초] + [3자리 랜덤] = 16자리 이하
예: 1748649600123456
목적:
- 32비트 PHP 환경에서 (int) 캐스팅으로 인한 오버플로우 방지
- 삽입 직전 중복 확인 후 최대 10회 재시도
- 문자열로 반환하여 DB 전달 시에도 정밀도 손실 없음
3. 보안 평가
DXCMS는 다양한 보안 위협에 대응하기 위한 다층적 메커니즘을 내장하고 있습니다.
3.1 입력값 검증 및 필터링
Secure.php WAF (Web Application Firewall)
Secure 클래스(v5.2.2)는 SQL Injection, XSS, LFI(Local File Inclusion), Command Injection 공격을 탐지·차단하기 위한 WAF 규칙을 내장합니다. POST 본문에서 content, body, description, editor_content 등 에디터 관련 필드는 WAF 검사에서 제외하여 오탐을 줄이도록 설계되었습니다.
DxSanitizer.php XSS 방어
DxSanitizer 클래스는 HTML 콘텐츠를 정제하여 XSS 공격을 방어합니다.
- 차단 태그:
script,iframe,object,embed,applet,form,input,button,select,textarea,frame,frameset,noscript,xml,svg등 - 이벤트 핸들러 제거:
on*속성 패턴을 정규식으로 전체 제거 (onclick,onload등) - 위험 프로토콜 차단:
blocked:,blocked:,blocked:,blocked:→blocked:로 치환 - data: URI 차단:
src="data:..."형식의 XSS 벡터 제거 - CSS 제거: IE 계열 CSS 인젝션 방지
- 허용 태그 화이트리스트:
strip_tags()로 비허용 태그 일괄 제거 후 속성 단위 필터링 - 허용 스타일 화이트리스트:
font-family,text-align,text-decoration,line-height등 안전한 CSS 속성만 허용 - URL 정제:
menuUrl(),url()메서드로 링크 속성 내 위험 프로토콜 차단
보안 경로(Security Path) 난독화
DX_SECURITY_PATH = 설치 시 생성된 16자리 해시 (data/config.php 정의)
경로: core/security/{hash}/Secure.php
폴백: 경로 미정의 또는 파일 없으면 원본 core/Secure.php 사용
설치 시 생성된 고유 경로를 사용함으로써 보안 클래스 파일 위치를 예측하기 어렵게 합니다.
CSRF 보호
- 토큰은 세션에 저장되며 3시간(
CSRF_TTL = 10800) 유효 - 연속 요청 시 동일 토큰을 유지하고 만료 시간만 갱신하여 사용자 경험 저해 없음
- 글쓰기 중 하트비트(Ajax)로 자동 갱신되어 장시간 작성 시에도 세션 만료 방지
csrfField()메서드로 HTML form 은닉 필드 자동 생성
세션 관리
session.use_only_cookies,session.cookie_httponly,session.gc_maxlifetime설정으로 세션 보안 강화- PHP 7.3+ 환경에서는
SameSite=Lax, PHP 7.1+에서는session.use_strict_mode적용 - 24시간마다 세션 ID 재생성으로 세션 하이재킹·고정 공격 대응
dx_member_sessions테이블을 통한 다중 기기 세션 추적
보안 HTTP 헤더
| 헤더 | 설정 | 방어 대상 |
|---|---|---|
X-Frame-Options |
SAMEORIGIN |
클릭재킹 |
X-Content-Type-Options |
nosniff |
MIME 스니핑 |
Referrer-Policy |
strict-origin-when-cross-origin |
리퍼러 노출 |
X-XSS-Protection |
1; mode=block |
구형 브라우저 XSS |
Permissions-Policy |
카메라·마이크·위치 차단 | 권한 남용 |
Strict-Transport-Security |
max-age=31536000 (HTTPS 시) |
프로토콜 다운그레이드 |
Content-Security-Policy |
스크립트·스타일·이미지 출처 제한 | XSS·리소스 인젝션 |
파일 업로드 검증
Secure::validateUpload() 메서드는 MIME 타입 화이트리스트를 통해 악성 파일 업로드를 방지합니다. 허용 MIME 타입은 image/jpeg, image/png, application/pdf, application/msword 등으로 제한됩니다.
Rate Limit
Redis 또는 파일 기반으로 Rate Limit 기능을 제공합니다.
| 설정 | 기본값 |
|---|---|
| Rate Window | 10초 |
| 세션별 최대 요청 | 60회 |
| IP별 최대 요청 | 200회/분 |
봇 탐지 및 화이트리스트
allowedBots 화이트리스트(Googlebot, Yeti, bingbot, DuckDuckBot, kakaotalk-scrap 등 12종)에 등록된 검색 엔진 봇은 허용하고, 그 외 의심스러운 봇 활동은 로그에만 기록합니다(차단 대신 로그 — 검색 엔진 봇 오차단 방지).
IP 바인딩
모바일 환경(IP 변경 빈번)을 고려하여 기본 비활성화. 옵션으로 활성화 시 세션 하이재킹 방어에 사용할 수 있습니다.
3.2 잠재적 보안 고려사항
admin/socket/index.php의 SSL 검증 비활성화
admin/socket/index.php에서 내부 HTTP GET 요청 시 아래와 같이 SSL 검증을 비활성화하는 코드가 확인되었습니다.
php
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
이는 중간자 공격(MITM)에 취약할 수 있으므로, 프로덕션 환경에서는 SSL 검증을 활성화하거나 내부 네트워크 통신으로 제한하는 것을 권장합니다.
$_GET, $_POST 직접 접근
코드 전반에 걸쳐 $_GET 및 $_POST 슈퍼글로벌 변수에 직접 접근하는 부분이 다수 존재합니다. Secure::sanitize() 또는 dx_input()과 같은 헬퍼 함수를 사용하여 입력값을 안전하게 처리하는 일관된 패턴을 적용하는 것이 권장됩니다. DxSanitizer::text()는 제어 문자를 제거하지만, HTML 엔티티 인코딩은 출력 시 htmlspecialchars()를 통해 별도로 이루어져야 함을 명시합니다.
4. 성능 평가
DXCMS는 성능 최적화를 위해 다음과 같은 메커니즘을 적용하고 있습니다.
4.1 멀티 드라이버 캐시 (DxCache.php)
DxCache 클래스는 환경에 따라 캐시 드라이버를 자동 선택합니다.
| 우선순위 | 드라이버 | 활성화 조건 | 특징 |
|---|---|---|---|
| 1순위 | Redis | REDIS_SESSION_URL 상수 정의 + Redis 익스텐션 + 연결 성공 |
원자적 연산, 다중 서버 공유 가능 |
| 2순위 | APCu | apcu_fetch 존재 + apc.enabled 활성화 |
PHP-FPM 프로세스 간 공유 메모리 |
| 3순위 | 파일 | data/cache/ 디렉토리 쓰기 가능 |
원자적 쓰기(임시파일 + rename) |
| 폴백 | none | 위 모두 불가 | 캐시 없이 동작 (치명적 오류 없음) |
Redis 연결 실패 시 자동으로 다음 드라이버로 폴백하여 서비스 연속성을 보장합니다. 파일 캐시는 getmypid()를 포함한 임시 파일명으로 원자적 쓰기를 구현하여 동시 쓰기 충돌을 방지합니다.
캐시 효과
settings캐시: 매 요청마다 발생하는 전역 설정 DB 쿼리 제거- 게시판 목록 캐시: 읽기 전용 요청의 DB 부하 감소
4.2 데이터베이스 인덱스 최적화
schema.sql의 인덱스 설계:
| 테이블 | 주요 인덱스 | 최적화 대상 |
|---|---|---|
dx_posts |
idx_board_status_id (board_id, status, id) |
게시판 목록 페이지네이션 |
dx_posts |
idx_popular_score (board_id, status, popular_score) |
인기글 정렬 |
dx_posts |
ft_title_content (FULLTEXT) |
전문 검색 |
dx_members |
idx_join_date |
회원 가입일 정렬 |
dx_boards |
idx_site_domain |
멀티사이트 게시판 조회 |
dx_notifications |
idx_to_unread (to_member_id, is_read) |
읽지 않은 알림 조회 |
dx_visit_logs |
idx_ip_date_browser (복합 4열) |
방문 통계 집계 |
dx_search_keywords |
FULLTEXT | 검색어 자동완성 |
dx_link_clicks |
uk_link_ip_date |
중복 클릭 방지 |
FULLTEXT 인덱스는 MySQL 5.6+ InnoDB에서 지원됩니다.
4.3 세션 최적화
GET 요청이면서 세션 쿠키가 없고 admin, auth, view, api, write, edit, reply 경로가 아닌 경우 세션 시작을 건너뜁니다. 비로그인 사용자의 단순 페이지 조회 시 불필요한 세션 파일 락을 방지하여 동시 처리 성능을 향상시킵니다.
4.4 BIGINT ID 처리
32비트 PHP 환경에서 BIGINT ID의 오버플로우를 방지하기 위해 PDO::ATTR_EMULATE_PREPARES 및 PDO::ATTR_STRINGIFY_FETCHES를 true로 설정하고, generateMicrotimeId() 함수로 문자열 기반 고유 ID를 생성합니다. 코드 내 (int) 캐스팅을 명시적으로 금지하는 주석이 포함되어 있습니다.
5. 코드 품질 및 유지보수성
5.1 모듈화 및 관심사 분리
Router, Dispatcher, Secure, Database, DxCache, DxSanitizer 등 각 클래스가 명확한 단일 책임을 가지고 모듈화되어 있어 가독성과 유지보수성이 높습니다.
핵심 클래스 목록:
| 클래스 | 역할 |
|---|---|
Secure |
보안 전반 (WAF, CSRF, 세션, 헤더, Rate Limit) |
Database |
PDO 래퍼, 쿼리 빌더 |
QueryBuilder |
라라벨 스타일 체인 쿼리 |
DxCache |
멀티 드라이버 캐시 |
DxSanitizer |
XSS 방어, 입력값 정제 |
DxContainer |
DI 컨테이너 |
Router |
URI 파싱 및 라우트 결정 |
Dispatcher |
라우트 실행 및 오류 격리 |
DxExtend |
훅 기반 확장 (top/middle/bottom) |
DxSocialAuth |
OAuth 2.0 소셜 로그인 |
DxMarket |
마켓 API 연동 |
DxTheme |
테마 관리 |
PluginRegistry |
플러그인 생명주기 |
HookManager |
훅 등록·실행 |
DxMailer |
메일 발송 (멀티 드라이버) |
DxSms |
SMS 발송 (멀티 드라이버) |
DxCaptcha |
캡챠 (멀티 드라이버) |
DxPoint |
포인트 시스템 |
DxNotification |
알림 시스템 |
DxSeo |
SEO 메타 관리 |
5.2 의존성 주입 컨테이너
DxContainer를 통한 DI 패턴은 코드 결합도를 낮추고 유연성을 높여 테스트 및 확장을 용이하게 합니다.
5.3 플러그인 아키텍처
PluginRegistry를 통해 플러그인 시스템을 지원하며, extend/ 디렉토리를 통한 확장 기능은 핵심 코드를 수정하지 않고도 기능을 추가하거나 변경할 수 있도록 합니다. DxExtend 클래스는 extend/top, extend/middle, extend/bottom 디렉토리의 PHP 파일을 safeExec()를 통해 오류 격리 모드로 로드합니다.
extend/top/ ← CMS 초기화 직후 (DB·세션·인증 완료 후)
extend/middle/ ← 라우팅 직전 (route 확정 후)
extend/bottom/ ← 렌더링 완료 후 (ob_end_flush 직전)
5.4 PHP 5.6+ 호환성
PHP 5.6부터 8.x까지 광범위한 버전 호환성을 유지합니다. IIFE 대신 일반 함수, ReflectionClass 사용 최소화, 32비트 PHP의 BIGINT 처리, mcrypt_create_iv 폴백(dx_random_bytes), SameSite 쿠키 PHP 버전 분기 등 하위 버전에서도 안정적으로 동작하도록 세밀하게 고려되어 있습니다.
5.5 주석 및 문서화
코드 내에 상세한 주석이 한국어로 작성되어 있으며, 각 클래스·메서드의 역할, 변경 사항, 사용법이 명확하게 설명되어 있습니다. docs/ 디렉토리에는 CAPTCHA_MANUAL.md, MARKET_API_SPEC.md가 포함되어 있으며, 스킨 개발자를 위한 boards/skins/SKIN_GUIDE.md와 컨트롤러 개발 예시(controllers/README.md)도 제공됩니다.
6. 데이터베이스 스키마
install/schema.sql에는 총 47개 테이블이 정의되어 있으며 MySQL 5.6+ InnoDB 엔진을 기준으로 설계되었습니다.
6.1 테이블 분류
회원 및 인증
| 테이블 | 설명 |
|---|---|
dx_members |
회원 기본 정보 (login_id·email UNIQUE, role·status·level 인덱스) |
dx_social_accounts |
소셜 로그인 연결 계정 (provider+provider_id UNIQUE) |
dx_member_sessions |
다중 기기 세션 추적 (session_key UNIQUE) |
dx_member_logs |
회원 활동 로그 (event·created_at 인덱스) |
dx_login_tokens |
자동 로그인 토큰 (token UNIQUE, expires_at 인덱스) |
dx_session_rescue |
세션 복구 키 (rescue_key UNIQUE) |
게시판 및 콘텐츠
| 테이블 | 설명 |
|---|---|
dx_boards |
게시판 설정 (board_key UNIQUE, site_domain 인덱스) |
dx_board_groups |
게시판 그룹 |
dx_board_fields |
게시판 커스텀 필드 정의 |
dx_categories |
카테고리 |
dx_posts |
게시글 (BIGINT PK, FULLTEXT 검색, 복합 인덱스) |
dx_post_meta |
게시글 커스텀 필드 값 (post_id+field_key UNIQUE) |
dx_post_files |
첨부파일 |
dx_post_links |
외부 링크 |
dx_post_drafts |
임시저장 (member+board, session+board 인덱스) |
dx_comments |
댓글 (BIGINT PK, parent_id 계층 구조) |
소통 및 커뮤니티
| 테이블 | 설명 |
|---|---|
dx_memos |
쪽지 (to_id+is_read 복합 인덱스) |
dx_dm_messages |
DM 채팅 메시지 (chat_group+id 인덱스) |
dx_notifications |
알림 (to_member_id+is_read 인덱스) |
dx_friends |
친구 관계 |
dx_likes |
좋아요 |
dx_scraps |
스크랩 |
dx_global_notices |
전체 공지 (기간·정렬 인덱스) |
사이트 관리
| 테이블 | 설명 |
|---|---|
dx_pages |
커스텀 페이지 (slug UNIQUE, site_domain 인덱스) |
dx_menus |
메뉴 구성 (site_domain·menu_group 인덱스) |
dx_popups |
팝업 (기간·상태 인덱스) |
dx_sites |
멀티사이트 |
dx_themes |
테마 정보 |
dx_plugins |
플러그인 정보 |
dx_settings |
전역 설정 (key-value) |
포인트 및 레벨
| 테이블 | 설명 |
|---|---|
dx_point_log |
포인트 적립·차감 내역 |
dx_exp_log |
경험치 내역 |
dx_level_config |
레벨 설정 |
커머스 및 마켓
| 테이블 | 설명 |
|---|---|
dx_shop_items |
쇼핑몰 상품 |
dx_shop_purchases |
구매 내역 |
dx_download_log |
다운로드 로그 |
dx_link_clicks |
링크 클릭 추적 (link_id+ip+date UNIQUE) |
통계 및 로그
| 테이블 | 설명 |
|---|---|
dx_visits |
방문 집계 |
dx_visit_logs |
방문 상세 로그 (복합 인덱스 8개) |
dx_search_keywords |
검색어 (FULLTEXT 인덱스) |
dx_sms_logs |
SMS 발송 로그 |
dx_api_keys |
API 키 (api_key·site_domain UNIQUE) |
dx_api_logs |
API 호출 로그 |
설문조사
| 테이블 | 설명 |
|---|---|
dx_surveys |
설문 (post_id UNIQUE) |
dx_survey_questions |
설문 항목 |
dx_survey_answers |
응답 내용 |
dx_survey_votes |
참여 기록 (survey_id+member_id UNIQUE) |
6.2 스키마 설계 특징
- 멀티사이트 지원:
dx_boards,dx_pages,dx_menus등 핵심 테이블에site_domain컬럼 및 인덱스를 추가하여 단일 DB로 다중 도메인을 운영할 수 있습니다. - 커스텀 필드 확장:
dx_board_fields(필드 정의)와dx_post_meta(필드 값)의 EAV(Entity-Attribute-Value) 패턴으로 게시판별 커스텀 필드를 스키마 변경 없이 추가할 수 있습니다. - 전문 검색:
dx_posts의ft_title_contentFULLTEXT 인덱스와dx_search_keywords의 FULLTEXT 인덱스로 MySQL 네이티브 전문 검색을 지원합니다. - 계층 댓글:
dx_comments의parent_id자기 참조 구조로 중첩 댓글을 지원합니다. - 클릭 중복 방지:
dx_link_clicks의uk_link_ip_date (link_id, ip, click_date)UNIQUE 키로 DB 수준에서 일 1회 클릭 중복을 방지합니다.
7. 결론
DXCMS v8.1.0은 PHP 5.6+ 환경에서 동작하는 견고하고 기능이 풍부한 CMS입니다.
강점
아키텍처는 모듈화가 잘 되어 있으며, 의존성 주입 컨테이너와 플러그인 시스템을 통해 확장성과 유지보수성을 확보했습니다. 보안 측면에서는 WAF, CSRF 보호, 세션 관리, 보안 헤더, 파일 업로드 검증, Rate Limit 등 다층적인 방어 메커니즘을 갖추고 있습니다. 성능 또한 멀티 드라이버 캐시, 세션 최적화, 데이터베이스 인덱스 최적화를 통해 고려되었습니다. 총 47개 테이블로 구성된 스키마는 커스텀 필드 확장, 멀티사이트, 전문 검색 등 실무 요구사항을 폭넓게 수용합니다.
개선 권고사항
admin/socket/index.php의 SSL 검증 비활성화(CURLOPT_SSL_VERIFYPEER => false)는 프로덕션 환경에서 활성화하거나 내부 네트워크 통신으로 제한할 것을 권장합니다.$_GET,$_POST직접 접근 부분에Secure::sanitize()또는dx_input()헬퍼 함수를 통한 일관된 입력값 처리 패턴 적용이 필요합니다.- CKEditor 4는 2023년 이후 공식 지원이 종료된 버전으로, 장기적으로는 CKEditor 5 또는 대체 에디터로의 전환을 검토할 것을 권장합니다.
전반적으로 DXCMS v8.1.0은 안정적이고 확장 가능한 CMS 솔루션으로 평가됩니다. 특히 공유 호스팅 환경에서의 광범위한 호환성과 한국 서비스(카카오·네이버 소셜 로그인, 국내 SMS 제공사)에 특화된 구성은 경쟁 제품 대비 뚜렷한 강점입니다.
본 보고서는 DXCMS_v8_1_0.zip 소스 패키지의 정적 코드 분석을 기반으로 작성되었습니다.