Ein Capacitor-Privacy Screen blendet den Inhalt Ihrer App aus, wenn der Nutzer den App-Wechsler öffnet, und blockiert auf Android Screenshots und Bildschirmaufnahmen. Ohne ihn erstellen iOS und Android ein Snapshot Ihres letzten Bildschirms, sodass ein Bankguthaben, ein medizinischer Befund oder ein einmaliges code in der Liste der letzten Apps sichtbar bleibt. @capgo/capacitor-privacy-screen fügt dies mit einem einzigen Aufruf oder einem Konfigurations-Flag hinzu und ermöglicht es, nur die Bildschirme zu schützen, die es benötigen.
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 an.
- Android zeigt in „Zuletzt verwendet“ eine Live- oder Cache-Vorschau.
Jeder, der kurz aufs Handy schaut, sieht diesen Snapshot. Das gilt auch für alle, die in einem Call den Bildschirm teilen, oder für Nutzer, die ihren Bildschirm für ein Support-Ticket aufzeichnen. Screenshots werden außerdem mit Cloud-Fotomediatheken synchronisiert – dort gelangen sensible Daten wirklich nach außen.
Welche Apps brauchen das
| App-Typ | Was preisgegeben werden kann |
|---|---|
| Banking, Fintech, Krypto | Kontostände, Kartennummern, IBANs, Transaktionen |
| Passwort-Manager, Authenticator-Apps | Passwörter, TOTP-Codes, Recovery-Keys |
| Gesundheit und Medizin | Diagnosen, Verschreibungen, 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 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, bevor dein JavaScript ausgeführt wird, sodass sogar 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 Änderung der Konfiguration. Die enabled Option wird nur aus der Capacitor-Konfiguration gelesen, sie ist keine Runtime-Option.
Option 2: Bestimmte 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 rein und raus abgedeckt ist. Bei Vue Router zum Beispiel:
router.afterEach(async (to) => {
if (to.meta.sensitive) {
await PrivacyScreen.enable();
} else {
await PrivacyScreen.disable();
}
});
Bei Angular nutzt du einen Guard oder eine NavigationEnd Subscription. Bei React Router funktioniert ein Hook in deiner Layout-Komponente. Wichtig ist, dass Back-Navigation, Deep Links und Tab-Wechsel durch dieselbe Logik laufen, sonst kann ein sensibler Screen ungeschützt bleiben.
Was die Optionen bewirken
Android
- Der Schutz nutzt
WindowManager.LayoutParams.FLAG_SECURE. Wenn aktiviert, werden Screenshots und Bildschirmaufnahmen blockiert und die Vorschau in der Übersicht ausgeblendet. dimBackground: truezeigt ein abgedunkeltes Overlay im App-Switcher. Mitfalse, zeigt das Plugin dein Splash-Drawable an, sofern verfügbar, und dimmt andernfalls.privacyModeOnActivityHiddensteuert, was angezeigt wird, wenn deine Activity durch etwas anderes verdeckt wird, z. B. durch den systemseitigen Biometric Prompt:'none'(Standard),'dim'oder'splash'.- Die alte
preventScreenshots-Option ist veraltet und wird ignoriert.FLAG_SECUREwird immer angewendet, solange der Schutz aktiv ist. Um einen Screenshot auf einem Screen zu erlauben, rufedisable()davor auf undenable()danach.
iOS
- Sobald die App nicht mehr aktiv ist, fügt das Plugin ein Overlay hinzu, damit der App-Switcher-Snapshot deine Inhalte nicht anzeigt.
blurEffect: 'light'oder'dark'nutzt natives Blur.'none'(Standard) zeigt den Launch Screen an, falls verfügbar, ansonsten einen System-Hintergrund.- Wenn aktiviert, wird der App-Content zusätzlich in eine sichere Rendering-Schicht gelegt. Behandle das Blockieren von iOS-Screenshots als Best-Effort: Apple stellt API nicht offiziell zum Blockieren von Screenshots bereit, und das Verhalten kann sich je nach iOS-Version ändern.
Web
Die Web-Implementierung trackt nur das enabled-Flag, damit dein code überall läuft. Browser können weder Tab-Vorschauen verbergen noch Screenshots blockieren.
Mit Biometrie kombinieren
Ein gängiges Muster für Banking-Apps: Blur im App-Switcher, dann Face ID oder Fingerabdruck verlangen, wenn die App nach einiger Zeit zurückkommt. Die Funktion des Plugins privacyModeOnActivityHidden hält den Content 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' });
}
});
Siehe den natives Biometrie-Plugin für Setup und Error Handling.
Das offizielle Plugin und das Capgo-Plugin
Das Capacitor Team veröffentlicht außerdem @capacitor/privacy-screen mit einem sehr ähnlichen API (enable, disable, isEnabled und denselben Plattformoptionen). Das Capgo Plugin behält diesen API bei und ergänzt:
enabled: truein 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 die Diagnose.- Eine Web-Implementierung, die das Enabled-Flag beibehält, sodass dasselbe code in einer Browser-Vorschau läuft.
Wenn du das offizielle Plugin bereits nutzt, ist der Umstieg meist nur ein anderer Import.
Wichtige UX-Details
- Blockiere Screenshots nicht grundlos überall. Nutzer machen Screenshots von Belegen, Bestätigungsnummern und Einstellungen. Schütze nur Bildschirme mit sensiblen Daten, nicht die gesamte App, es sei denn, deine Sicherheitsrichtlinie schreibt es vor.
- Erkläre den Nutzern, warum. Wenn jemand auf Android versucht, einen Screenshot zu machen, und nur ein schwarzes Bild bekommt, spart ein kurzer Hinweis im Help Center Support-Tickets.
- Teste Screen Sharing. Videoanrufe und Casting werden auf Android blockiert, solange
FLAG_SECUREgesetzt 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
- Öffne einen sensiblen Screen und wechsle zum App-Switcher. Der Inhalt muss auf beiden Plattformen verborgen sein.
- Versuche auf Android einen Screenshot und eine Bildschirmaufnahme. Beides muss schwarz oder blockiert sein.
- Löse einen biometrischen Prompt aus und prüfe den Hintergrund.
- Navigiere von einem sensiblen Screen zurück zu einem normalen. Im Per-Screen-Modus sollte der Schutz dann aus sein.
- App killen und neu starten. Mit
enabled: truein der Config muss der erste Snapshot geschützt sein. - Teste auf einem iPad mit Split View und Slide Over. Die App darf sichtbar bleiben, wenn sie nicht aktiv ist.
Fehlerbehebung
Snapshot zeigt auf iOS immer noch Inhalte an. Du hast den Schutz erst aktiviert, nachdem die App schon im Hintergrund war, oder nur für bestimmte Routes. Nutze die Config-Option für app-weiten Schutz.
Schwarzer Screen in den Recents auf Android statt des Splash-Screens. Setzen Sie dimBackground: false und stelle sicher, dass dein Splash-Drawable existiert, sonst greift das Plugin auf Dimmen zurück.
Screenshots funktionieren unter Android weiterhin. Prüfen isEnabled(). Ein anderer Teil deiner App kann disable() beim Navigieren.
Schutz nach einem OTA-Update verloren. Config-Werte sind nativ. Wenn du plugins.PrivacyScreen in einem capacitor.config.ts, neuen Store-Build ausliefern. Laufzeit enable() und disable() Aufrufe in deinem JavaScript kannst du ändern mit Capgo Live Updates.
Verwandte Security-Themen
Ein Privacy Screen ist ein Punkt auf der Mobile-Security-Checkliste. Schau dir auch Secure Storage, Certificate Pinning und Root Detection an. Capgo hat Plugins für SSL Pinning und Root- und Jailbreak-Detection, und unser Post zu Apples Privacy-Regeln für Capacitor Apps behandelt die Review-Seite. Alle Plugin-Optionen findest du in den Privacy Screen Docs.