
PoC: changedetection.io 설정 블라인드 병합 대량 할당 (CVE-2026-71204, 중간 6.3)
제품: dgtlmoon/changedetection.io — v0.55.7
파일: changedetectionio/blueprint/settings/__init__.py, changedetectionio/forms.py
CWE: CWE-284 — 부적절한 접근 제어
CVSS 3.1: AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:L — 6.3 (중간)
CNA: Turan Security · CVE 레코드
changedetection.io의 /settings 저장 핸들러는 form.data['application']에서 업데이트 dict를 구성하고 이를 .update()를 통해 저장된 애플리케이션 설정에 블라인드 병합합니다. HTML 체크박스는 체크된 경우에만 제출된 폼 데이터에 나타나므로, 보안 관련 체크박스 필드(예: API 키 요구를 강제하는 필드)를 단순히 생략한 조작된 POST는 핸들러 수준에서 사용자가 UI에서 체크를 해제한 것과 구별할 수 없습니다. 즉, 블라인드 .update()가 해당 설정을 조용히 꺼버립니다.
api_access_token_enabled(또는 이와 동등한 값)를 명시적으로 false로 설정하지 않는 요청 — 그저 POST 본문에서 해당 필드를 빼버리는 것 — 은 해당 보호 기능이 사실상 비활성화된 채로 애플리케이션 설정이 병합되게 합니다. "사용자가 체크를 해제함"과 "필드가 전송되지 않음"을 구분하는 명시적 확인 단계나 감사 신호 없이 말입니다.
/settings 페이지에 정상적으로 인증합니다.api_access_token_enabled 필드(또는 테스트 중인 보호 관련 불리언 설정)를 본문에서 완전히 생략한 POST를 /settings에 제출합니다:
POST /settings HTTP/1.1
Content-Type: application/x-www-form-urlencoded
application-some_other_field=value
form.data['application'] → .update() 병합은 누락된 필드를 명시적 "off"와 동일하게 취급하므로, 사용자(또는 요청을 검토하는 감사자)가 명시적인 해제 신호를 보지 못한 채 보호 기능을 조용히 비활성화합니다.원시 폼 데이터에 대한 블라인드 dict .update() 사용은 체크박스 기반 설정에서 "POST에 필드가 없음"과 "필드가 명시적으로 false로 설정됨"을 동일하게 취급합니다. HTML 폼은 체크 해제된 체크박스를 절대 제출하지 않으므로, 이 패턴은 보안 영향이 있는 모든 설정 필드에 대해 안전하지 않습니다.
예상되는 불리언 설정 필드를 명시적으로 열거하고 누락된 필드는 현재 저장된 값(False가 아닌)으로 기본 설정하거나, "제출되지 않음"과 "체크 해제된 상태로 제출됨"을 구분하고 보안 관련 토글을 블라인드 dict 병합이 아닌 명시적으로 검증하는 폼 라이브러리를 사용하십시오.