Asosiy matnga o'tish
Blog

Mobil

APK va IPA ichidagi kalitlar va API manzillar: nega "yashirilgan" kalit sir emas

Mobil ilovaga qo'yilgan har qanday kalit va manzil jadx yoki strings bilan topiladi. Nimani ilovada saqlash mumkin, nimani faqat serverda, va obfuskatsiya qayergacha yordam beradi.

· 10 daq. o'qish

Foto: Raimond Spekking, CC BY-SA 4.0 · Wikimedia Commons

Mobil ilova ishlab chiqishda tez-tez uchraydigan holat: SMS-shlyuz, to'lov tizimi yoki xarita xizmatining API kaliti ilova kodiga yoki .env fayliga yoziladi, "foydalanuvchi baribir ko'rmaydi" degan fikr bilan. Yoki server manzillari, shu jumladan test va admin manzillari, oddiy satr sifatida kodda turadi. Ekspert esa ilovani tahlil qilishni aynan shundan boshlaydi: APK yoki IPA ochiladi va ichidagi barcha satrlar ko'rib chiqiladi.

O'z ilovamiz ekspertizasida ham shu mavzuga tegishli topilma bo'lgan: API manzillari kodda ochiq satr sifatida saqlanmasligi kerak edi. Bu maqolada ilova ichidan nimalarni chiqarib olish mumkinligini, nega "yashirish" yetarli emasligini va to'g'ri himoya qayerda qurilishini ko'rib chiqamiz.

Muammo nimada

Foydalanuvchi qurilmasiga o'rnatilgan ilova — bu foydalanuvchining qo'lidagi fayl. Uni nusxalash, ochish, dekompilyatsiya qilish va ish vaqtida kuzatish mumkin. Demak, ilovaga qo'yilgan har qanday qiymatni yetarli vaqt sarflagan odam albatta topadi. Bu qoida Android'ga ham, iOS'ga ham, native kodga ham, Flutter va React Native'ga ham tegishli.

Ilova ichida odatda quyidagilar topiladi:

  • Uchinchi tomon xizmatlarining maxfiy kalitlari — SMS yuborish, to'lov, email, bulut xotira (masalan, S3 access key), AI API kalitlari. Bular eng xavfli: kalitni olgan odam sizning hisobingizdan SMS yuboradi, fayllarni o'qiydi yoki to'lov API'sini chaqiradi.
  • Ochiq (public) identifikatorlar — Firebase konfiguratsiyasi, Google Maps kaliti, analytics ID. Bular sir sifatida yaratilmagan, lekin to'g'ri cheklanmasa suiiste'mol qilinadi.
  • Server manzillari — asosiy API, staging, test, admin panel, ichki xizmatlar.
  • Statik login/parol yoki "service" token — hamma foydalanuvchi uchun bir xil bo'lgan, server API'ga kirish uchun ishlatiladigan qiymat.
  • Shifrlash kalitlari — kodga yozilgan AES kaliti yoki IV. Bunday shifrlash amalda hech narsani himoya qilmaydi.

Nega bu ekspertiza uchun muhim

OWASP Mobile Top 10 (2024) ro'yxatida birinchi o'rinda M1 — Improper Credential Usage turadi, unga kodga yozilgan (hardcoded) kalitlar va ma'lumotlar kiradi. Kodga yozilgan shifrlash kalitlari M10 (Insufficient Cryptography) ga, ochiq satrlar va himoyasiz binar M7 (Insufficient Binary Protections) ga tegishli. MASVS'da bu STORAGE, CRYPTO va RESILIENCE guruhlarida talablar sifatida bor.

Ekspert APK'ni dekompilyatsiya qilib, satrlarni avtomatik va qo'lda qidiradi. Topilgan maxfiy kalit odatda yuqori xavf deb baholanadi, chunki uning oqibati ilovadan tashqariga — butun xizmatga ta'sir qiladi.

Ilova ichidan nimani ko'rish mumkin: o'zingiz tekshiring

Android: jadx va apktool

# Java/Kotlin kodini o'qiladigan ko'rinishda ochish
jadx -d out app-release.apk

# Resurslar va manifest
apktool d app-release.apk -o res_out

# Tipik qidiruvlar
grep -rniE "api[_-]?key|secret|token|password|bearer" out/ res_out/
grep -rnoE "https?://[a-zA-Z0-9./_-]+" out/ res_out/ | sort -u

res_out/res/values/strings.xml faylini alohida ko'ring — ko'p kalitlar aynan shu yerga qo'yiladi.

Flutter ilovalari

Flutter'da Dart kodi lib/arm64-v8a/libapp.so ichiga kompilyatsiya qilinadi. jadx uni ko'rsatmaydi, lekin satrlar baribir binar ichida turadi:

unzip -o app-release.apk -d apk_out
strings -n 8 apk_out/lib/arm64-v8a/libapp.so | grep -iE "https?://|key|secret"
ls apk_out/assets/flutter_assets/

Ikkita keng tarqalgan tuzoq:

  1. flutter_dotenv bilan .env fayli asset sifatida ilovaga qo'shiladi va assets/flutter_assets/.env yo'lida oddiy matn holida turadi. Uni ochish uchun hech qanday vosita kerak emas.
  2. --dart-define qiymatlari kompilyatsiya vaqtida konstanta bo'lib binar ichiga yoziladi. Ular manba kodda ko'rinmaydi, lekin strings bilan topiladi.

iOS: IPA

unzip -o App.ipa -d ipa_out
plutil -p ipa_out/Payload/App.app/Info.plist
strings ipa_out/Payload/App.app/App | grep -iE "https?://|key|secret"
# Flutter iOS ilovasida Dart kodi shu yerda:
strings ipa_out/Payload/App.app/Frameworks/App.framework/App | grep -iE "https?://"

Info.plist va ilova ichidagi .plist, .json konfiguratsiya fayllarini ham ko'rib chiqing.

Avtomatik qidiruv

Dekompilyatsiya qilingan papkani sirlarni qidiruvchi vositalar bilan tekshirish mumkin:

gitleaks detect --no-git --source out/ -v
trufflehog filesystem out/

Shu vositalarni CI'da manba kodga ham qo'ying — kalit repozitoriyaga tushmasligi ilovaga tushmasligidan oldin keladi. Bu haqda sirlar va kalitlarni boshqarish maqolasida yozganmiz.

Nega "yashirish" yechim emas

Kalitni base64 qilish, ikki qismga bo'lish yoki XOR bilan "shifrlash" — statik qidiruvni qiyinlashtiradi, lekin kalitni himoya qilmaydi. Ilova kalitni ishlatish uchun uni xotirada ochiq holga keltirishi kerak, va shu daqiqada uni Frida bilan funksiyani ushlab olib yoki tarmoq trafigini kuzatib ko'rish mumkin. Server manzillari ham shunday: ilova ularga so'rov yuboradi, demak ular trafikda ko'rinadi.

Obfuskatsiya haqida ham to'g'ri tasavvur kerak:

  • R8 / ProGuard klass va metod nomlarini qisqartiradi, lekin satr literallarini shifrlamaydi.
  • Dart --obfuscate simvol nomlarini almashtiradi, satrlar esa o'z holicha qoladi.
  • Tijoriy himoya vositalari satrlarni shifrlashi mumkin, lekin ular ham ish vaqtida ochiladi.

Qoida oddiy: agar qiymat oshkor bo'lsa, xizmatga zarar yetadigan bo'lsa, u ilovada bo'lmasligi kerak. Ilovada faqat oshkor bo'lishi mumkin bo'lgan, server tomonda cheklangan qiymatlar qoladi.

Shunga qaramay, ochiq satrlarni kamaytirish foydali va ekspertiza buni kutadi: bu statik tahlil narxini oshiradi, avtomatik skanerlar uchun ilovani "oson nishon" bo'lishdan chiqaradi va ichki manzillar tasodifan oshkor bo'lishining oldini oladi. Lekin bu himoyaning yordamchi qatlami, asosiysi emas.

Qanday yopiladi

1. Maxfiy kalitlarni serverga ko'chiring

Uchinchi tomon xizmatini ilova to'g'ridan-to'g'ri chaqirmasin. Ilova sizning backend'ingizga foydalanuvchi tokeni bilan murojaat qiladi, backend esa kalit bilan xizmatni chaqiradi. Laravel misoli:

// routes/api.php
Route::middleware(['auth:sanctum', 'throttle:5,1'])
    ->post('/otp/send', [OtpController::class, 'send']);

// app/Http/Controllers/OtpController.php
public function send(Request $request, SmsGateway $sms)
{
    $user = $request->user();
    $sms->send($user->phone, $this->makeCode($user)); // kalit config('services.sms.key') da
    return response()->noContent();
}

Node (Express) misoli:

app.post('/api/geocode', requireAuth, rateLimit({ windowMs: 60_000, max: 30 }),
  async (req, res) => {
    const r = await fetch(`https://maps.example.com/geocode?q=${encodeURIComponent(req.body.q)}`,
      { headers: { Authorization: `Bearer ${process.env.MAPS_SECRET}` } });
    res.json(await r.json());
  });

Shu bilan kalit faqat serverda yashaydi, har bir so'rov foydalanuvchiga bog'lanadi va so'rovlar soni cheklanadi.

2. Ochiq identifikatorlarni cheklang

Ilovada qolishi kerak bo'lgan kalitlar (masalan, xarita SDK'si uchun) xizmat provayderi panelida cheklansin: Android uchun paket nomi va imzo sertifikati SHA-1 xeshi, iOS uchun bundle ID, ruxsat berilgan API'lar ro'yxati va kunlik limit. Firebase konfiguratsiyasi sir emas — uning xavfsizligi Security Rules va App Check'ga tayanadi, shuning uchun qoidalar "hamma o'qiy oladi" holatida qolmasin.

3. Statik "service" token'dan voz keching

Hamma ilova nusxasi uchun bir xil token — bu umumiy parol. Uning o'rniga har bir foydalanuvchi login orqali o'z qisqa muddatli tokenini oladi (Sanctum, OAuth2 va hokazo). Login'dan oldingi so'rovlar (ro'yxatdan o'tish, OTP) esa rate limiting va bot himoyasi bilan cheklanadi.

4. Ilova haqiqiyligini server tomonda tekshiring

Android'da Play Integrity API, iOS'da App Attest (DeviceCheck) yoki Firebase App Check serverga "so'rov o'zgartirilmagan ilovadan, haqiqiy qurilmadan kelyapti" degan signal beradi. Bu autentifikatsiya o'rnini bosmaydi, lekin skript orqali API'ni suiiste'mol qilishni qiyinlashtiradi.

5. Release build'da faqat release manzillari

Staging, test va admin manzillari release build'ga umuman tushmasin. Flutter'da flavor'lar yoki alohida entry point ishlating:

flutter build apk --release --flavor prod -t lib/main_prod.dart \
  --obfuscate --split-debug-info=build/symbols

Admin panel mobil ilova orqali kerak bo'lmasa, uning manzili ilovada bo'lmasin va server tomonda IP allowlist bilan yopilsin.

6. Qolgan satrlarni kamaytiring

API manzili kabi qiymatlarni oddiy literal sifatida saqlamaslik uchun build vaqtida shifrlab qo'yadigan yondashuvlar bor. Masalan, Dart'da envied paketi obfuscate: true rejimida qiymatlarni ochiq satr ko'rinishida saqlamaydi:

@Envied(path: '.env.prod', obfuscate: true)
abstract class Env {
  @EnviedField(varName: 'API_BASE')
  static final String apiBase = _Env.apiBase;
}

Bu .env faylini asset sifatida qo'shishdan ancha yaxshi, lekin yuqoridagi qoida o'z kuchida: bu yerga faqat oshkor bo'lishi mumkin bo'lgan qiymatlar qo'yiladi. Bunga qo'shimcha ravishda Android'da R8 (minifyEnabled true), Dart'da --obfuscate va RASP binar himoyasini to'ldiradi — bu haqda ilova yaxlitligi va obfuskatsiya maqolasida.

7. Oshkor bo'lgan kalitni almashtiring

Agar kalit avval chiqarilgan biror versiyada bo'lgan bo'lsa, uni olib tashlash yetarli emas — eski APK'lar internetda qoladi. Kalitni provayder panelida bekor qiling (rotate) va yangisini faqat serverga qo'ying.

Qisqa checklist

  • jadx, apktool va strings bilan release APK/IPA tekshirilgan; maxfiy kalit topilmagan.
  • .env asset sifatida ilovaga qo'shilmagan; --dart-define orqali sir uzatilmagan.
  • Uchinchi tomon xizmatlari backend orqali chaqiriladi; kalitlar faqat serverda.
  • Ilovada qolgan kalitlar provayder panelida paket/bundle ID va imzo bo'yicha cheklangan.
  • Firebase Security Rules ochiq emas; App Check yoki Play Integrity / App Attest ko'rib chiqilgan.
  • Barcha foydalanuvchilar uchun umumiy statik token yo'q.
  • Kodga yozilgan shifrlash kaliti yo'q.
  • Release build'da staging, test va admin manzillari yo'q.
  • API manzillari ochiq literal sifatida saqlanmaydi; R8 va --obfuscate yoqilgan.
  • Ilgari oshkor bo'lgan kalitlar almashtirilgan.
  • CI'da gitleaks yoki shunga o'xshash vosita ishlaydi.

Xulosa

Mobil ilova ichida sir saqlab bo'lmaydi — faqat sir saqlash narxini oshirish mumkin. Shuning uchun to'g'ri yondashuv ikki qavatli: haqiqiy sirlar serverda, ilovada esa faqat cheklangan, oshkor bo'lsa ham zarar keltirmaydigan qiymatlar; ustidan esa obfuskatsiya va ochiq satrlarni kamaytirish ekspertiza talablarini qoplaydi. Bu yondashuv nafaqat ekspertizadan o'tishga, balki kalit oshkor bo'lganda uning oqibatini kichraytirishga ham yordam beradi.

Release ilovangiz ichida nima borligini ekspert ko'rishidan oldin ko'rmoqchi bo'lsangiz, skanerlash uchun ariza qoldiring. Claude AI agenti APK/IPA va manba kodni tez ko'rib chiqadi, mutaxassisimiz esa topilgan har bir kalit va manzilni baholab, ularni serverga ko'chirishda yordam beradi.