Безпека мобільних додатків: OWASP MASVS, Pinning та захист від зворотного інженерингу
OWASP Mobile Application Security Verification Standard — це не академічний документ. Це перелік того, що перевіряє пентестер у вашому додатку. І те, що він знаходить — часто неприємне.
Certificate Pinning: навіщо та як не зламати production
Certificate Pinning — прив'язка додатку до конкретного TLS-сертифіката або його публічного ключа. Без цього трафік додатку перехоплюється через проксі (Charles, mitmproxy) за п'ять хвилин — це OWASP MASVS-NETWORK-2.
На iOS реалізується через URLSessionDelegate.urlSession(_:didReceive:completionHandler:) з перевіркою SecTrust. Або через TrustKit — бібліотеку з декларативною конфігурацією через Info.plist. TrustKit також може відправляти звіти про невдалі перевірки на сервер — корисно для моніторингу атак MITM у продакшні.
На Android — network_security_config.xml:
<network-security-config>
<domain-config>
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2026-01-01">
<pin digest="SHA-256">base64_public_key_hash</pin>
<pin digest="SHA-256">backup_key_hash</pin>
</pin-set>
</domain-config>
</network-security-config>
Критично: завжди два піни — основний та резервний. Якщо сертифікат закінчився, а backup pin не налаштований, всі користувачі не зможуть увійти в додаток до наступного оновлення. Саме так великі додатки йшли у даунтайм.
Ще одна точка відмови: CDN та third-party SDK. Якщо рекламний SDK або аналітика роблять запити до своїх серверів, а в network_security_config налаштований глобальний pinning — SDK зломається. Конфігурація повинна бути піддоменно-специфічною.
Обфускація та захист коду
iOS: Swift-код компілюється в нативний бінарик, який не декомпілюється у читаний Swift. Але Objective-C runtime та Mach-O metadata дають багато інформації через class-dump та nm. Імена класів, методів, строки у бінарнику — все видно. Для критичних строк (ключі конфігурації, не API-ключі — їх там не повинно бути) — обфускація через SwiftShield.
Android: Java/Kotlin компілюється в DEX, який читається через jadx за секунди. R8 (включений за замовчуванням у release збірках) мініфікує та обфусцирує. Але ProGuard/R8 rules потребують ретельного налаштування: часто після включення обфускації додаток крашається в production через рефлексію або Gson-сериалізацію. Відладочні -dontwarn правила, накопичені роками — джерело дір у захисті.
Для максимального захисту Android — DexGuard (платний) або вільний DexProtector. Вони додають runtime protection, шифрування строк та перевірки цілісності.
Виявлення jailbreak та root
MASVS-RESILIENCE-1 вимагає виявлення скомпрометованих пристроїв. Стандартні перевірки: наявність /Applications/Cydia.app, /usr/bin/ssh, здатність писати файл за межами sandbox (/private/jailbreak_test), наявність MobileSubstrate.
Але: статичні перевірки легко обходяться через A-Bypass, Liberty Lite та подібні твіки. Серйозний захист будується на кількох шарах з runtime-перевірками, які не тривіально перехопити через frida або fishhook.
Готові рішення: IOSSecuritySuite (iOS, open source), rootbeer (Android). Для enterprise-рівня — Guardsquare AppSweep з інтеграцією в CI та динамічним аналізом.
Зберігання даних та Keychain
MASVS-STORAGE-1 та STORAGE-2 — найчастіше порушувані вимоги.
Частої помилки на iOS: токени авторизації зберігаються в UserDefaults. Дані з UserDefaults резервуються в iCloud та доступні при відновленні на інший пристрій. Токен з UserDefaults на новому пристрої — це чужа авторизована сесія. Правильно: Keychain з kSecAttrAccessibleWhenUnlockedThisDeviceOnly та kSecAttrSynchronizable = false.
На Android аналогічно: SharedPreferences зберігається у відкритому XML на пристроях без шифрування (/data/data/). EncryptedSharedPreferences з Jetpack Security або Android Keystore для ключових даних.
| Уразливість | MASVS вимога | Інструмент перевірки |
|---|---|---|
| Незахищений трафік | NETWORK-1,2 | mitmproxy, Burp Suite |
| Дані в UserDefaults/SharedPrefs | STORAGE-1 | frida, objection |
| Відсутність pinning | NETWORK-2 | Charles Proxy |
| Слабка обфускація | RESILIENCE-3 | jadx, class-dump |
| Немає jailbreak detection | RESILIENCE-1 | Jailbroken device test |
Строки: security-аудит по OWASP MASVS рівню L1 — 1-2 тижні. Реалізація захисного шару для існуючого додатку — 3-6 тижнів залежно від знайдених проблем.







