Реалізація ізольованої пісочниці (Sandbox) для міні-програм у Super App

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація ізольованої пісочниці (Sandbox) для міні-програм у Super App
Складний
від 1 тижня до 3 місяців
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Реалізація ізольованої пісочниці (Sandbox) для мініпрограм у Super App

Super App з мініпрограмами — це, по суті, операційна система всередині операційної системи. Хост-додаток завантажує та виконує код від сторонніх розробників. Якщо цей код може читати дані інших мініпрограм або основного додатку — вся архітектура безпеки розваліється.

Чому це складніше, ніж здається

У WeChat Mini Programs, Grab SuperApp, Gojek — скрізь своя реалізація ізоляції. Головна проблема: нативний код у iOS та Android не вміє «ізолювати» довільний JS чи Dart код без спеціальних механізмів. WebView дає ізоляцію DOM, але не ізоляцію пам'яти та не обмеження мережевих запитів.

Типовий антипаттерн: завантажити JS мініпрограми в WKWebView / WebView, відкрити addJavascriptInterface для потрібних API — і вважати це пісочницею. Це не пісочниця. Будь-який XSS у мініпрограмі отримує доступ до всіх об'єктів, зареєстрованих через addJavascriptInterface, включаючи мости до нативного коду.

Рівні ізоляції, які потрібно реалізувати

1. Ізоляція виконання коду

На Android мініпрограми на JS краще виконувати у окремому процесі через атрибут android:process у маніфесті. Кожна мініпрограма — окремий процес зі своєю heap. Крах однієї програми не валить хост. Для Dart/Flutter — Isolate з обмеженим API ReceivePort.

Для WebView-базованих мініпрограм: WebView з setJavaScriptEnabled(true) у окремому процесі + WebViewClient із білим списком хостів:

class SandboxedWebViewClient(
    private val allowedHosts: Set<String>
) : WebViewClient() {

    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        val host = request.url.host ?: return blockRequest()
        if (host !in allowedHosts) {
            auditLogger.logBlockedRequest(miniProgramId, request.url)
            return blockRequest()
        }
        return null // продовжуємо
    }

    private fun blockRequest() = WebResourceResponse(
        "text/plain", "UTF-8", ByteArrayInputStream("blocked".toByteArray())
    )
}

2. JavaScript Bridge із capability model

Замість відкритого addJavascriptInterface — декларативний міст із явним списком розрішень. Мініпрограма запитує API, хост перевіряє, дозволено ли він у маніфесті цієї програми:

class CapabilityBridge(
    private val miniAppManifest: MiniAppManifest,
    private val userId: String
) {

    @JavascriptInterface
    fun callNative(apiName: String, params: String, callbackId: String) {
        val capability = Capability.fromString(apiName) ?: run {
            sendError(callbackId, "UNKNOWN_API")
            return
        }

        if (!miniAppManifest.hasPermission(capability)) {
            auditLogger.logUnauthorizedApiCall(miniAppId, apiName)
            sendError(callbackId, "PERMISSION_DENIED")
            return
        }

        nativeApiRouter.dispatch(capability, params, callbackId)
    }
}

Маніфест мініпрограми описує запрошені API — аналог uses-permission в Android, тільки для екосистеми mini app.

3. Ізоляція сховища

Кожна мініпрограма отримує ізольований namespace у SharedPreferences та окремої директорії в filesDir:

/app/mini_programs/
  /{mini_app_id}/
    /storage/      ← SharedPreferences namespace
    /files/        ← файлове сховище
    /cache/        ← очищується при нехватці місця

Доступ до сховища іншої мініпрограми — тільки через явний Intent із підтвердженням користувача. Кросс-програмний доступ до даних поза цією схемою — заборонений на рівні ContentProvider із перевіркою callingUid.

4. Мережева ізоляція

На Android 8+ можна використовувати ConnectivityManager з NetworkCapabilities для привʾязки конкретного з'єднання до VPN-профілю мініпрограми. Менш агресивний варіант — proxy із allowlist на рівні хоста та HTTPS pinning до серверів мініпрограми через користувацький X509TrustManager.

На iOS — WKContentWorld (iOS 14+) дозволяє виконувати JS кожної мініпрограми у ізольованому світі з окремим глобальним об'єктом:

let miniAppWorld = WKContentWorld.world(withName: "mini_app_\(miniAppId)")

webView.evaluateJavaScript(miniAppCode, in: nil, in: miniAppWorld) { result, error in
    // код виконується в ізольованому контексті
}

Різні WKContentWorld не видять змінні одна одної навіть в одному WKWebView.

Аттестація коду мініпрограм

Перед запуском — верифікація підпису бандла. Кожен бандл підписується розробником та перевіряється за публічним ключем, зареєстрованим на платформі:

fun verifyMiniAppBundle(bundle: ByteArray, signature: ByteArray, publisherKey: PublicKey): Boolean {
    val sig = Signature.getInstance("SHA256withECDSA")
    sig.initVerify(publisherKey)
    sig.update(bundle)
    return sig.verify(signature)
}

Запуск непідписаного або модифікованого бандла — відмова з логуванням інциденту.

Мониторинг під час виконання

Sandbox — не статична конструкція. Потрібен runtime мониторинг: час виконання CPU для кожної мініпрограми, обʼєм виділеної пам'яті, кількість мережевих запитів. Мініпрограма, що робить 500 запитів на секунду, або зламана, або займається майнингом.

На Android — Debug.MemoryInfo + Debug.ThreadCpuTimeNanos() для кожного процесу мініпрограми. Пороги налаштовуються в конфігу платформи.

Терміни

Базова пісочниця із WebView-процесною ізоляцією та capability bridge — 2–3 тижні. Повна платформа з мережевою ізоляцією, аттестацією бандлів, runtime мониторингом та консоллю управління розрішеннями — 2–3 місяці.