T2Editor 9.1.2-alpha1.0.0 전수감사 보고서
- T2Editor 9.1.2-alpha1.0.0 전수감사 보고서
- 1. 감사 개요
- 2. 감사 범위
- 3. 감사 방법
- 3.1 전수 비교
- 3.2 정적 분석
- 3.3 문법 점검
- 3.4 스팟 테스트
- 4. 전수 비교 결과
- 4.1 패키지 비교 총괄
- 4.2 변경 파일 전수 목록
- 5. 실반영 확인 사항
- 5.1 업로드 공통 보안 경계 강화
- 5.2 설정 계층의 보안·구조 개선
- 5.3 설정 조회 경로의 중복 정의 제거
- 5.4 파일 업로드 엔드포인트 정비
- 5.5 이미지 업로드 보호 강화
- 5.6 비디오 업로드 및 재생 경로 복구
- 5.7 파일 플러그인 전반 재정비
- 5.8 코드 블럭 및 에디터 복원성 보강
- 5.9 테이블 붙여넣기 경로 보강
- 5.10 UI/디자인·운영 안정성 개선
- 6. 문법 점검 및 테스트 결과
- 6.1 PHP 문법 검사
- 6.2 JavaScript 문법 검사
- 6.3 스팟 테스트 결과
- 7. 잔존 위험 및 미해소 사항
- 8. 종합 판정
- 8.1 판정
- 8.2 판정 사유
- 8.3 권고
- 9. 대외 공지 반영 가능 문안(내부 검토용)
본 감사는 T2Editor 9.1.1을 기준선으로 하여 9.1.2-alpha1.0.0 패키지 전체를 전수 비교·전수 점검한 결과를 정리한 것이다. 감사 결과, 9.1.2-alpha1.0.0은 업로드 보안 경계, 허용 도메인 중앙화, 비디오 업로드·재생 경로, 파일 블럭 복원, 코드블럭 입력 안정성 등 다수의 개선이 실제 반영된 것으로 확인되었다. 다만, editor.lib.php의 hidden textarea 원문 출력, js/core.js의 수기 HTML 정화 로직, 일부 협업 엔드포인트의 과도한 CORS 허용 등 잔존 위험이 존재하므로 최종 판정은 '''조건부 승인'''으로 한다.
1. 감사 개요
| 항목 | 내용 |
|---|---|
| 대상 버전 | 9.1.2-alpha1.0.0 |
| 기준 버전 | 9.1.1 |
| 감사 방식 | 패키지 전수 비교, 정적 분석, 문법 점검, 함수 단위 스팟 테스트 |
| 비교 단위 | 동일 파일명 69개 전수 대조 |
| 실제 변경 파일 | 17개 |
| 감사 목적 | 9.1.1 대비 보안·기능·안정성 변경의 실반영 여부와 잔존 위험 식별 |
2. 감사 범위
감사 범위는 다음과 같다.
- 9.1.1 전체 패키지
- 9.1.2-alpha1.0.0 전체 패키지
- 변경 파일 17개에 대한 수기 검토
- 전체 패키지 69개 파일에 대한 정적 검색 기반 위험 징후 확인
- 변경 PHP 파일 문법 검사
- 변경 JavaScript 파일 문법 검사
- 허용 도메인 함수, Origin 검증, 업로드 MIME/매직바이트 검증에 대한 스팟 테스트
3. 감사 방법
3.1 전수 비교
- 9.1.1과 9.1.2-alpha1.0.0의 전체 파일 목록을 대조하였다.
- 파일명 기준 동일한 69개 파일을 전수 확인하였다.
- 추가/삭제 파일은 없었고, 변경 파일 17개를 식별하였다.
3.2 정적 분석
- HTML 주입 관련 키워드(
innerHTML,outerHTML,href,src,style)를 전수 검색하였다. - 업로드 관련 키워드(
move_uploaded_file,finfo,realpath,check_request_origin)를 전수 검색하였다. - CORS, Host 헤더, 절대 URL 허용, hidden textarea 출력, 사용자 입력 기반 속성 삽입 여부를 중점 검토하였다.
3.3 문법 점검
- 변경 PHP 파일 전부에 대해
php -l검사를 수행하였다. - 변경 JavaScript 파일 전부에 대해
node --check검사를 수행하였다.
3.4 스팟 테스트
t2editor_get_allowed_domains()및t2editor_is_allowed_url()의 정상·비정상 URL 처리 여부를 확인하였다.check_request_origin()의 POST 빈 Origin 차단 여부를 확인하였다.validate_upload_file()의 MIME/매직바이트 보강이 실제로 동작하는지 확인하였다.
4. 전수 비교 결과
4.1 패키지 비교 총괄
| 항목 | 수치 |
|---|---|
| 전체 파일 수(9.1.1) | 69 |
| 전체 파일 수(9.1.2-alpha1.0.0) | 69 |
| 추가 파일 | 0 |
| 삭제 파일 | 0 |
| 변경 파일 | 17 |
4.2 변경 파일 전수 목록
| 번호 | 파일 | 변경 규모(상대) | 주된 성격 |
|---|---|---|---|
| 1 | config/get_upload_config.php | 소 | 설정 조회 경로 정리 및 Origin 검증 |
| 2 | config/nsfw_api_browser.js | 중 | NSFW 로딩 경로/진행률 UI 지원 |
| 3 | config/t2_config.php | 중 | Host 검증, 경로 계산, 허용 도메인 공통화 |
| 4 | config/upload_config.php | 대 | 업로드 공통 보안 경계 강화 |
| 5 | editor.lib.php | 중 | 코드블럭 복원·저장 경로 보강, ID 이스케이프 |
| 6 | js/core.js | 소 | 필수 플러그인 로드 큐 정리 |
| 7 | plugin/code/code.js | 대 | 코드블럭 복원 및 Enter 입력 안정화 |
| 8 | plugin/file/file.js | 대 | 파일 플러그인 업로드 위임·복원·표시 안전화 |
| 9 | plugin/file/file_upload.php | 중 | uid 정제, 공통 검증 연계, JSON 응답 정리 |
| 10 | plugin/file/pdf_view.php | 중 | 경로 처리, 출력 이스케이프, 환경 호환성 |
| 11 | plugin/image/image.css | 중 | SafeAI/모달 UI 보강 |
| 12 | plugin/image/image.js | 대 | NSFW 진행 UI, 업로드 래퍼 추가, 모달 안정화 |
| 13 | plugin/image/image_upload.php | 대 | 이미지 업로드 보호 강화 |
| 14 | plugin/table/table.js | 소 | 붙여넣기 이벤트 속성 제거 |
| 15 | plugin/video/video.js | 중 | 비디오 업로드·응답 파싱·표시 안전화 |
| 16 | plugin/video/video_view.php | 중 | 허용 도메인 기반 외부 URL 처리, 경로 검증 |
| 17 | readme.txt | 소 | 버전 표기 변경 |
5. 실반영 확인 사항
5.1 업로드 공통 보안 경계 강화
config/upload_config.php는 9.1.2-alpha1.0.0에서 가장 큰 폭의 재정비가 이루어진 파일이다.
주요 반영 사항은 다음과 같다.
check_request_origin()공통화sanitize_original_name()공통화verify_file_magic_bytes()공통화validate_upload_file()의$tmp_path확장- 비디오 MIME 허용 범위 확장(
video/quicktime,video/x-m4v등) - mp4/m4v 계열 매직바이트 박스 타입 허용 범위 확장(
ftyp,mdat,moov,wide,free,skip,pdin,pnot) - POST/PUT/DELETE 계열 요청에 대해 빈 Origin 차단
T2EDITOR_MAX_IMAGE_PIXELS,T2EDITOR_STRICT_WEBP_CONVERSION도입
이 변경으로 업로드 엔드포인트 간 검증 로직 편차가 줄었으며, iOS/QuickTime 계열 비디오 false negative도 완화되었다.
5.2 설정 계층의 보안·구조 개선
config/t2_config.php에서는 다음 개선이 확인되었다.
HTTP_HOST형식 검증 추가realpath()기반 경로 계산으로 심볼릭 링크·Windows 구분자 대응 보강T2EDITOR_ALLOWED_URL_DOMAINS상수 도입t2editor_get_allowed_domains()공통 함수 도입t2editor_is_allowed_url()공통 함수 도입
이 구조는 이후 미디어 플러그인에서 허용 도메인 정책을 재사용할 수 있게 해 준다는 점에서 설계 일관성이 양호하다.
5.3 설정 조회 경로의 중복 정의 제거
config/get_upload_config.php에서는 다음 사항이 반영되었다.
check_request_origin()인라인 정의 제거upload_config.php포함 후 공통 함수 재사용- 설정 조회 요청에도 Origin 검증 적용
Content-Type: application/json; charset=utf-8정리
이는 동일 PHP 프로세스에서의 함수 중복 선언 위험을 제거하고, 설정 조회 경로를 공통 보안 정책 아래 두었다는 점에서 타당하다.
5.4 파일 업로드 엔드포인트 정비
plugin/file/file_upload.php에서는 다음 개선이 확인되었다.
- 출력 버퍼 정리 후 JSON 응답 일원화
- 잘못된 Origin 요청 차단
- uid를 업로드 차단 사유가 아닌 정제 대상 값으로 완화
- 원본 파일명에 대한 서버 측 정제
- 강화된
validate_upload_file()적용 - 저장 파일명 난수화
9.1.1 대비 가장 큰 차이는, uid 불일치가 업로드 전체 실패로 직결되던 구조가 완화되었다는 점이다.
5.5 이미지 업로드 보호 강화
plugin/image/image_upload.php에서는 다음 사항이 실제 반영되었다.
memory_limit=512M,max_execution_time=120적용- POST Origin 검증 적용
- uid 정제 로직 정비
- 블록 대상 확장자(
svg,ico) 명시적 차단 - 업로드 전후 2단계 검증(사전 확장자/크기, 사후 MIME/매직바이트)
- 랜덤 임시 파일명·랜덤 저장 파일명 사용
- 최대 픽셀 수 제한
- 엄격 WebP 변환 정책 반영
이는 이미지 업로드 경로를 파일 업로드 이상의 엄격한 보호 수준으로 끌어올린 조치로 평가된다.
5.6 비디오 업로드 및 재생 경로 복구
plugin/video/video.js, plugin/video/video_view.php의 조합에서는 다음 사항이 확인되었다.
generateUid()대신String(Date.now())사용response.json()대신text() → trim() → JSON.parse()사용- 업로드 미리보기 및 URL 수정 모달에 HTML 이스케이프 적용
uploadVideoFile(file)공개 API 추가video_view.php에서 same-domain 절대 URL 허용t2editor_is_allowed_url()기반 허용 도메인 제어- 상대 경로에 대한
realpath()기반 포함 검증 유지 - MIME 타입 확장(
mov,avi,mkv,wmv,flv,m4v)
이 변경으로 9.1.1에서 나타났던 “업로드는 되었으나 뷰어가 외부 URL로 오인하여 차단하는 문제”가 구조적으로 해소되었다.
5.7 파일 플러그인 전반 재정비
plugin/file/file.js는 기능·보안·복원성 측면에서 대규모 수정이 확인되었다.
반영 사항은 다음과 같다.
- 업로드 응답 파싱을
text() → trim() → JSON.parse()로 전환 - 문서/기타 업로드에서
Date.now()기반 uid 사용 handleImageUpload()가 이미지 플러그인 공개 API로 위임handleVideoUpload()가 비디오 플러그인 공개 API로 위임- 파일명/오디오 URL/다운로드 링크 출력 시 HTML 이스케이프 보강
- 파일 블럭에
data-t2-block="file"마킹 추가 insertElementAtCursor()에서 selection containment 검증 추가- 재로딩 시 파일 블럭 식별 전략 다중화
- 오디오 duration 복원 이벤트 재연결
- 삭제·이동 컨트롤 재생성 로직 보강
이는 단순 업로드 성공률 개선에 그치지 않고, 저장 후 재불러오기까지 포함한 파일 블럭 생명주기 전체를 정비한 변경으로 판단된다.
5.8 코드 블럭 및 에디터 복원성 보강
plugin/code/code.js, editor.lib.php에서는 다음 사항이 확인되었다.
- iOS Safari 계열에서 코드블럭 Enter를 두 번 눌러야 개행되던 문제 개선
- beforeinput + keydown 이중 처리 방식 도입
html_entity_decode()전후 코드블럭 텍스트 보존 처리 보강$idHTML 속성 이스케이프 및 JS 컨텍스트 분리- 저장 시
.t2-code-block code의textContent만 보존하도록 정리 - 저장 HTML에서 뷰 전용 속성 제거
해당 변경은 코드블럭의 구조 파괴, 줄바꿈 오동작, 저장 후 재복원 실패 가능성을 줄이는 방향으로 의미가 있다.
5.9 테이블 붙여넣기 경로 보강
plugin/table/table.js에서는 클립보드 HTML에서 복제한 테이블 요소에 대해 on* 이벤트 속성을 제거하는 로직이 추가되었다. 이는 이벤트 핸들러 기반 XSS 경로를 줄이는 보안 보강으로 평가된다.
5.10 UI/디자인·운영 안정성 개선
보안 외 부수적 반영 사항도 실제 존재한다.
config/nsfw_api_browser.js및plugin/image/image.js,plugin/image/image.css- NSFW 모델 로딩 진행률 표시
- 모달/버튼 정리 및 사용자 피드백 강화
js/core.js- 필수 플러그인 로드 완료 전
contentSetQueue를 소비하던 타이밍 보정 plugin/file/pdf_view.php- standalone/Gnuboard 겸용 include 구조 정리
- PDF 링크/worker 경로 출력 이스케이프
6. 문법 점검 및 테스트 결과
6.1 PHP 문법 검사
변경된 PHP 파일 전부에서 문법 오류가 확인되지 않았다.
config/get_upload_config.phpconfig/t2_config.phpconfig/upload_config.phpeditor.lib.phpplugin/file/file_upload.phpplugin/file/pdf_view.phpplugin/image/image_upload.phpplugin/video/video_view.php
6.2 JavaScript 문법 검사
변경된 JavaScript 파일 전부에서 구문 오류가 확인되지 않았다.
config/nsfw_api_browser.jsjs/core.jsplugin/code/code.jsplugin/file/file.jsplugin/image/image.jsplugin/table/table.jsplugin/video/video.js
6.3 스팟 테스트 결과
| 항목 | 결과 | 판정 |
|---|---|---|
t2editor_get_allowed_domains() 기본 동작 | 서버 도메인 자동 포함 확인 | 양호 |
t2editor_is_allowed_url() same-domain 절대 URL | 허용 확인 | 양호 |
t2editor_is_allowed_url() 비허용 외부 도메인 | 차단 확인 | 양호 |
check_request_origin() POST + 빈 Origin | 거부 확인 | 양호 |
check_request_origin() Origin 불일치 | 거부 확인 | 양호 |
validate_upload_file() mp4 시그니처 | 허용 확인 | 양호 |
validate_upload_file() 비정상 위장 파일 | 차단 확인 | 양호 |
7. 잔존 위험 및 미해소 사항
전수감사 결과, 9.1.2-alpha1.0.0은 9.1.1 대비 실질적인 개선이 확인되나, 다음과 같은 잔존 위험이 존재한다.
| 등급 | 파일 | 내용 | 감사 의견 |
|---|---|---|---|
| 높음 | editor.lib.php | hidden textarea 본문에 $content를 원문 그대로 출력(line 519, line 821) | </textarea> 포함 콘텐츠가 DOM 구조를 깨뜨릴 수 있으므로 htmlspecialchars(..., ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') 적용 필요 |
| 중간 | js/core.js | sanitizeHTML()가 href, src, style 속성을 허용하나 프로토콜·스타일 값 검증이 없음(line 2092-2138) | 커스텀 정화기 유지보다는 검증된 sanitizer 도입 권고 |
| 중간 | plugin/collab/collab_number_delete.php | Access-Control-Allow-Origin: * 유지 | 협업 엔드포인트는 same-origin 또는 allowlist 기반으로 축소 권고 |
| 낮음 | config/t2_config.php | 허용 도메인 함수의 IPv6 literal 처리 미흡 | explode(':', ...) 대신 IPv6-aware host 정규화 필요 |
| 낮음 | 일부 플러그인 | response.json() 직접 사용 경로 잔존 (image.js 설정 조회, draw.js, search.js 등) | 보안 결함은 아니나 경고/BOM 환경에서 파싱 취약 가능성 있음 |
상기 잔존 위험 중 editor.lib.php의 hidden textarea 원문 출력은 9.1.1에서 그대로 이어진 구조이며, 9.1.2-alpha1.0.0에서도 해결되지 않았다. 이 항목은 기능 문제를 넘어 저장 콘텐츠 기반 DOM 구조 파손 가능성과 연계되므로 우선순위를 높게 두어야 한다.
8. 종합 판정
8.1 판정
'''조건부 승인'''
8.2 판정 사유
- 9.1.1 대비 업로드 보안 경계, 허용 도메인 관리, 비디오 업로드/재생, 파일 블럭 복원, 코드블럭 입력 안정성은 실제로 유의미하게 개선되었다.
- 변경 파일 17개에 대한 검토 결과, 새로 도입된 구조 중 즉시 배포를 전면 중단해야 할 신규 치명 결함은 확인되지 않았다.
- 다만, hidden textarea 원문 출력과 수기 sanitizer 등 기존 계열 잔존 위험이 남아 있으므로 무조건 승인으로 보기는 어렵다.
8.3 권고
- '''외부 공개 배포 전 필수 보완'''
editor.lib.phphidden textarea 본문 이스케이프js/core.jssanitizer 재설계 또는 검증된 라이브러리 도입
- '''단기 보완 권고'''
- 협업 삭제 엔드포인트 CORS 축소
- IPv6 literal 호스트 처리 보강
- JSON 파싱 보조 헬퍼 공통화
9. 대외 공지 반영 가능 문안(내부 검토용)
외부 공지에는 다음 수준의 표현이 적절하다.
- 업로드 보안 및 처리 안정성 강화
- 파일·이미지·비디오 업로드 경로 정비
- 허용 도메인 기반 외부 URL 제어 기능 추가
- 파일 블럭 생성·복원 안정성 개선
- 코드블럭 줄바꿈 입력 안정성 개선
- SafeAI/NSFW 로딩 진행 UI 및 일부 편집 UI 개선
다만 내부 미해소 항목(editor.lib.php hidden textarea 원문 출력, 커스텀 sanitizer 한계 등)은 외부 공지의 홍보성 문구로 희석하지 말고 내부 릴리스 관리 항목으로 별도 추적하는 것이 바람직하다.
부록 A: 감사 수행 요약
- 전체 파일 69개 전수 대조
- 변경 파일 17개 수기 검토
- 변경 PHP 8개 문법 검사 통과
- 변경 JavaScript 7개 문법 검사 통과
- 허용 도메인, Origin, 업로드 검증 함수 스팟 테스트 수행