Asosiy matnga o'tish
Blog

Veb

SSTI: server-side shablon in'ektsiyasi (Twig/Blade)

Foydalanuvchi matni to'g'ridan-to'g'ri shablon mexanizmiga uzatilsa, u oddiy matn o'rniga kod sifatida bajarilishi mumkin. SSTI qanday paydo bo'ladi, qanday tekshiriladi va Twig/Blade'da qanday oldini olinadi.

· 6 daq. o'qish

Foto: Dinkun Chen, CC BY-SA 4.0 · Wikimedia Commons

SQL injection haqida deyarli har bir dasturchi eshitgan, lekin shablon in'ektsiyasi (SSTI — Server-Side Template Injection) kamroq tanilgan, garchi oqibati xuddi shunday og'ir bo'lishi mumkin: hujumchi serverda o'z kodini bajarishi (RCE).

Muammo qayerdan kelib chiqadi

Twig, Blade, Jinja2, FreeMarker kabi shablon mexanizmlari ikki narsani bajaradi: statik matnni chiqaradi va {{ }} ichidagi ifodalarni hisoblaydi. Agar ilova foydalanuvchi kiritgan matnni to'g'ridan-to'g'ri shablon manbai sifatida qayta ishlasa, hujumchi oddiy matn o'rniga shablon sintaksisini yuboradi va mexanizm uni kod sifatida bajaradi.

Oddiy misol — xabar matnini shunday yasash:

$template = "Salom, " . $request->name . "!";
return Blade::render($template);

Bu yerda foydalanuvchi matni shablonning o'zi sifatida qayta render qilinadi. Agar name o'rniga {{ phpinfo() }} yoki {{ system('id') }} yuborilsa, Blade buni ifoda deb hisoblab bajaradi. Xuddi shu xato Twig'da ham uchraydi: foydalanuvchi matnini $twig->createTemplate($userInput)->render() orqali o'tkazish — klassik SSTI eshigi. Taqqoslash uchun: oddiy view('welcome', ['name' => $request->name]) chaqiruvi xavfsiz, chunki name bu yerda faqat qiymat, shablon emas.

Nega bu RCE'ga olib keladi

Oddiy shablon ifodasi matematik amal yoki o'zgaruvchiga murojaat bo'lishi mumkin, lekin ko'pchilik shablon mexanizmlari ob'ekt metodlarini chaqirishga ham ruxsat beradi. Twig va Blade'da PHP'ning o'zi ishlaydi, shuning uchun to'g'ri payload bilan fayl tizimiga, muhit o'zgaruvchilariga yoki hatto buyruq bajarish funksiyalariga yetib borish mumkin. Natijada SSTI ko'pincha to'liq server nazoratiga aylanadi — in'ektsiya toifasidagi eng og'ir ko'rinishlardan biri.

Shablon mexanizmi — bu kichik dasturlash tili. Unga foydalanuvchi matnini "shablon" sifatida bermang, faqat "ma'lumot" sifatida bering.

Qanday tekshirish mumkin

Eng oddiy usul — matematik ifoda yuborish va natijani kutish:

name=${7*7}
name={{7*7}}
name=#{7*7}
name=<%= 7*7 %>

Agar javobda matn o'rniga 49 chiqsa, demak kiritilgan qiymat shablon sifatida bajarilgan. Qaysi sintaksis ishlashi mexanizmni aniqlashga yordam beradi: {{ }} — Twig/Jinja2/Blade uslubi, ${ } — FreeMarker/Velocity, <%= %> — ERB.

Forma maydonlari, email shablonlari, PDF generatorlari, bildirishnoma matnlari — foydalanuvchi matni "shablon" sifatida ishlatilishi mumkin bo'lgan barcha joylarni ro'yxatlang va har biriga shu probani yuboring:

curl -s https://your-domain.uz/contact \
  --data-urlencode "message={{7*7}}" | grep -o "49"

Qanday tuzatish kerak

1. Foydalanuvchi matnini shablon sifatida hech qachon render qilmang

Eng ishonchli tuzatish — foydalanuvchi kiritgan matnni shablon manbai sifatida umuman ishlatmaslik. Shablonlar faqat dasturchi yozgan, versiya nazoratida saqlanadigan fayllar bo'lsin; foydalanuvchi ma'lumoti faqat o'zgaruvchi qiymati sifatida uzatilsin:

// Xavfli: foydalanuvchi matni shablon manbai
return Blade::render($request->input('template'), $data);

// To'g'ri: foydalanuvchi matni faqat qiymat
return view('messages.welcome', ['name' => $request->input('name')]);

2. Agar dinamik shablon kerak bo'lsa — sandbox

Ba'zan biznes talabiga ko'ra foydalanuvchiga o'z shablonini yozish imkoni berish kerak (masalan, email konstruktori). Bu holda Twig'ning SandboxExtension'idan foydalaning — u ruxsat etilmagan funksiya va metodlarni chaqirishni bloklaydi. Blade'da bunga o'xshash tayyor sandbox yo'q, shuning uchun foydalanuvchi shablonini Blade orqali render qilishdan saqlaning; o'rniga cheklangan o'zgaruvchi almashtirish (masalan, {{ ism }} kabi oddiy placeholder'larni qo'lda almashtirish) ishlatilsin.

3. Chiqishni escaping bilan birga qo'llang

SSTI va XSS yondosh muammolar: shablon in'ektsiyasini yopgandan keyin ham chiqish to'g'ri escape qilinishi kerak. Blade'da {{ }} avtomatik escape qiladi, {!! !!} esa qilmaydi — foydalanuvchi matnini {!! !!} bilan chiqarmang.

Nega bu xato takrorlanadi

SSTI ko'pincha "qulaylik" nomi bilan paydo bo'ladi: dasturchi email shablonini, bildirishnoma matnini yoki hisobot sarlavhasini admin panel orqali tahrirlashga ruxsat berishni xohlaydi. Bu o'zi yomon g'oya emas — muammo shundaki, "tahrirlash" imkoniyati ko'pincha "render qilish" bilan aralashtiriladi. Admin panelidan matn kiritish mumkin bo'lsa ham, bu matn avtomatik ravishda shablon tiliga aylanmasligi kerak. Agar admin panelida "shablon" maydoni bo'lsa va u keyinchalik Blade::render() orqali ishlov berilsa, bu aynan shu xato — faqat administrator tomonidan ishlatiladi, deb o'ylab qoldirilgan bo'ladi. Lekin admin hisobi buzilsa yoki ichki tahdid bo'lsa, bu yo'l orqali ham to'liq server nazorati qo'lga olinishi mumkin. Shuning uchun "faqat ishonchli foydalanuvchi kiradi" degan taxmin yetarli himoya emas.

Tuzatishdan keyingi tekshiruv

  • Barcha "shablon" sifatida ishlatiladigan joylarga {{7*7}} kabi probalar yuborildimi va javobda matn o'zgarishsiz qoldimi
  • Foydalanuvchi matni hech qayerda Blade::render(), Twig::createTemplate() kabi funksiyalarga to'g'ridan-to'g'ri uzatilmayaptimi
  • Dinamik shablon kerak bo'lgan joylarda sandbox yoki cheklangan placeholder mexanizmi ishlatilganmi
  • Chiqishda "raw" chiqish faqat ishonchli manbalar uchun qoldirilganmi

Xulosa

SSTI SQL injection kabi keng tanilmagan, lekin oqibati xuddi shunday — ko'pincha to'liq server nazorati. Qoida oddiy: shablon mexanizmiga faqat dasturchi yozgan shablonlarni bering, foydalanuvchi matnini esa faqat ma'lumot sifatida. Bu kabi in'ektsiya turlari OWASP Top 10 ro'yxatida ham qamrab olingan.

Ilovangizda SSTI yoki boshqa in'ektsiya zaifliklari bor-yo'qligini bilmoqchimisiz? Skanerlash uchun ariza qoldiring — Claude AI agenti kod bazangizni ko'rib chiqadi, mutaxassisimiz esa topilgan muammolarni tasdiqlab, yopishga yordam beradi.