
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 | High: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Product | Vaultwarden |
| Affected | 1.37.3 (eb212e23). Image vaultwarden/server:1.37.3. Docker published-port / userland-proxy / Desktop NAT, या कोई भी RFC1918 पीयर। |
| Auth | unauthenticated |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1 |
हमलावर IP-कुंजीबद्ध ब्रूट-फोर्स सुरक्षा को हटा देता है। वे हर प्रयास पर एक नया X-Real-IP भेजते हैं। गवर्नर एक DashMap है जो उस पते पर कुंजीबद्ध है, इसलिए बर्स्ट और अवधि कभी ट्रिगर नहीं होते।
POST /identity/connect/token पासवर्ड-ग्रांट। डिफ़ॉल्ट बर्स्ट प्रति IP प्रति 60 सेकंड में 10 है। अद्वितीय हेडर बकेट को रीसेट कर देते हैं।/api/two-factor/send-email-login, POST /admin, साथ ही unauth hint / prelogin / delete-recover / auth-request / Send access सभी 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 GHSAs के बाद 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 LIMITER_LOGIN को उस IpAddr पर कुंजीबद्ध करता है। Docker ब्रिज, Desktop VM NAT, और लूपबैक सभी गैर-ग्लोबल हैं।
मैंने लूपबैक 127.0.0.1:18170:80 पर स्टॉक vaultwarden/server:1.37.3 को बिना ओवरराइट-प्रॉक्सी के खड़ा किया, साथ ही 18171 पर IP_HEADER=none के साथ एक दूसरा इंस्टेंस। [email protected] रजिस्टर किया। गलत पासवर्ड और बिना हेडर के पासवर्ड-ग्रांट अनुरोध 11 पर 429 हो गया (बर्स्ट 10)। प्रत्येक प्रयास पर अद्वितीय X-Real-IP: 198.51.100.{n} के साथ वही ग्रांट चौदह बार HTTP 400 पर रहा, शून्य 429। 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 पर सेट करें। local को "कोई भी RFC1918 पीयर" मानना पब्लिश्ड-पोर्ट मामला है। फ़ॉरवर्डिंग हेडर का होना प्रॉक्सी का प्रमाण नहीं है।
src/config.rs (ip_header, ip_header_trusted_proxies)src/auth.rs (ip_header_is_trusted, ClientIp)src/ratelimit.rs