Security Guide

Defense-in-depth protections built into the Everything App.

Security Architecture

The Everything App implements multiple layers of security to protect against common attack vectors in mobile/web applications.

๐Ÿ›ก๏ธ SSRF Prevention

URL scheme allowlisting and trusted host validation prevent server-side request forgery via malicious API responses.

๐Ÿ’‰ SQL Injection Prevention

All database queries use parameterized bindings (whereArgs). No string interpolation in SQL.

๐Ÿ”‘ Credential Security

API keys loaded from environment variables via --dart-define. Never hardcoded in source.

๐Ÿ” Secure Storage

Sensitive data stored via flutter_secure_storage (Keychain on iOS, EncryptedSharedPreferences on Android).

SSRF Protection

Server-Side Request Forgery (SSRF) is a critical vulnerability where an attacker tricks the application into making requests to unintended URLs. This is particularly relevant when following pagination links from external APIs.

The Attack Vector

When fetching calendar events from Microsoft Graph, the API returns @odata.nextLink for pagination. A malicious or compromised API could set this to an internal URL:

// Malicious response { "value": [...], "@odata.nextLink": "http://169.254.169.254/latest/meta-data/" // โ† Cloud metadata! }

Our Defenses

1. Scheme Allowlist

HttpUtils._validateUrl() rejects any URL not using https:

// AppConstants.allowedSchemes = ['https'] // Blocks: http://, file://, ftp://, gopher://, etc.

2. Trusted Host Validation

Pagination URLs are validated against AppConstants.trustedApiHosts:

// Only these hosts are trusted for pagination: static const trustedApiHosts = [ 'graph.microsoft.com', 'api.example.com', ]; // First request: our own URL (trusted by construction) // Subsequent requests: validated against trustedApiHosts HttpUtils.getRequest(nextUrl, requireTrustedHost: page > 0);

3. Pagination Limit

GraphService._maxPages = 50 prevents infinite pagination loops from malformed responses.

SQL Injection Prevention

All database operations use sqflite's parameterized query API:

// โœ… Safe โ€” parameterized binding db.delete('events', where: 'id = ?', whereArgs: [id]); // โŒ Vulnerable โ€” never do this db.rawDelete("DELETE FROM events WHERE id = '$id'");

Authentication Security

Dependency Security

Reporting Vulnerabilities

If you discover a security vulnerability, please report it responsibly:

  1. Do not open a public GitHub issue
  2. Email the maintainer or use GitHub's private vulnerability reporting
  3. Include: description, reproduction steps, impact assessment
  4. Allow reasonable time for a fix before disclosure