
Vaultwarden 1.37.3 기본 X-Real-IP trusted-local은 Docker NAT에서 로그인 속도 제한을 우회합니다
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vaultwarden-ip-header-spoof
Vaultwarden 1.37.3 - dani-garcia
기본값 IP_HEADER=X-Real-IP와 IP_HEADER_TRUSTED_PROXIES=local은 전역이 아닌 모든 TCP 피어를 리버스 프록시로 취급합니다. 기본 Docker 게시 포트 NAT는 RFC1918입니다. 클라이언트가 제공한 X-Real-IP가 속도 제한 키가 됩니다. 고유한 값은 버스트를 공유하지 않습니다.
| ID | 아직 CVE 없음 |
| CWE | CWE-307 / CWE-290 |
| CVSS | 높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| 제품 | Vaultwarden |
| 영향받는 버전 | 1.37.3 (eb212e23). 이미지 vaultwarden/server:1.37.3. Docker 게시 포트 / userland-proxy / Desktop NAT, 또는 모든 RFC1918 피어. |
| 인증 | 인증 불필요 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
공격자는 IP 기반 무차별 대입 보호를 제거합니다. 매 시도마다 새로운 X-Real-IP를 보냅니다. 거버너는 해당 주소를 키로 하는 DashMap이므로 버스트와 기간이 절대 걸리지 않습니다.
POST /identity/connect/token 비밀번호 그랜트. 기본 버스트는 IP당 60초에 10회입니다. 고유한 헤더는 버킷을 초기화합니다./api/two-factor/send-email-login, POST /admin, 그리고 인증 없는 hint / prelogin / delete-recover / auth-request / Send 접근 모두 ClientIp를 키로 사용합니다.docker run -p 80:80과 compose 80:80은 피어를 브리지 또는 Desktop NAT 주소로 만듭니다. trusted=local은 !is_global(peer)입니다. 이는 일치합니다.X-Real-IP를 실제 클라이언트로 교체하는 리버스 프록시와 피어가 전역 주소인 호스트 바인딩은 모두 거버너를 정직하게 유지합니다. 취약점은 기본값과 덮어쓰기 없는 게시 포트의 조합입니다.
1.35.x / 1.36.0 / 1.37.0 GHSA 이후 dani-garcia/vaultwarden 1.37.3 (eb212e23)을 고정했습니다. GHSA-c5rv는 send-email-login을 LIMITER_LOGIN에 올렸습니다. 남은 것은 ClientIp가 선택되는 방식입니다.
config.rs는 ip_header를 X-Real-IP로, ip_header_trusted_proxies를 local로 기본 설정합니다. auth.rs의 ip_header_is_trusted는 local을 !is_global(remote)로 취급합니다. ratelimit.rs는 해당 IpAddr를 키로 LIMITER_LOGIN을 설정합니다. Docker 브리지, Desktop VM NAT, 루프백은 모두 비전역입니다.
덮어쓰기 프록시 없이 루프백 127.0.0.1:18170:80에 기본 vaultwarden/server:1.37.3을 세우고, IP_HEADER=none으로 18171에 두 번째 인스턴스를 세웠습니다. [email protected]를 등록했습니다. 잘못된 비밀번호와 헤더 없음으로 비밀번호 그랜트를 하면 요청 11에서 429가 발생했습니다(버스트 10). 매 시도마다 고유한 X-Real-IP: 198.51.100.{n}을 사용한 동일한 그랜트는 14번 HTTP 400을 유지했고 429는 0회였습니다. none 인스턴스에서는 고유한 203.0.113.{n}도 11에서 429가 발생했습니다.
SUCCESS VAULTWARDEN-IP-HEADER-SPOOF nohdr-429-at=11 spoof-400=14 spoof-429=0 none-429-at=11 VAULTWARDEN-IP-HEADER-SPOOF-WITNESS
이미 기록된 잘못된 시도: 1.37.3 이미지가 로컬에 없어서 첫 compose가 풀을 기다렸습니다. 첫 /alive는 Rocket이 바인딩하는 동안 빈 응답이었고, 대기 2에서 200이었습니다. 더미 등록 JSON(masterPasswordHash + 짧은 key)으로 충분했고, 긴 키 재시도는 없었습니다. 리버스 셸. 연극. 오라클은 헤더 없이 429, 고유 헤더로 400입니다.
cd lab
./run.sh
오직 http://127.0.0.1:18170(기본)과 http://127.0.0.1:18171(IP_HEADER=none)만 대상으로 합니다. 이미지 vaultwarden/server:1.37.3.
IP_HEADER를 none으로 기본 설정하거나, IP_HEADER_TRUSTED_PROXIES를 빈 목록 / 명시적 프록시 CIDR로 기본 설정합니다. "모든 RFC1918 피어"로서의 local이 게시 포트 사례입니다. 포워딩 헤더의 존재는 프록시의 증거가 아닙니다.
src/config.rs (ip_header, ip_header_trusted_proxies)src/auth.rs (ip_header_is_trusted, ClientIp)src/ratelimit.rs