Skip to content

Wiki Security Review Notes

Won-Kyu Park edited this page Aug 8, 2026 · 2 revisions

Wiki 보안 리뷰 노트

이 문서는 현재 wiki.php 요청 경계에 대한 소스 리뷰 노트를 기록한다.

확인된 요청 경계 수정

관련 코드 branch에는 다음 경계에 대한 좁은 수정이 들어갔다.

  • upload file copy 전에 filename을 _safe_filename()으로 검사한다.
  • upload AJAX JSON 값은 _json_string()으로 escape한다.
  • redirect message link text는 출력 전에 escape한다.
  • session startup 조건은 더 이상 boolean을 문자열 Anonymous와 비교하지 않는다.
  • invalid session cleanup은 main $options 배열까지 전파된다.
  • same-host 검사는 redirect 계열 URL 비교 전에 HTTP_HOST를 정규화한다.
  • image alignment는 알려진 CSS class suffix만 출력한다.
  • minor edit line count는 eval() 없이 parsing한다.

이 수정들은 변경 범위를 요청 경계에 국한하면서 구체적인 sink를 제거한다.

요청 identity 순서

wiki.php는 session validation 전에 init_requests($options)를 호출한다. init_requests()WikiUser를 통해 MONI_ID를 읽고 사용자 정보를 load한 뒤 $options['id']를 쓴다.

이후 _session_start()는 invalid MONIWIKI session cookie를 감지하고 $DBInfo->user->id = 'Anonymous'로 설정할 수 있다. 기존 문제는 $options['id'] = 'Anonymous' 대입이 함수 내부에만 남아 caller가 원래 $optionswiki_main($options)로 넘긴다는 점이었다.

현재 수정 지점은 중앙화되어 있다. _session_start()$options를 reference로 받고, $DBInfo->user와 caller의 $options를 함께 무효화한다. 이로써 cache header, wiki_main(), plugin authorization이 같은 identity state를 사용한다.

대부분의 handler가 실행될 때는 authorization이 이미 $options['id']를 사용한 뒤이므로, 개별 plugin을 먼저 고치는 것보다 이 중앙 경계를 고치는 편이 낫다.

Host 정규화 메모

_normalize_http_host()는 host 비교와 cookie-domain fallback 전에 유효한 :port suffix를 제거한다. 이는 effective wiki host는 같지만 frontend나 개발용 port가 HTTP_HOST로 전달되는 proxy/localhost 사례를 위한 의도된 동작이다.

이 helper는 정규화한 host를 재사용하기 전에 control character, path separator, 잘못된 dot sequence를 거부한다.

남은 identity 경계

WikiUser::checkID()는 여러 punctuation 문자를 거부하지만 control character는 허용한다. 따라서 \r 또는 \n이 포함된 user ID가 setID()에서 받아들여질 수 있다.

이는 user ID가 다음 경로로 흐르기 때문에 경계 문제다.

  • UserPreferences link 같은 display link
  • log entry
  • sender/return address 구성을 통한 notification mail header

저비용 수정은 checkID()에서 ASCII control character를 거부하는 것이다. 이는 더 넓은 password/hash 현대화와 독립적으로 처리할 수 있다.

중앙 경계를 먼저 유지하는 이유

현재 코드는 legacy output과 plugin extension point가 많다. Raw link_tag() caller를 하나씩 고치는 작업은 main identity state가 신뢰 가능해진 뒤에야 효과가 크다.

권장 follow-up 순서는 다음과 같다.

  1. wikilib.php의 identity validation을 강화한다.
  2. 확인된 file/JSON 경계 수정을 유지한다.
  3. 정리된 중앙 identity model을 기준으로 high-risk action을 다시 리뷰한다.

이 순서는 산발적인 plugin patch보다 더 근본적이면서도 YAGNI에 맞다. Downstream check가 이미 사용하는 공유 경계를 바꾸기 때문이다.

Clone this wiki locally