
WPManageNinja의 FluentCRM에서 패치되지 않은 취약점에 대한 책임 있는 공개
업데이트 2023-06-12: 더 이상 스니펫이 필요하지 않습니다. WPManageNinja는 공개 공개 후 2시간 만에 취약점을 패치했습니다(신고 후 93일).
업데이트 2024-01-27: 영원한 해시 값과 관련된 문제가 이제 완전히 해결되었습니다.
tl;dr 공격자가 FluentCRM에서 연락처 세부 정보를 보고 편집할 수 있습니다. WPManageNinja는 90일 책임 공개 기간 내에 취약점을 패치하지 않았습니다. 공식 패치를 기다리는 동안 취약점 악용을 방지하기 위한 완화 스니펫을 제공합니다.
오늘, WPManageNinja의 인기 WordPress 플러그인 FluentCRM에서 발견한 취약점에 대한 정보를 공개합니다. 취약점 CVE-2023-1430은 FluentCRM이 이메일 주소 해시를 권한 부여 제어로 부적절하게 사용하여 발생합니다. Google Zero의 취약점 공개 정책에 따라 책임 있게 공개했습니다. WPManageNinja는 90일 이내에 패치를 제공하지 않았으며 기한 연장을 요청하지도 않았습니다.
이 보고서에서 _contact_는 FluentCRM 접촉 객체를, _user_는 WordPress 사용자 객체를 의미합니다. 접촉은 사용자와 연결될 수 있지만 필수는 아닙니다. 취약점 악용에 대한 세부 정보는 공식 패치가 제공될 때까지 보류됩니다. 보안 전문가는 전체 보고서를 위해 저에게 연락할 수 있습니다 ([email protected]).
FluentCRM이 실행 중인 사이트에서 공격자는 연락처의 이메일 주소를 알면 이름, 이메일 주소, 목록 설정을 보고 편집할 수 있습니다. 연락처 이름은 종종 뉴스레터에 병합 태그로 포함되므로, 공격자는 연락처 이름을 욕설로 바꿔 웹사이트 소유자가 저속한 뉴스레터를 보내도록 할 수 있습니다. 웹사이트 관리자가 FluentCRM의 환경 설정 관리 단축 코드를 활성화하고 공개 웹 페이지에 추가한 경우, 공격자는 노출된 모든 개인 정보(제목, 전화번호, 생년월일, 주소 등, FluentCRM 구성에 따라 다름)를 보고 편집할 수 있습니다.
FluentCRM은 30,000개 이상의 사이트에 설치되어 있습니다. FluentCRM 사이트 관리자는 자식 테마의 functions.php 파일에 제 완화 스니펫을 추가하여 취약점 악용을 방지할 수 있습니다.
스니펫은 취약점을 패치하지 않습니다. FluentCRM의 구독 취소 페이지(unsubscribe.php)와 환경 설정 관리 페이지(manage_subscription.php)의 취약한 콘텐츠를 오류 메시지로 대체하여 연락처가 대신 이메일로 문의하도록 안내합니다. 오류 메시지의 이메일 주소는 사이트 관리자 이메일 주소입니다(스니펫에서 변경 가능). 완화 스니펫은 또한 로그인하지 않은 방문자가 FluentCRM의 취약한 환경 설정 관리 단축 코드(fluentcrm_pref)를 렌더링하지 못하도록 합니다. 로그인하지 않은 방문자는 대신 로그인하라는 오류 메시지를 보게 됩니다. 모든 문자열은 제공된 POT 파일로 번역 가능합니다.
웹사이트 소유자에게 제가 제공하는 완화 조치 또는 자체 완화 조치를 구현할 것을 권장합니다. 웹사이트 소유자는 FluentCRM 연락처 데이터의 무결성을 확인하고, 가능하다면 로그에서 잠재적인 데이터 유출을 확인해야 합니다. 특히 다음 사이트의 경우 로그 확인이 중요합니다:
웹사이트의 지정된 데이터 컨트롤러는 해당 관할권의 법률 및 규정에 따라 개인 정보의 잠재적 데이터 유출을 처리해야 합니다.
FluentCRM이 연락처 설정을 해당 사용자와 동기화하도록 구성된 경우, 공격자는 사용자 이름을 변경할 수 있습니다. 다행히 FluentCRM은 연락처에서 사용자로 이메일 주소를 동기화하지 않습니다. 만약 그랬다면 이 취약점으로 인해 전체 사이트가 장악될 수 있었을 것입니다. 공격자는 사이트 관리자의 이메일 주소를 변경한 다음 관리자 비밀번호를 재설정하여 권한 있는 접근을 얻을 수 있었을 것입니다.
그러나 다른 솔루션(예: WP Fusion 및 FluentCRM의 API)은 연락처에서 사용자로 모든 메타데이터를 동기화할 수 있습니다. WP Fusion은 아마도 CRM(예: FluentCRM)과 WordPress 간에 연락처 메타데이터를 동기화하는 가장 인기 있는 타사 플러그인일 것입니다. 다행히 현재 버전의 WP Fusion은 취약한 양식에서 시작된 메타데이터 변경에 연결되어 있지 않습니다. WP Fusion 개발자에게 알렸으며, WPManageNinja가 취약점을 패치할 때까지 이 제한 사항을 해결하지 않을 것입니다.
FluentCRM의 API를 사용하여 연락처 및 사용자 데이터를 업데이트할 수도 있습니다. FluentCRM의 API를 사용하여 사용자 이메일 주소를 업데이트하는 사이트 소유자는 FluentCRM의 페이지 또는 환경 설정 관리 단축 코드에서 시작된 업데이트를 비활성화해야 합니다(또는 취약한 양식에서 설정을 업데이트할 수 없도록 제 완화 스니펫을 추가).
FluentCRM은 공개 웹 페이지에서 연락처가 구독을 취소하고 환경 설정을 관리할 수 있도록 합니다. 이 페이지에 대한 링크는 모든 뉴스레터에 포함됩니다. 이 페이지에서 이루어진 변경 사항은 URL 매개변수로 전달되는 연락처 이메일 주소의 MD5 해시로 승인됩니다. 이메일 주소의 MD5 해시는 비밀이 아니며 누구나 계산할 수 있습니다. 공격자는 해시의 잘못된 사용을 악용하여 특정 연락처를 구독 취소하거나 알려진 이메일 주소를 가진 연락처를 대량으로 구독 취소할 수 있습니다.
구독 취소 페이지는 전적으로 MD5 해시에 의존하는 반면, 환경 설정 관리 페이지는 ce_id라는 추가 URL 매개변수가 필요합니다. 이 경우 ce_id는 fc_subscribers 테이블에 있는 연락처의 ID를 나타냅니다. 이 ID는 증가하는 정수입니다. 따라서 ce_id 값은 가능한 모든 값을 테스트하여 쉽게 찾을 수 있습니다(검색 공간은 사이트에 등록된 연락처 수입니다). 관리자 사용자는 낮은 값을 가질 가능성이 높습니다.
환경 설정 관리 페이지에서 공격자는 연락처의 secure_hash 값도 유출할 수 있습니다. 연락처의 이메일 주소를 업데이트하면 연락처의 "secure_hash" 값이 fc_hash_secure라는 쿠키에 저장됩니다. 이 쿠키가 설정되면 공격자는 FluentCRM의 환경 설정 양식 단축 코드에서 제공하는 모든 연락처 정보를 표시할 수 있습니다.
앞서 언급한 "secure_hash"는 FluentCRM이 (일부 상황에서) MD5 이메일 주소 해시 대신 또는 대안으로 의존하는 값입니다. FluentCRM 2.8.0 릴리스 이후 구독 취소 페이지는 전적으로 secure_hash 값에 의존하여 승인합니다. 환경 설정 관리 페이지는 새 secure_hash 값과 이전 MD5 이메일 주소 해시를 모두 승인에 허용합니다.
secure_hash 값은 이메일 주소에서 파생될 수 없지만, FluentCRM의 사용 방식은 좋은 보안 관행을 따르지 않습니다. secure_hash 값은 연락처당 한 번 생성됩니다. 절대 업데이트되지 않으며 만료되지 않습니다. 이는 secure_hash 값이 모든 뉴스레터에 포함되기 때문에 문제가 됩니다. 공격자가 연락처의 받은 편지함에 접근할 수 있다면, 공격자는 연락처의 설정을 무기한 변경할 수 있습니다. 영향을 받는 연락처가 관리자 권한이 있는 사용자와 연결되어 있고 이메일 주소 변경이 FluentCRM에서 WordPress로 동기화된다면, 이 연락처에 전송되는 모든 뉴스레터에는 사이트를 장악할 수 있는 만료되지 않는 토큰이 포함됩니다.
이 관련 문제를 2023-03-15에 WPManageNinja에 보고했습니다. 두 달 후(2023-05-15), WPManageNinja는 보안 자문가들이 정적 secure_hash 값을 문제로 간주하지 않는다고 답변했습니다. WPManageNinja의 보안 자문가들은 "연락처를 식별하기 위해 이 유형의 일회성 생성 토큰을 사용하는 것이 괜찮다"며 "SaaS 서비스의 API 토큰과 유사하며, 이는 다른 연락처에 전달되지 않고 실제 이메일 주소 소유자에게만 전송된다"고 말했습니다.
WPManageNinja는 열린 태도를 보였으며, 여전히 보안 문제라고 생각되면 알려달라고 했고, 저는 그렇게 했습니다. secure_hash 값을 API 토큰과 비교할 수 없는 이유를 설명했습니다. (API 토큰은 TLS 연결을 통해서만 전송되도록 할 수 있으며, API 토큰에 대한 접근을 제한할 수 있습니다. 이메일의 일반 텍스트 값의 경우 그렇지 않습니다. 가장 중요한 것은 API 토큰은 취소할 수 있지만, 연락처가 secure_hash 값을 취소할 방법이 없다는 점입니다.)
같은 날 WPManageNinja는 감사를 표하며 이메일 레코드 ID를 해시와 결합하는 것을 고려하겠다고 말했습니다. 이는 이전(시간 기반 만료) 또는 이전(카운터 기반 만료) secure_hash 값의 자동 취소와 함께 구현된다면 문제를 해결할 것입니다. 이 기능은 아직 구현되지 않았지만, 정적 해시 값을 이 CVE의 일부로 간주하지 않습니다.
2023년 1분기에 이전 뉴스레터 도구(Sendy)에서 FluentCRM으로 마이그레이션을 시작했습니다. FluentCRM을 Nikka Systems Academy (Project Opal)와 통합하는 과정에서 취약점을 발견했습니다. FluentCRM의 구독 관리 시스템을 자체 플러그인으로 대체했기 때문에 FluentCRM의 취약한 양식은 당사 사이트나 고객 데이터에 영향을 미치지 않았습니다.
FluentCRM은 훌륭한 플러그인이지만, WPManageNinja의 취약점 공개 처리에는 개선의 여지가 많습니다. 다음 목록은 WPManageNinja가 상황을 개선할 수 있는 방법에 대한 제 제안입니다.
그렇긴 하지만, 저는 여전히 WPManageNinja를 신뢰합니다. 모든 소프트웨어에는 버그가 있으며, 단 한 번의 부실한 취약점 보고 처리가 그들의 플러그인 사용을 중단할 이유는 아닙니다.
업데이트 2023-06-12: 그들이 여전히 변경 로그에서 취약점을 숨기려고 한 사실이 진심으로 걱정됩니다. (이제 CVE를 추가했습니다.)