Files
cursor_gen/flutter-cursor-templates/templates/rules/security/security-standards.mdc.tmpl
T

110 lines
4.9 KiB
Cheetah

---
description: "Security standards for {{PROJECT_NAME}} — ALWAYS APPLIED on every file write"
alwaysApply: true
---
# Security Standards — {{PROJECT_NAME}}
> **Pillar 5**: Security is an always-on rule, not just a reactive agent.
> These rules apply to EVERY file write, regardless of feature or context.
## Credential & secret management
- **NEVER** hardcode API keys, tokens, or secrets in source code
- **NEVER** commit `.env` files — use `.gitignore` and document required vars in `.env.example`
- API keys belong in: flavored `--dart-define` build args, or a secrets manager (e.g. AWS Secrets)
- Use `flutter_secure_storage` for tokens/credentials — **NEVER** `SharedPreferences` for sensitive data
- Obfuscation: enable `--obfuscate --split-debug-info=build/debug-symbols/` for release builds
## Authentication & sessions
- JWT/session tokens: stored in `flutter_secure_storage`, never in `SharedPreferences` or local DB
- Implement token refresh with retry logic — never let a 401 show a raw error to the user
- Certificate pinning: required for production builds on {{AUTH}} — use `dio_pinning_interceptor`
- Biometric re-auth: require for any transaction > defined threshold
## Data & privacy
- **NEVER** log PII (names, emails, phone numbers, addresses) to console or crash reporters
- Sanitize all user inputs before sending to backend
- Use `SensitiveWidget` wrapper to exclude screens from screenshots / app switcher thumbnails
- Comply with platform privacy requirements: iOS `NSPrivacyAccessedAPITypes`, Android permissions
## Network security
- All API calls use HTTPS — no http:// in production
- Validate SSL certificates — never bypass with `badCertificateCallback: (_,_,_) => true`
- Add a timeout to every HTTP call: `connectTimeout: Duration(seconds: 10)`
- Rate-limit sensitive endpoints: auth, OTP, password reset
## Dependency security
- Run `dart pub outdated` monthly — flag packages with known CVEs
- Never use a package with <100 pub points without explicit tech lead approval
- Pin critical security packages to exact versions in `pubspec.yaml`
## Secure coding patterns
```dart
// ✅ Correct: secure token storage
final storage = FlutterSecureStorage();
await storage.write(key: 'access_token', value: token);
// ❌ Wrong: SharedPreferences for sensitive data
final prefs = await SharedPreferences.getInstance();
prefs.setString('access_token', token); // NEVER do this
// ✅ Correct: PII-safe logging
logger.info('User authenticated: userId=${user.id}'); // ok — id, not email
logger.debug('Payment processed: orderId=$orderId'); // ok — no card data
// ❌ Wrong: PII in logs
logger.info('Login: email=${user.email}, phone=${user.phone}'); // NEVER
// ✅ Correct: --dart-define for secrets (build arg, not in code)
// flutter build apk --dart-define=API_KEY=$API_KEY
const apiKey = String.fromEnvironment('API_KEY'); // acceptable
// ✅ Correct: certificate pinning with Dio
(dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () {
final client = HttpClient();
client.badCertificateCallback = (cert, host, port) => false; // strict
return client;
};
```
## Deep linking & intent security
- Validate all incoming deep link parameters — never trust raw URL params
- Use `app_links` package for verified deep link handling
- Restrict URL schemes to known patterns — reject unknown schemes
- For OAuth callbacks: validate `state` parameter to prevent CSRF
## Storage security
- Encrypt locally cached sensitive data using `hive` with `HiveAesCipher`
- Clear sensitive data from memory after use (set to null, trigger GC)
- Do NOT cache auth tokens in network layer (no `dio_cache_interceptor` for auth endpoints)
- Use `SecureRandom` for nonce/token generation — never `Random()`
## Code obfuscation & binary protection
```yaml
# android/app/build.gradle — release config
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
```
```bash
# Flutter release build with obfuscation
flutter build apk --release --obfuscate --split-debug-info=build/debug-symbols/
flutter build ipa --release --obfuscate --split-debug-info=build/debug-symbols/
```
## Release checklist
Before every production release, verify:
- [ ] No hardcoded secrets (`grep -r "api_key\|secret\|password\|token" lib/`)
- [ ] Debug flags disabled (`kDebugMode` guards on all debug-only paths)
- [ ] Obfuscation enabled in release build config
- [ ] Certificate pinning active and tested on both platforms
- [ ] Crash reporter PII filters configured (Sentry `beforeSend`, Firebase `setConsentType`)
- [ ] `flutter_secure_storage` used for all tokens — no `SharedPreferences` for sensitive keys
- [ ] Network calls all HTTPS — scan for `http://` in lib/
- [ ] Dependencies audited: `dart pub outdated --json | jq '.packages[] | select(.isDiscontinued)'`
- [ ] Deep link parameters validated
- [ ] App transport security / network security config reviewed