1. Security Assessment
Security Issues Overview
1.1 Authentication & Authorization
Status: ⚠️Warning
Findings:
- OAuth2 token-based authentication implemented with access and refresh tokens
- Automatic token refresh mechanism on 401 errors
- Social login support (Facebook, Google, Apple Sign In)
- Security concern: Access tokens and refresh tokens stored in plain text in SQLite database
- Tokens persist across app restarts without encryption
- No token expiration validation on client side
- Username and UID also stored unencrypted in database
Evidence:
lib/rest_client.dart: OAuth2 endpoints (/app/oauth/token/mobile,/app/oauth/social/mobile)lib/state_models/session_state.dart: Tokens stored directly in database as plain strings (lines 84-106)lib/base_singleton.dart: Automatic token refresh on 401 errors (lines 114-151)lib/db/database.dart: Moor/SQLite database used for storagelib/routes/login_route.dart: Login flow stores tokens without encryption
Risk Level: Medium Risk
Recommendation:
- Encrypt sensitive tokens before storing in database using Flutter's secure storage (e.g.,
flutter_secure_storage) - Use Android Keystore/iOS Keychain for storing sensitive credentials
- Implement proper token revocation on logout
1.2 Data Storage & Encryption
Status: ❌Fail
Findings:
- Critical: Sensitive authentication data stored in plain text in SQLite database
- Access tokens, refresh tokens, usernames, UIDs, and email addresses stored unencrypted
- Moor/SQLite database file accessible on device without encryption
- No encryption at rest for sensitive user data
- Database file can be extracted from device and read directly
- No use of platform secure storage (Android Keystore/iOS Keychain) for sensitive data
Evidence:
lib/state_models/session_state.dart: All sensitive data stored as plain strings in databaseaccessTokenstored directly (line 88)refreshTokenstored directly (line 104)username,uid,emailstored unencrypted (lines 64, 80, 72)lib/db/database.dart: Moor database implementation without encryption layer- No encryption libraries or secure storage packages in
pubspec.yaml - Database file location: App's data directory (accessible on rooted/jailbroken devices)
Risk Level: High Risk
Recommendation:
- Immediate actions:
- Migrate sensitive data to
flutter_secure_storagepackage - Use Android Keystore and iOS Keychain for credential storage
- Encrypt database file or sensitive columns using SQLCipher
- Remove plain text storage of tokens and credentials
- Short-term:
- Implement database encryption for all sensitive fields
- Use platform-specific secure storage APIs
1.3 Network Security
Status: ❌Fail
Findings:
- Critical: Certificate validation can be disabled via remote configuration
OnlyAllowTinqOverrideaccepts invalid SSL certificates for specific host without proper validation- Certificate validation controlled by Firebase Remote Config flag
override_bad_certificates - No certificate pinning implemented
- Hostname validation only checks for exact match, not certificate chain validation
AllowAllOverrideclass exists (though not used in production) that accepts all certificates- Remote config can dynamically enable/disable certificate validation, creating security risk
Evidence:
lib/utils/http_overrides.dart:OnlyAllowTinqOverrideaccepts certificates for "max.korting.tinq.nl" without proper validation (lines 15-23)AllowAllOverrideaccepts all certificates (lines 5-12) - dangerous patternlib/main.dartandlib/main_prod.dart:HttpOverrides.global = OnlyAllowTinqOverride()(line 27)- Remote config can override:
FirebaseRemoteConfig.instance.getBool('override_bad_certificates')(lines 38-40) - Default sets
override_bad_certificates: true(line 30) - No certificate pinning implementation found
- No SSL/TLS version enforcement
Risk Level: Critical Risk
Recommendation:
- Immediate actions:
- Remove certificate validation override functionality
- Remove
AllowAllOverrideclass entirely - Implement proper certificate pinning using
certificate_pinningor similar package - Remove remote config flag that controls certificate validation
- Enforce strict SSL/TLS validation
- Short-term:
- Implement certificate pinning for API endpoints
- Add SSL/TLS version checks (enforce TLS 1.2+)
- Remove ability to disable certificate validation via remote config
1.4 Secrets & Credentials Management
Status: ❌Fail
Findings:
- Critical: Sensitive files including certificates, private keys, and service account credentials are stored directly in the repository
- Android certificates and keys:
android-src-files/tinq4u.keystore.jks- Android signing keystoreandroid-src-files/private_key.pepk- Private key fileandroid-src-files/deployment_cert.der- Deployment certificateandroid-src-files/upload_cert.der- Upload certificateandroid-src-files/fastlane-serivce-account.json- Google Play service account with embedded private keyandroid-src-files/google-services.json- Firebase configuration- Apple certificates and keys:
apple-src-files/Signin-with-apple-AuthKey_63ZBT4A89B.p8- Apple Sign In private keyapple-src-files/ApplePushServices.certSigningRequest- Certificate signing requestsrc-assets/AuthKey_9BWX5U9947.p8- Additional Apple private key- Hardcoded path reference to sensitive file in
android/fastlane/Appfile - No centralized secrets management system
- Risk of credentials being exposed in version control history
- No
.gitignoreentries for sensitive directories (android-src-files/,apple-src-files/,src-assets/)
Evidence:
android-src-files/directory contains multiple sensitive filesapple-src-files/directory contains Apple private keyssrc-assets/AuthKey_9BWX5U9947.p8contains private key in repositoryandroid/fastlane/Appfileline 1: Hardcoded path to service account JSON.gitignoredoes not exclude sensitive directories- Private keys visible in search results (PEM format)
Risk Level: Critical Risk
Recommendation:
- Immediate actions:
- Move all sensitive files to centralized secrets management (e.g., AWS Secrets Manager, HashiCorp Vault, or secure cloud storage)
- Remove sensitive files from repository (after backing up to secure location)
- Add sensitive directories to
.gitignore:android-src-files/,apple-src-files/,src-assets/ - Rotate all exposed credentials (keystores, service accounts, private keys)
- Update
android/fastlane/Appfileto reference secrets from secure location - Short-term:
- Implement secrets injection in CI/CD pipeline (Codemagic secrets management)
- Use environment variables or secure file injection for build-time secrets
1.6 Code Obfuscation & Reverse Engineering
Status: ❌Fail
Findings:
- Critical: Code obfuscation and minification disabled in release builds
minifyEnabled = falseandshrinkResources = falsein Android release configuration- ProGuard rules file exists but not used (obfuscation disabled)
- No R8 code shrinking enabled
- Source code, API endpoints, and business logic easily reverse-engineerable
- No string encryption or code protection mechanisms
- Comment in build.gradle indicates minification disabled due to crashes (technical debt)
Evidence:
android/app/build.gradlelines 100-106:
release {
signingConfig signingConfigs.release
// Turning off any type of minification to mitigate still unknown
// crashes on certain devices.
minifyEnabled false
shrinkResources false
}
android/app/proguard-rules.pro: ProGuard rules exist but unused- No Flutter obfuscation flags in build commands
- No code protection or anti-tampering measures
Risk Level: High Risk
Recommendation:
- Immediate actions:
- Enable code obfuscation and minification for release builds
- Investigate and fix crashes that prevented minification
- Enable R8 code shrinking for Android
- Use Flutter's
--obfuscateflag for release builds - Short-term:
- Enable ProGuard/R8 with proper rules