The Problem with Traditional Secure Storage
If you've ever worked with sensitive data in Flutter—API keys, authentication tokens, user credentials—you've probably used flutter_secure_storage or similar packages. They're great tools, but they have a fundamental architectural weakness: sensitive data passes through the Dart VM heap and platform channels in plaintext.
Think about what happens when you call secureStorage.read('token'):
- Native code decrypts your token
- Plaintext value crosses the platform channel
- String gets allocated in Dart's heap memory
- Your app uses the value
- Eventually, garbage collection cleans it up (maybe)
During this entire lifecycle, your sensitive data is vulnerable to memory dumps, heap inspection attacks, and platform channel interception. For most apps, this is acceptable risk. But what if you're building a banking app? A health records system? A cryptocurrency wallet?
We needed something better.
Introducing MemGuard: Secure by Design for Flutter
MemGuard is a hybrid secure storage solution that eliminates plaintext exposure across the entire stack—from the Dart VM to native storage. It combines two complementary approaches:
🚀 Memory Storage Mode (Rust FFI)
- Ultra-fast zero-copy access via Rust FFI
- Sensitive data never touches the Dart VM
- Ephemeral by design (vanishes on app close)
- Optional AES-256-GCM encryption in Rust
- Perfect for session tokens and temporary credentials
🔒 Device Secure Storage Mode (Platform Channels + Hardware Encryption)
- Hardware-backed encryption (Android KeyStore, iOS Keychain)
- Persistent across app restarts
- Platform channels transmit only boolean flags—never plaintext
- Rust cache layer for fast subsequent reads
- Perfect for long-term credentials and user data
The Zero-Leak Architecture
Here's the revolutionary part: your Dart code never sees sensitive data directly.
// Traditional approach - UNSAFE
final token = await secureStorage.read('auth_token');
// ❌ Plaintext now in Dart heap!
// MemGuard approach - SAFE
await MemGuardStatic.store('auth_token', 'secret_jwt');
final token = await MemGuardStatic.retrieve('auth_token');
// ✅ Data lives in Rust protected memory, zero-copy access
How It Works
┌─────────────────────────────────────────────────────────────┐
│ YOUR DART CODE │
│ • Never touches sensitive data directly │
│ • Only receives boolean status flags │
└──────────────────┬──────────────────────────────────────────┘
│
▼
┌─────────────────────┐
│ MemGuard Plugin │
│ (Dart API Layer) │
└─────────┬───────────┘
│
┌─────────┴─────────┐
▼ ▼
┌──────────────────┐ ┌────────────────────┐
│ Rust FFI │ │ Platform Channel │
│ (Memory Cache) │ │ (Kotlin/Swift) │
│ │ │ │
│ • Direct access │ │ • KeyStore/Keychain│
│ • Zero-copy │ │ • Encrypted files │
│ • Protected mem │ │ • No plaintext │
└──────────────────┘ └────────────────────┘
Key Innovation: Platform channels return true/false/null instead of plaintext values. Dart then retrieves the actual data directly from Rust's protected memory via FFI, bypassing the VM entirely.
Advanced Feature: Zero-Copy Cryptographic Operations
For maximum security, MemGuard lets you perform cryptographic operations directly on data without ever copying it to Dart:
// Sign a message with a private key that NEVER enters Dart memory
final signature = await MemGuardStatic.performSecureOperation<String>(
'private_key',
(dataPtr, length) {
// Direct pointer access to Rust memory
final keyBytes = dataPtr.asTypedList(length);
// Perform signing operation
final signature = ed25519.sign(keyBytes, message);
return signature;
// Private key automatically zeroed after this scope
},
);
This pattern is perfect for:
- Cryptographic signing without key exposure
- Hash computation on sensitive data
- Encryption/decryption with in-memory keys
- Any operation where data must never touch the Dart heap
Security Guarantees
✅ What MemGuard Protects Against
- Memory dumps of Dart VM
- Platform channel interception
- Heap inspection attacks
- Data tampering (GCM authentication)
- Key extraction (hardware-backed keys)
- Root access (partial—keys resist extraction even on rooted devices)
❌ What MemGuard Does NOT Protect Against
- Physical device seizure by sophisticated attackers
- Compromised OS/kernel (malware with system privileges)
- User-authorized access (screen recording, accessibility services)
- State-level adversaries with hardware forensics
Threat Model: MemGuard is designed for production app security against common attack vectors. It's not a substitute for end-to-end encryption or protection against nation-state actors.
Getting Started
Installation is straightforward:
dependencies:
memguard: ^2.1.4
Basic setup with memory storage:
import 'package:memguard/memguard.dart';
void main() {
runApp(
MemGuard(
storageType: StorageType.memory,
enableEncryptionMemory: true,
autoCleanupMemory: true,
cleanupIntervalMemory: Duration(minutes: 10),
showLog: true,
child: MyApp(),
),
);
}
Then use it anywhere:
// Store
await MemGuardStatic.store('auth_token', 'secret_jwt');
// Retrieve
final token = await MemGuardStatic.retrieve('auth_token');
// Check existence
final exists = await MemGuardStatic.contains('auth_token');
// Delete
await MemGuardStatic.delete('auth_token');
When to Use Each Mode
Memory Storage → Use When:
✅ Data is ephemeral (session tokens, temporary API keys)
✅ Maximum speed is critical
✅ Data should vanish on app close
✅ You need zero-copy cryptographic operations
Device Secure Storage → Use When:
✅ Data must persist across restarts
✅ Storing user credentials or refresh tokens
✅ Need hardware-backed encryption
The Tech Stack
MemGuard is built on a foundation of battle-tested technologies:
- Rust FFI: Memory-safe protected storage with explicit zeroing
- Android KeyStore: Hardware-backed AES-256-GCM encryption (StrongBox/TEE)
- iOS Keychain: Native iOS secure enclave integration (coming soon)
- Platform Channels: Custom protocol that transmits only status flags
The native implementation lives in MemGuard Core, which provides the Rust .so libraries and Kotlin integration code.
Platform Support
| Platform | Memory Storage | Device Secure | Status |
|---|---|---|---|
| Android | ✅ Full | ✅ Full | Production Ready |
| iOS | ⚠️ Untested | ⚠️ Untested | Coming Soon |
| Linux | ✅ Full | ❌ N/A | Supported |
| Windows | ⚠️ Untested | ⚠️ Untested | Coming Soon |
| macOS | ⚠️ Untested | ⚠️ Untested | Coming Soon |
Linux Requirements: glibc 2.31+ (Ubuntu 20.04+, Debian 11+, Fedora 34+)
Roadmap & Contribution
We're actively working on:
- iOS/macOS platform implementation
- Windows secure storage integration
- Additional encryption algorithms
- Performance benchmarks and comparisons
- Comprehensive test coverage
Contributions are welcome! Check out the GitHub repository to get involved.
Conclusion: Security Without Compromise
MemGuard represents a fundamental shift in how we think about secure storage in Flutter. By eliminating plaintext exposure across the entire stack—from Dart VM to native storage—we've created a solution that doesn't compromise between security and performance.
Whether you're building a fintech app that needs to protect user credentials, a health platform handling sensitive medical data, or a crypto wallet managing private keys, MemGuard provides the security architecture you need without sacrificing Flutter's developer experience.
Try MemGuard today:
Have questions or feedback? Open an issue on GitHub or start a discussion. We'd love to hear how you're using MemGuard in production!
Security Notice
MemGuard implements defense-in-depth secure storage, but no client-side storage is absolutely secure. Always validate critical operations server-side, use certificate pinning, implement request signing, rotate credentials regularly, and enable biometric authentication when available.
For high-security applications, combine MemGuard with additional layers of protection (HSM, remote attestation, etc.).
Tags: #Flutter #Security #Rust #Cryptography #MobileDevelopment #OpenSource #Android #iOS #SecureStorage #MemorySafety
Top comments (0)