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 via Dio interceptor
- Token-based authentication using
markedeer_oauthpackage - Security concern: Access tokens and refresh tokens stored in plain text in SQLite database (Drift)
- Tokens persist across app restarts without encryption
- Username, email, UID, and login status also stored unencrypted in database
- No token expiration validation on client side
Evidence:
lib/singletons/dio_singleton.dart: OAuth2 token refresh on 401 errors (lines 73-125)lib/states/session_state.dart: Tokens stored directly in database as plain stringsaccessTokenstored directly (lines 86-92)refreshTokenstored directly (lines 94-100)username,uid,emailstored unencrypted (lines 62-84)
lib/database/database.dart: Drift/SQLite database used for storage- No encryption libraries or secure storage packages in
pubspec.yaml
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
- Add token expiration validation on client side
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
- Drift/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
- General key-value storage used for all sensitive data without encryption
Evidence:
lib/states/session_state.dart: All sensitive data stored as plain strings in databaseaccessTokenstored directly (line 90)refreshTokenstored directly (line 98)username,uid,emailstored unencrypted (lines 64, 80, 72)
lib/database/database.dart: Drift database implementation without encryption layer (lines 13-19)- No encryption libraries or secure storage packages in
pubspec.yaml - Database file location: App's data directory (accessible on rooted/jailbroken devices)
lib/database/daos/general_dao.dart: General DAO used for key-value storage of sensitive data
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: ⚠️Warning
Findings:
- Certificate validation appears to be enabled by default (no HTTP overrides found)
- Commented-out code in
dio_singleton.dartshows a previously disabledbadCertificateCallbackthat would accept all certificates - No certificate pinning implemented
- No SSL/TLS version enforcement
- Firebase Performance monitoring enabled for network requests
- 30-second connection timeout and 20-second receive timeout configured
Evidence:
lib/singletons/dio_singleton.dart:- Commented-out
badCertificateCallbackthat would accept all certificates (lines 95-101) - currently disabled - No active certificate validation override
- Firebase Performance interceptor added (line 27)
- Commented-out
lib/main_prod.dartandlib/main_staging.dart: No HTTP overrides configured- No certificate pinning implementation found
- No SSL/TLS version enforcement
- Dio configured with standard timeouts (lines 23-24)
Risk Level: Medium Risk
Recommendation:
- Immediate actions:
- Remove commented-out certificate validation bypass code
- Implement proper certificate pinning using
certificate_pinningor similar package - Short-term:
- Implement certificate pinning for API endpoints
- Add SSL/TLS version checks (enforce TLS 1.2+)
- Consider implementing certificate transparency monitoring
1.4 Secrets & Credentials Management
Status: ❌Fail
Findings:
- Critical: Sensitive files including keystores are stored directly in the repository
- Android certificates and keys:
android-assets/gulfforyou.keystore.jks- Android signing keystore stored in repository- Keystore file accessible in version control
- No centralized secrets management system
- Risk of credentials being exposed in version control history
- Keystore file should not be in repository, even if password-protected
- CI/CD uses Codemagic secrets management for signing, but keystore file still present in repo
Evidence:
android-assets/directory contains keystore fileandroid-assets/gulfforyou.keystore.jks- Keystore file in repositoryandroid-assets/keystore-readme.txt- Documentation for keystore usagecodemagic.yaml: Uses Codemagic secrets management (gulf-android-keystore) for CI/CD signing.gitignoremay not exclude sensitive directories- Keystore file visible in repository
Risk Level: Critical Risk
Recommendation:
- Immediate actions:
- Move keystore file to centralized secrets management (e.g., AWS Secrets Manager, HashiCorp Vault, or secure cloud storage)
- Remove keystore file from repository (after backing up to secure location)
- Add sensitive directories to
.gitignore:android-assets/ - Rotate keystore if it has been exposed in version control history
- Short-term:
- Ensure CI/CD pipeline uses only secure secrets management (already using Codemagic secrets)
- Document proper keystore management procedures
- Remove keystore file from repository entirely
1.5 Code Obfuscation & Reverse Engineering
Status: ❌Fail
Findings:
- Critical: Code obfuscation and minification not configured in Android release builds
- No
minifyEnabledorshrinkResourcessettings found inbuild.gradle - ProGuard rules file exists (
proguard-rules.pro) but may not be used - No R8 code shrinking enabled
- Source code, API endpoints, and business logic easily reverse-engineerable
- No string encryption or code protection mechanisms
- No Flutter obfuscation flags in build commands
Evidence:
android/app/build.gradle: NominifyEnabledorshrinkResourcesin release build type (lines 93-100)android/app/proguard-rules.pro: ProGuard rules file exists but may not be used- No Flutter obfuscation flags (
--obfuscate) 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
- Enable R8 code shrinking for Android
- Use Flutter's
--obfuscateflag for release builds - Short-term:
- Enable ProGuard/R8 with proper rules
- Review and update ProGuard rules to ensure all necessary classes are preserved
- Consider additional string encryption for sensitive API endpoints or keys