はじめに
Flutterアプリにおいて、これまでのセキュリティ対策は主に以下でした:
- HTTPS通信
- トークンの安全保存(
flutter_secure_storage) - Root / Jailbreak検知
- 難読化(obfuscation)
しかし、ある重要な穴がありました。
画面共有・録画・ミラーリングによる情報漏洩
たとえば:
- Zoom / Meet で画面共有中
- Android のスクリーン録画
- キャスト(画面投影)
- リモート操作アプリ
このとき、ユーザーの機密情報がそのまま見える問題です。
解決策:SensitiveContent Widget
Flutterはこの問題に対して、公式に
SensitiveContent Widget
を提供しました。
これは、
「このUIは機密です」とOSに伝える仕組み
です。
基本の使い方
SensitiveContent(
sensitivity: ContentSensitivity.sensitive,
child: YourWidget(),
)
これだけ。
何が起きるのか?
Android(API 35+)では:
- 画面共有(MediaProjection)時
- 録画時
画面が自動的に隠される / マスクされる
つまり、
「この画面は映さないで」とOSレベルで制御
されます。
ContentSensitivity の3種類
1. notSensitive
通常表示(保護なし)
ContentSensitivity.notSensitive
2. sensitive(最重要)
ContentSensitivity.sensitive
最強レベル
特徴:
- 1つでも存在すると画面全体が保護対象
- 画面共有時に完全ブロック
3. autoSensitive
ContentSensitivity.autoSensitive
中間レベル
- 他に
sensitiveがなければ有効 - 柔軟な制御用
重要な仕様
① Android限定(しかもAPI 35+)
Android 14以下では効かない
② iOSでは無効
つまりクロスプラットフォームではない
③ スクリーンショットは防げない
ここ超重要
| 機能 | 防げる? |
|---|---|
| 画面共有 | ✅ |
| 録画 | ✅ |
| スクリーンショット | ❌ |
どこに使うべきか?
✔️ 使うべき画面
- クレジットカード表示
- 銀行残高
- OTPコード
- パスワード表示
- 個人情報
- 管理画面
使わない方がいい
- 一覧画面全部
- SNSフィード
- 商品一覧
理由:
UXが悪化する
実践例:銀行アプリ
class BalanceScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SensitiveContent(
sensitivity: ContentSensitivity.sensitive,
child: Scaffold(
appBar: AppBar(title: Text('残高')),
body: Column(
children: [
Text('残高: ¥1,200,000'),
Text('口座番号: 12345678'),
],
),
),
);
}
}
設計のコツ(実務向け)
① 画面単位で使うのが基本
SensitiveContent(
child: Scaffold(...)
)
部分的に使うより安全
② 本当に重要な画面だけ
乱用するとUX崩壊
発展:最近タスク画面対策
SensitiveContentとは別に、
アプリ切り替え時のプレビュー対策
も必要
方法:
FLAG_SECURE- or
flutter_windowmanager - or 専用Widget
まとめ
セキュリティは「1つの技術」ではなく
多層防御(Defense in Depth)
です。
SensitiveContentはその中の1レイヤー。