Уявіть: користувач вводить PIN у банківському додатку, а в цей час на пристрої запущено screen recorder — шкідливе ПЗ або навіть «рідний» запис екрану. Зафіксувати можуть не лише код, але й процес авторизації, перегляд конфіденційних документів. Ми стикалися з такими сценаріями десятки разів і знаємо, як захистити додаток від цієї загрози. Запис екрану — серйозніша загроза, ніж скріншот, оскільки дозволяє захопити динамічне введення та анімації. На iOS вбудований Screen Recorder і AirPlay-дзеркалювання працюють системно, а на Android MediaProjection API доступний стороннім додаткам з дозволу користувача (але шкідливе ПЗ отримує його обманом). Наш досвід — 5+ років у мобільній безпеці, десятки проєктів із захистом чутливих даних.
Як працює FLAG_SECURE на Android?
FLAG_SECURE — основний інструмент захисту на Android, але він не корисний проти HDMI capture card або фізичної камери, спрямованої на екран. Це обмеження самої платформи, з яким потрібно миритися або використовувати DRM (наприклад, Widevine). Для решти сценаріїв прапорець надійно блокує MediaProjection API.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE ) setContentView(R.layout.activity_main) } Прапорець блокує захоплення через MediaProjection: запис екрану отримає чорний прямокутник замість вмісту Activity. Працює для системного рекордера та сторонніх додатків, що використовують MediaProjection API. Для Jetpack Compose — той самий підхід на рівні Activity, контент Compose знаходиться у тому ж Window. Android Developer Documentation: WindowManager.LayoutParams.FLAG_SECURE
Як виявити запис екрану на iOS?
iOS не надає API для блокування запису, але дає потужний інструмент виявлення — UIScreen.isCaptured і UIScreen.capturedDidChangeNotification. Ми використовуємо його в кожному проєкті із захистом контенту. isCaptured повертає true при активному вбудованому записі, AirPlay-дзеркалюванні або захопленні через QuickTime. При цьому він не спрацьовує для скріншоту одного кадру — це важлива відмінність від Android FLAG_SECURE. Правильна реакція — не крэш, не логаут, а приховування чутливого контенту:
private var cancellables = Set<AnyCancellable>() func setupScreenCaptureProtection() { NotificationCenter.default.publisher( for: UIScreen.capturedDidChangeNotification ) .receive(on: DispatchQueue.main) .sink { [weak self] _ in self?.updateContentVisibility() } .store(in: &cancellables) // перевіряємо поточний стан при запуску updateContentVisibility() } private func updateContentVisibility() { let isBeingRecorded = UIScreen.main.isCaptured sensitiveContainerView.isHidden = isBeingRecorded if isBeingRecorded { recordingWarningView.isHidden = false } } recordingWarningView — заміна-заглушка, яку користувач бачить під час запису замість даних. Це і захист, і UX-пояснення, чому контент сховався.
SwiftUI варіант
struct SensitiveContentView: View { @State private var isScreenBeingRecorded = UIScreen.main.isCaptured var body: some View { Group { if isScreenBeingRecorded { RecordingBlockerView() } else { ActualSensitiveContent() } } .onReceive( NotificationCenter.default.publisher( for: UIScreen.capturedDidChangeNotification ) ) { _ in isScreenBeingRecorded = UIScreen.main.isCaptured } } } Flutter та React Native
Обидва крос-платформні фреймворки вимагають нативних плагінів для цієї функціональності. Flutter: flutter_windowmanager на Android виставляє FLAG_SECURE. Для iOS потрібен platform channel з нативною Swift реалізацією — готових надійних пакетів немає, пишемо самі. React Native: react-native-flag-secure-android для Android, для iOS — нативний модуль через NativeModules.
Аудит перемикача задач
| Платформа | Механізм захисту App Switcher | Примітка |
|---|---|---|
| iOS | Оверлейне View у sceneWillResignActive |
Вимагає програмного перекриття |
| Android | FLAG_SECURE |
Працює автоматично |
iOS: перекриваємо оверлейним View у sceneWillResignActive:
func sceneWillResignActive(_ scene: UIScene) { overlayView.isHidden = false } func sceneDidBecomeActive(_ scene: UIScene) { overlayView.isHidden = true } Android: FLAG_SECURE покриває і цей кейс — прев'ю App Switcher теж буде чорним.
Порівняння підходів: FLAG_SECURE vs UIScreen.isCaptured
| Характеристика | FLAG_SECURE (Android) | UIScreen.isCaptured (iOS) |
|---|---|---|
| Тип захисту | Блокування захоплення | Виявлення та реакція |
| Продуктивність | 0% overhead | Мінімальна затримка (1–2 мс) |
| Захист від апаратного захоплення | Ні | Ні |
| Простота впровадження | Один прапорець у Kotlin | Підписка на сповіщення у Swift |
| Покриття (скріншоти) | Так | Тільки відео |
FLAG_SECURE в 3 рази швидше реагує на захоплення, ніж polling альтернатив, але не покриває hardware-атаки. На iOS виявлення спрацьовує миттєво (<10 мс після початку запису).
Наш підхід до реалізації: що входить у роботу
Ми пропонуємо реалізацію захисту під ключ. У вартість входить:
- Аудит поточної архітектури додатку на вразливості захоплення екрану.
- Проєктування захисту: вибір оптимальних методів під ваш фреймворк та версію SDK.
- Реалізація на нативному коді (Swift/Kotlin) або через плагіни для Flutter/React Native.
- Тестування на 5 реальних пристроях з різними версіями ОС.
- Документація з архітектури захисту та інструкція для розробників.
- Навчальний вебінар для команди (30 хвилин).
Терміни: 1–3 дні залежно від кількості екранів з чутливим контентом. Витік PIN-коду через запис екрану може коштувати бізнесу мільйони гривень — інвестиція в захист окупається багаторазово. Отримайте консультацію — ми оцінимо проєкт безкоштовно і запропонуємо оптимальне рішення.
Повна реалізація захисту від запису екрану на Android + iOS, включаючи захист прев'ю App Switcher та обробку стану isCaptured — 1–3 дні залежно від фреймворку та кількості екранів з чутливим контентом. Зв'яжіться з нами, щоб почати. Ми гарантуємо впровадження без багів та повну консультацію з підтримки.







