Asosiy matnga o'tish
Blog

Veb

Host header injection: oddiy ko'rinadigan, lekin jiddiy zaiflik

Ilova Host yoki X-Forwarded-Host headeriga ishonsa, parol tiklash havolalari begona domenga yo'naltirilishi mumkin. Real holat, tekshirish usuli va Laravel hamda nginx'da tuzatish.

· 7 daq. o'qish

Foto: Dietmar Rabich, CC BY-SA 4.0 · Wikimedia Commons

Host header injection — ko'p dasturchilar e'tibor bermaydigan zaiflik. Kodda SQL yoki XSS kabi ko'zga tashlanadigan xato yo'q, hamma narsa odatdagidek ishlaydi. Lekin ilova so'rovdagi Host yoki X-Forwarded-Host headeriga ko'r-ko'rona ishonsa, hujumchi ilova yaratadigan havolalarni o'z domeniga yo'naltira oladi.

Bu zaiflik o'z mahsulotimiz — soliq-moliya SaaS platformasi — ekspertizasida topilgan edi. Quyida u qanday ishlashi, qanday tekshirilishi va qanday yopilganini ko'rsatamiz.

Muammo qayerdan kelib chiqadi

Ilovalar ko'pincha to'liq (absolyut) URL yasaydi: email'dagi havolalar, redirect'lar, canonical teglar, fayl manzillari. Buning uchun ular joriy so'rovdan domen nomini oladi. Framework domenni Host headeridan, ilova proksi orqasida bo'lsa esa X-Forwarded-Host headeridan o'qiydi.

Muammo shundaki, bu headerlarni mijoz o'zi yuboradi. Agar ilova "proksi qo'shgan bo'lsa kerak" deb X-Forwarded-Host ga ishonsa, istalgan odam o'zi xohlagan domenni ko'rsata oladi.

Real holat: parol tiklash havolasi

Bizning holatda ilova barcha X-Forwarded-* headerlariga ishonib qolgan edi. Hujum ssenariysi quyidagicha ko'rinadi:

  1. Hujumchi parolni tiklash formasiga qurbonning email manzilini kiritadi.
  2. So'rovga X-Forwarded-Host: attacker.example headerini qo'shadi.
  3. Ilova tiklash havolasini shu domen bilan yasaydi: https://attacker.example/reset-password/<token>.
  4. Qurbon haqiqiy saytdan kelgan haqiqiy xatni oladi. Havolani bossa, maxfiy token hujumchi serveriga boradi.
  5. Hujumchi token bilan haqiqiy saytda parolni almashtiradi.

Xat rasmiy manzildan keladi, matn to'g'ri, faqat havoladagi domen boshqa. Shuning uchun bu zaiflik jiddiy hisoblanadi.

Boshqa oqibatlar ham bo'lishi mumkin: keshlanadigan sahifalarda begona domen havolalari bo'lib qolishi (cache poisoning), redirect'larning begona saytga yo'naltirilishi.

Nima uchun bu zaiflik uzoq vaqt sezilmay qoladi? Chunki odatiy foydalanishda Host har doim to'g'ri keladi va testlarda ham hamma narsa ishlaydi. Muammo faqat kimdir headerni ataylab o'zgartirganda ko'rinadi. Proksi orqasidagi ilovalarda esa dasturchilar ko'pincha "hammasiga ishon" sozlamasini sayt to'g'ri ishlashi uchun qo'yib qo'yadi va keyin unutadi.

Mijoz yuborgan har qanday header — foydalanuvchi kiritgan ma'lumot. Host ham bundan mustasno emas.

Qanday tekshirish mumkin

Eng oddiy tekshiruv — begona domen bilan so'rov yuborib, u javobda paydo bo'ladimi, ko'rish:

curl -si https://your-domain.uz/login \
  -H "X-Forwarded-Host: attacker.example" | grep -i attacker

curl -si https://your-domain.uz/login \
  -H "Host: attacker.example" | grep -i attacker

Shuningdek:

  • Parolni tiklash formasini X-Forwarded-Host bilan yuboring va kelgan xatdagi havolani tekshiring (o'zingizning test akkauntingizda).
  • Location headerli redirect javoblarini ko'ring.
  • X-Forwarded-Server, X-Host, Forwarded kabi muqobil headerlarni ham sinab ko'ring.

Agar javobda yoki xatda attacker.example chiqsa, zaiflik bor.

Laravel'da tuzatish

1. Proksiga ishonchni cheklang

Laravel TrustProxies middleware'i qaysi proksilarga va qaysi headerlarga ishonishni belgilaydi. Bizda muammo shu yerda edi: barcha headerlarga ishonilgan. Tuzatish — faqat X-Forwarded-For, Proto va Port ga ishonish, X-Forwarded-Host ni esa e'tiborsiz qoldirish.

Laravel 11+ da bootstrap/app.php:

use Illuminate\Http\Request;

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(
        at: ['127.0.0.1'],
        headers: Request::HEADER_X_FORWARDED_FOR
            | Request::HEADER_X_FORWARDED_PORT
            | Request::HEADER_X_FORWARDED_PROTO
    );
})

at ga faqat haqiqiy proksi manzilini yozing, '*' emas.

2. Production'da root URL'ni majburlang

Havolalar so'rovdan emas, konfiguratsiyadan yasalishi uchun AppServiceProvider::boot() ga qo'shing:

use Illuminate\Support\Facades\URL;

if ($this->app->isProduction()) {
    URL::forceRootUrl(config('app.url'));
    URL::forceScheme('https');
}

.env dagi APP_URL to'g'ri domen bilan to'ldirilgan bo'lishi shart.

3. Ruxsat etilgan hostlar

Qo'shimcha qatlam sifatida TrustHosts middleware'ini yoqing — u faqat ruxsat etilgan domenlardan kelgan so'rovlarni qabul qiladi:

$middleware->trustHosts(at: ['your-domain.uz']);

nginx'da tuzatish

Ilova darajasidagi himoya bilan birga veb-server ham begona Host bilan kelgan so'rovlarni ilovaga yetkazmasligi kerak.

default_server

nginx so'rovni server_name bo'yicha mos server blokiga yuboradi. Mos blok topilmasa, so'rov default_server ga tushadi — agar u belgilanmagan bo'lsa, birinchi blokka, ya'ni ko'pincha asosiy saytingizga. Shuning uchun alohida "tutib qoluvchi" blok qo'shing:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_reject_handshake on;
    return 444;
}

server {
    listen 443 ssl;
    server_name your-domain.uz;
    # ... asosiy sayt
}

return 444 ulanishni javobsiz yopadi, ssl_reject_handshake (nginx 1.19.4+) esa noma'lum domen uchun TLS ulanishni rad etadi.

Proksiga uzatiladigan headerlar

Agar nginx ilovaga proksi qilsa, mijoz yuborgan X-Forwarded-Host ni o'tkazib yubormang va Host ni server qiymati bilan yuboring:

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host "";

Tuzatishdan keyin

Yuqoridagi curl buyruqlarini qayta ishga tushiring: begona Host bilan so'rov nginx tomonidan rad etilishi, X-Forwarded-Host esa havolalarga hech qanday ta'sir qilmasligi kerak. Parol tiklash xatini ham qayta tekshiring.

Xulosa

Host header injection kodda ko'rinmaydi — u ishonch sozlamalarida yashaydi. Tuzatish qisqa: proksiga ishonchni cheklash, root URL'ni majburlash va nginx'da default_server qo'shish. Lekin buni oldindan bilish va tekshirish kerak.

Saytingiz begona headerlarga ishonmayotganini tekshirmoqchimisiz? Skanerlash uchun so'rov qoldiring — Claude AI agenti va mutaxassisimiz konfiguratsiyangizni ko'rib chiqib, topilgan teshiklarni yopishga yordam beramiz.