Sensitive value copied to the system clipboard

ID

dart.privacy.clipboard_sensitive_data

Severity

high

Remediation Complexity

trivial

Remediation Risk

medium

Remediation Effort

low

Resource

Privacy

Language

Dart

Description

A sensitive value (token, password, OTP, recovery phrase / mnemonic / seed phrase, PIN, API key, JWT) is written to the system clipboard via Clipboard.setData(ClipboardData(text: …​)). The clipboard is shared across all apps on the device and persists indefinitely.

Rationale

The system clipboard is global and unprotected:

  • Any other app on the device can read it. Adware, keyboard apps, screen-time / parental-control utilities, accessibility services — all routinely read clipboard contents on every paste event.

  • iOS Universal Clipboard / Handoff syncs the clipboard across the user’s Apple devices — your password is now on their laptop, iPad, and Apple Watch.

  • Android 12+ shows a toast on every clipboard read, confirming the leak but not preventing it.

  • The clipboard persists indefinitely unless explicitly cleared. A token copied at 9am is still readable at 9pm by every app launched in between.

Copying a long-lived credential to the clipboard is therefore a trust-handoff to every app the user happens to run. For short-lived material (an OTP that the user must paste into a banking page within 30 seconds), copying is sometimes the only reasonable UX — but clear the clipboard after a short timeout.

The following code illustrates a vulnerable pattern detected by this rule:

class CopySecrets {
  Future<void> copyToken(String token) async {
    // VULNERABLE: Sensitive value copied to the system clipboard
    await Clipboard.setData(ClipboardData(text: token));
  }

  Future<void> copyApiKey(String apiKey) async {
    await Clipboard.setData(ClipboardData(text: apiKey));
  }

  Future<void> copyRecoveryPhrase(String recoveryPhrase) async {
    await Clipboard.setData(ClipboardData(text: recoveryPhrase));
  }
}

Remediation

Avoid copying credentials. Prefer:

  • In-app reveal: show the value with a tap-and-hold gesture that does not put it on the clipboard.

  • Share Sheet limited to a chosen target: lets the user paste into one specific app without the clipboard middleman.

  • For short-lived OTPs / codes: copy, then clear after 30 s with Clipboard.setData(const ClipboardData(text: '')).

import 'package:flutter/services.dart';

// Vulnerable
await Clipboard.setData(ClipboardData(text: token));
await Clipboard.setData(ClipboardData(text: 'Your recovery phrase: $mnemonic'));

// Fixed: short-lived OTP only, with auto-clear
await Clipboard.setData(ClipboardData(text: otp));
Timer(const Duration(seconds: 30), () async {
  await Clipboard.setData(const ClipboardData(text: ''));
});

Configuration

This detector does not need any configuration.

References

© 2026 Xygeni. All rights reserved