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_oauth package
  • 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 strings
    • accessToken stored directly (lines 86-92)
    • refreshToken stored directly (lines 94-100)
    • username, uid, email stored 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 database
    • accessToken stored directly (line 90)
    • refreshToken stored directly (line 98)
    • username, uid, email stored 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_storage package
  • 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.dart shows a previously disabled badCertificateCallback that 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 badCertificateCallback that would accept all certificates (lines 95-101) - currently disabled
    • No active certificate validation override
    • Firebase Performance interceptor added (line 27)
  • lib/main_prod.dart and lib/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_pinning or 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 file
  • android-assets/gulfforyou.keystore.jks - Keystore file in repository
  • android-assets/keystore-readme.txt - Documentation for keystore usage
  • codemagic.yaml: Uses Codemagic secrets management (gulf-android-keystore) for CI/CD signing
  • .gitignore may 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 minifyEnabled or shrinkResources settings found in build.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: No minifyEnabled or shrinkResources in 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 --obfuscate flag 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