-
Notifications
You must be signed in to change notification settings - Fork 19
Wiki Security Review Notes
이 문서는 현재 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를 제거한다.
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가 원래 $options를 wiki_main($options)로 넘긴다는 점이었다.
현재 수정 지점은 중앙화되어 있다. _session_start()가 $options를 reference로 받고, $DBInfo->user와 caller의 $options를 함께 무효화한다. 이로써 cache header, wiki_main(), plugin authorization이 같은 identity state를 사용한다.
대부분의 handler가 실행될 때는 authorization이 이미 $options['id']를 사용한 뒤이므로, 개별 plugin을 먼저 고치는 것보다 이 중앙 경계를 고치는 편이 낫다.
_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를 거부한다.
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 순서는 다음과 같다.
-
wikilib.php의 identity validation을 강화한다. - 확인된 file/JSON 경계 수정을 유지한다.
- 정리된 중앙 identity model을 기준으로 high-risk action을 다시 리뷰한다.
이 순서는 산발적인 plugin patch보다 더 근본적이면서도 YAGNI에 맞다. Downstream check가 이미 사용하는 공유 경계를 바꾸기 때문이다.