Zum Hauptinhalt springen

Capacitor Privacy Screen: App-Inhalte ausblenden

Füge einen Capacitor Privacy Screen hinzu, um App-Inhalte im App-Switcher zu verbergen und Screenshots zu blockieren – inklusive Steuerung pro Screen, Konfiguration und Plattform-Hinweisen.

Capacitor Privacy Screen: App-Inhalte ausblenden

Ein Capacitor Privacy Screen blendet deine App-Inhalte aus, sobald der User den App-Switcher öffnet, und blockiert auf Android Screenshots sowie Screen-Recordings. Ohne diesen erstellen iOS und Android einen Snapshot des letzten Screens, wodurch Kontostände, medizinische Daten oder ein code in der Liste der zuletzt genutzten Apps sichtbar bleiben. @capgo/capacitor-privacy-screen erledigt das mit einem einzigen Aufruf oder einem Config-Flag und lässt dich gezielt nur die Screens schützen, die es wirklich brauchen.

Was der App-Switcher preisgibt

Verlässt ein Nutzer deine App, erstellen beide Systeme ein Bild des aktuellen Bildschirms:

  • iOS erstellt einen Snapshot, wenn die App inaktiv wird und zeigt ihn im App-Switcher sowie kurz beim Neustart der App.
  • Android shows a live or cached preview in Recents.

Jeder, der kurz auf das Handy schaut, sieht diesen Snapshot. Das gilt auch für Screen-Sharing in Calls oder Nutzer, die ihren Bildschirm für ein Support-Ticket aufzeichnen. Screenshots werden zudem mit Cloud-Fotomediatheken synchronisiert – dort gelangen sensible Daten oft unbemerkt nach außen.

Welche Apps das benötigen

App-Typ Was preisgegeben werden kann
Banking, Fintech, Krypto Kontostände, Kartennummern, IBANs, Transaktionen
Passwort-Manager, Authentifikatoren Passwörter, TOTP-Codes, Recovery-Keys
Gesundheit und Medizin Diagnosen, Rezepte, Laborergebnisse
Messaging Private Unterhaltungen
HR, Gehaltsabrechnung, Rechtliches Gehälter, Verträge
Dating, private Medien Fotos und Matches

Security-Reviews und Penetrationstests für diese Kategorien bemängeln regelmäßig fehlenden App-Switcher-Schutz. OWASP MASVS enthält Checks für sensible Daten, die über die UI offengelegt werden, und Auditoren testen genau das.

Installieren

bun add @capgo/capacitor-privacy-screen
bunx cap sync

Das Plugin unterstützt Capacitor 8 mit der Version 8.x.

Option 1: Die gesamte App beim Start schützen

Setze es in capacitor.config.ts. Das native Plugin liest dies beim Laden aus, noch bevor dein JavaScript ausgeführt wird, sodass selbst der erste Snapshot geschützt ist:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.bank',
  appName: 'Example Bank',
  webDir: 'dist',
  plugins: {
    PrivacyScreen: {
      enabled: true,
      android: {
        dimBackground: false,
        privacyModeOnActivityHidden: 'splash',
      },
      ios: {
        blurEffect: 'dark',
      },
    },
  },
};

export default config;

Ausführen bunx cap sync nach der Konfigurationsänderung. Die enabled Option wird nur aus der Capacitor Konfiguration gelesen; es ist keine Runtime-Option.

Option 2: Spezifische Screens schützen

import { PrivacyScreen } from '@capgo/capacitor-privacy-screen';

export async function enterSensitiveScreen() {
  await PrivacyScreen.enable({
    android: { dimBackground: true },
    ios: { blurEffect: 'light' },
  });
}

export async function leaveSensitiveScreen() {
  await PrivacyScreen.disable();
}

const { enabled } = await PrivacyScreen.isEnabled();

Binde diese in deinen Router ein, damit jeder Pfad abgedeckt ist. Mit dem Vue Router zum Beispiel:

router.afterEach(async (to) => {
  if (to.meta.sensitive) {
    await PrivacyScreen.enable();
  } else {
    await PrivacyScreen.disable();
  }
});

Mit Angular nutzt du einen Guard oder eine NavigationEnd Subscription. Mit React Router funktioniert ein Hook in deiner Layout-Komponente. Wichtig ist, dass Back-Navigation, Deep Links und Tab-Wechsel dieselbe Logik nutzen, da sonst ein sensibler Screen ungeschützt bleiben könnte.

Was die einzelnen Optionen bewirken

Android

  • Schutz verwendet WindowManager.LayoutParams.FLAG_SECURE. Wenn aktiviert, werden Screenshots und Bildschirmaufnahmen blockiert und die Vorschau in der App-Übersicht ausgeblendet.
  • dimBackground: true zeigt ein abgedunkeltes Overlay im App-Switcher. Mit falsezeigt das Plugin dein Splash-Drawable an, falls verfügbar, ansonsten wird abgedunkelt.
  • privacyModeOnActivityHidden steuert, was angezeigt wird, wenn deine Activity durch etwas anderes verdeckt wird, z. B. durch den System-Biometric-Prompt: 'none' (Standard), 'dim' oder 'splash'.
  • Die alte preventScreenshots -Option ist veraltet und wird ignoriert. FLAG_SECURE wird immer angewendet, solange der Schutz aktiv ist. Um einen Screenshot auf einem Screen zu erlauben, rufe disable() davor auf und enable() darauf.

iOS

  • Sobald die App wieder aktiv wird, fügt das Plugin ein Overlay hinzu, damit der App-Switcher-Snapshot keinen Inhalt anzeigt.
  • blurEffect: 'light' oder 'dark' nutzt natives Blur. 'none' (Standard) zeigt den Launch Screen an, falls verfügbar, ansonsten einen System-Hintergrund.
  • Bei aktiviertem Schutz wird der App-Inhalt zudem in einem Secure Rendering Layer gerendert. Betrachte das Blockieren von iOS-Screenshots als Best-Effort-Lösung: Apple bietet kein offizielles API zum Blockieren von Screenshots an, und das Verhalten kann sich zwischen iOS-Versionen ändern.

Web

Die Web-Implementierung trackt lediglich das enabled-Flag, damit dein code überall läuft. Browser können Tab-Vorschauen nicht verbergen oder Screenshots blockieren.

Kombination mit Biometrie

Ein gängiges Muster für Banking-Apps: Blur im App-Switcher, gefolgt von Face ID oder Fingerabdruck, sobald die App nach einer gewissen Zeit wieder aktiv wird. Das Plugin privacyModeOnActivityHidden hält den Inhalt verdeckt, während der Android Biometric Prompt angezeigt wird.

import { App } from '@capacitor/app';
import { NativeBiometric } from '@capgo/capacitor-native-biometric';

// null until the app has really gone to the background
let backgroundedAt: number | null = null;

App.addListener('appStateChange', async ({ isActive }) => {
  if (!isActive) {
    backgroundedAt = Date.now();
    return;
  }
  const away = backgroundedAt === null ? 0 : Date.now() - backgroundedAt;
  backgroundedAt = null;
  if (away > 60_000) {
    await NativeBiometric.verifyIdentity({ reason: 'Confirm it is you' });
  }
});

Sieh dir das native Biometrie-Plugin für Setup und Error Handling an.

Das offizielle Plugin und das Capgo Plugin

Das Capacitor Team veröffentlicht zudem @capacitor/privacy-screen mit einem sehr ähnlichen API (enable, disable, isEnabled und denselben Plattform-Optionen). Das Capgo Plugin behält diesen API bei und bietet:

  • enabled: true in der Capacitor Config, sodass der Schutz aktiv ist, bevor JavaScript ausgeführt wird. Das offizielle Plugin lässt sich nur via JavaScript aktivieren.
  • Sicheres iOS-Rendering des Inhalts bei aktiviertem Modus, zusätzlich zum App-Switcher-Overlay, wie im Plugin dokumentiert.
  • getPluginVersion() für Diagnosen.
  • Eine Web-Implementierung, die das Enabled-Flag beibehält, sodass dasselbe code in einer Browser-Vorschau läuft.

Wenn du bereits das offizielle Plugin nutzt, ist der Wechsel meist nur eine Änderung beim Import.

Wichtige UX-Details

  • Blockiere Screenshots nicht grundlos überall. Nutzer machen Screenshots von Belegen, Bestätigungsnummern oder Einstellungen. Schütze nur Bildschirme mit sensiblen Daten, nicht die gesamte App, es sei denn, deine Sicherheitsrichtlinie schreibt es vor.
  • Erkläre es den Nutzern. Wenn jemand unter Android einen Screenshot macht und nur ein schwarzes Bild erhält, spart ein kurzer Hinweis im Help Center Support-Tickets.
  • Teste Screen Sharing. Videoanrufe und Casting werden unter Android blockiert, wenn FLAG_SECURE eingestellt ist. Falls deine App einen „Bildschirm mit dem Support teilen“-Flow hat, deaktiviere den Schutz dafür.
  • Prüfe die Barrierefreiheit. Screenreader funktionieren weiterhin mit FLAG_SECURE, aber teste es trotzdem mit TalkBack und VoiceOver.

Testing-Checkliste

  1. Öffne einen sensiblen Screen und wechsle zum App-Switcher. Der Inhalt muss auf beiden Plattformen verborgen sein.
  2. Versuche auf Android einen Screenshot und eine Bildschirmaufnahme. Beides muss schwarz oder blockiert sein.
  3. Löse einen Biometric Prompt aus und prüfe den Hintergrund.
  4. Navigiere von einem sensiblen Screen zu einem normalen Screen zurück. Der Schutz sollte sich deaktivieren, wenn du den Per-Screen-Modus nutzt.
  5. App killen und neu starten. Mit enabled: true in der Config muss der erste Snapshot geschützt sein.
  6. Teste auf einem iPad mit Split View und Slide Over. Die App darf sichtbar bleiben, während sie inaktiv ist.

Fehlerbehebung

Snapshot zeigt auf iOS immer noch Inhalte an. Du hast den Schutz erst aktiviert, nachdem die App bereits in den Hintergrund ging, oder nur für bestimmte Routes. Nutze die Config-Option für App-weiten Schutz.

Schwarzer Screen in der Übersicht (Recents) auf Android statt des Splash-Screens. Setze dimBackground: false und stelle sicher, dass dein Splash Drawable existiert, sonst greift das Plugin auf Dimming zurück.

Screenshots funktionieren unter Android weiterhin. Prüfe isEnabled(). Ein anderer Teil deiner App kann disable() beim Navigieren.

Schutz nach einem OTA-Update verloren. Konfigurationswerte sind nativ. Wenn du plugins.PrivacyScreen in capacitor.config.ts, ship a new store build. Runtime enable() und disable() Aufrufe in deinem JavaScript können mit Capgo Live Updates.

Ein Privacy Screen ist ein wichtiger Punkt auf jeder Mobile-Security-Checkliste. Beachte auch Secure Storage, Certificate Pinning und Root Detection. Capgo bietet Plugins für SSL Pinning und Root- und Jailbreak-Detection, und unser Post über Apples Privacy-Regeln für Capacitor Apps behandelt die Review-Seite. Alle Plugin-Optionen findest du in den Privacy Screen Docs.

Live-Updates für Capacitor-Apps

Wenn ein Bug im Web-Layer live ist, rollst du den Fix über Capgo aus, statt Tage auf die App-Store-Freigabe zu warten. Nutzer bekommen das Update im Hintergrund, während native Änderungen weiter den normalen Review-Prozess durchlaufen.

Neuestes aus unserem Blog

Capgo bietet dir die besten Insights für eine wirklich professionelle Mobile App.