🇰🇷 한글 설명
Memos의 webhook URL 검증 과정에서 0.0.0.0/8 대역을 예약된 IP 목록에서 누락하여 발생하는 보안 취약점입니다. 공격자가 0.0.0.0 주소를 사용하여 검증을 우회하면, 서버가 자신의 루프백 인터페이스로 HTTP 요청을 보내 내부 서비스에 접근할 수 있습니다.
💡 쉬운 설명
웹훅 주소를 확인할 때 특정 주소를 걸러내지 못하는 허점이 있습니다. 이를 통해 공격자가 서버 내부에서만 접속 가능한 비밀 서비스에 몰래 접근할 수 있습니다.
🇺🇸 원문 (English)
Memos' webhook URL validation, isReservedIP() (internal/webhook/validate.go), checks a candidate IP against a reservedCIDRs list that omits 0.0.0.0/8 and never calls ip.IsUnspecified() — unlike the correctly implemented sibling function isInternalIP() in internal/httpgetter/html_meta.go, which does. Because Linux redirects connections to 0.0.0.0 to loopback (127.0.0.1), an attacker registering a webhook URL of http://0.0.0.0:PORT/ bypasses the reserved-IP check and causes the Memos server to make outbound HTTP requests to its own loopback interface, exposing internal-only services.
📍 영향받는 시스템
Memos (webhook URL 검증 로직이 포함된 버전)
⚔️ 공격 벡터
공격자가 webhook URL로 http://0.0.0.0:PORT/ 형식을 등록하여 서버의 내부 루프백 서비스로 요청을 유도함
🛡️ 대응 방법
isReservedIP() 함수에 ip.IsUnspecified() 체크를 추가하여 0.0.0.0 대역을 차단하도록 패치 적용
🔧 검증 코드
0.0.0.0 주소를 webhook으로 등록했을 때 내부 서비스로 요청이 전달되는지 여부로 취약점 확인
curl -I http://localhost:PORT/ (Memos 서비스 포트 확인)