freezone/portal-server/SECURITY.md
2025-06-30 17:01:40 +02:00

11 KiB

Portal Server Security Analysis

Executive Summary

The Portal Server implements a multi-layered security approach for handling sensitive KYC verification and payment processing operations. This document provides a comprehensive analysis of the current security posture, identifies potential vulnerabilities, and recommends security enhancements.

Current Security Implementation

Implemented Security Features

1. Feature-Based CORS Configuration

  • Development Mode: Permissive CORS for local development
  • Production Mode: Strict origin restrictions with configurable allowed domains
  • Implementation: src/server.rs:113-150
#[cfg(feature = "prod")]
{
    let mut cors = CorsLayer::new()
        .allow_methods([http::Method::GET, http::Method::POST])
        .allow_headers(Any);
    // Restricted to configured origins only
}

2. Webhook Signature Verification

3. Input Validation

  • Request Validation: All endpoints validate required fields
  • Configuration Validation: Server startup validates required API keys
  • Implementation: src/server.rs:96-110

4. Environment Variable Protection

  • Sensitive Data: API keys stored in environment variables
  • Configuration: Support for .env files with validation
  • Implementation: src/config.rs:33-59

5. Error Handling

  • Information Disclosure: Controlled error responses without sensitive data exposure
  • Logging: Structured logging with appropriate log levels
  • Implementation: src/handlers.rs:47-64

Security Architecture

graph TB
    subgraph "Client Applications"
        A[Portal WASM App]
        B[Admin Dashboard]
    end
    
    subgraph "Portal Server Security Layers"
        C[CORS Layer]
        D[Input Validation]
        E[Request Handlers]
        F[Service Layer]
    end
    
    subgraph "External Services"
        G[Stripe API]
        H[Identify API]
    end
    
    subgraph "Security Controls"
        I[Webhook Signature Verification]
        J[Environment Variable Protection]
        K[Error Handling]
        L[Logging & Monitoring]
    end
    
    A --> C
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    F --> H
    
    I --> E
    J --> F
    K --> E
    L --> E

Threat Model

High-Risk Threats

1. API Key Compromise

  • Risk: Unauthorized access to Stripe/Identify services
  • Impact: Financial fraud, data breach, service disruption
  • Mitigation: Environment variable protection, key rotation

2. Webhook Spoofing

  • Risk: Malicious webhook payloads bypassing verification
  • Impact: False payment confirmations, data manipulation
  • Mitigation: Signature verification (partially implemented)

3. Cross-Origin Attacks

  • Risk: Unauthorized cross-origin requests
  • Impact: Data theft, CSRF attacks
  • Mitigation: Feature-based CORS restrictions

Medium-Risk Threats

4. Data Injection Attacks

  • Risk: Malicious input in payment/KYC data
  • Impact: Data corruption, service disruption
  • Mitigation: Input validation, sanitization

5. Rate Limiting Bypass

  • Risk: API abuse, DoS attacks
  • Impact: Service degradation, increased costs
  • Mitigation: Not currently implemented

6. Information Disclosure

  • Risk: Sensitive data in logs/errors
  • Impact: Data breach, compliance violations
  • Mitigation: Controlled error responses

Security Gaps & Recommendations

🔴 Critical Security Gaps

1. Incomplete Webhook Signature Verification

Current State: Placeholder implementation

// src/services.rs:83-90
pub fn verify_webhook_signature(&self, _payload: &str, signature: &str) -> bool {
    // For now, we'll just check that the signature is not empty
    !signature.is_empty()
}

Recommendation: Implement proper HMAC-SHA256 verification

use hmac::{Hmac, Mac};
use sha2::Sha256;

pub fn verify_webhook_signature(&self, payload: &str, signature: &str, secret: &str) -> bool {
    let mut mac = Hmac::<Sha256>::new_from_slice(secret.as_bytes()).unwrap();
    mac.update(payload.as_bytes());
    let expected = mac.finalize().into_bytes();
    let provided = hex::decode(signature.trim_start_matches("sha256=")).unwrap_or_default();
    expected.as_slice() == provided.as_slice()
}

2. No API Authentication

Current State: All endpoints are publicly accessible Recommendation: Implement API key authentication middleware

async fn api_key_middleware(
    headers: HeaderMap,
    request: Request<Body>,
    next: Next<Body>
) -> Result<Response, StatusCode> {
    let api_key = headers.get("x-api-key")
        .and_then(|v| v.to_str().ok())
        .ok_or(StatusCode::UNAUTHORIZED)?;
    
    if !validate_api_key(api_key) {
        return Err(StatusCode::UNAUTHORIZED);
    }
    
    Ok(next.run(request).await)
}

3. In-Memory Session Storage

Current State: Verification sessions stored in HashMap Security Risk: Data loss on restart, no persistence, no encryption Recommendation: Implement encrypted database storage with TTL

🟡 Important Security Enhancements

4. Rate Limiting

Recommendation: Implement per-IP and per-endpoint rate limiting

use tower_governor::{GovernorLayer, GovernorConfigBuilder};

let governor_conf = GovernorConfigBuilder::default()
    .per_second(10)
    .burst_size(20)
    .finish()
    .unwrap();

router.layer(GovernorLayer::new(&governor_conf))

5. Request Size Limits

Recommendation: Add request body size limits

use tower_http::limit::RequestBodyLimitLayer;

router.layer(RequestBodyLimitLayer::new(1024 * 1024)) // 1MB limit

6. Security Headers

Recommendation: Add security headers middleware

use tower_http::set_header::SetResponseHeaderLayer;

router.layer(SetResponseHeaderLayer::overriding(
    header::X_CONTENT_TYPE_OPTIONS,
    HeaderValue::from_static("nosniff")
))

Compliance Considerations

PCI DSS Compliance (Payment Processing)

  • Requirement 1: Firewall configuration (network level)
  • Requirement 2: Default passwords changed (API keys)
  • ⚠️ Requirement 3: Cardholder data protection (delegated to Stripe)
  • Requirement 4: Encryption in transit (HTTPS required)
  • Requirement 6: Secure development (needs security testing)
  • Requirement 8: Access control (no authentication implemented)
  • Requirement 10: Logging and monitoring (basic logging only)
  • Requirement 11: Security testing (not implemented)

GDPR Compliance (Data Protection)

  • ⚠️ Data Minimization: Only collect necessary KYC data
  • Data Encryption: No encryption at rest implemented
  • ⚠️ Data Retention: No automatic data deletion
  • Audit Logging: Limited audit trail
  • Data Subject Rights: No data export/deletion endpoints

Security Testing Strategy

1. Automated Security Testing

# Dependency vulnerability scanning
cargo audit

# Static analysis
cargo clippy -- -W clippy::all

# Security-focused linting
cargo semver-checks

2. Penetration Testing Checklist

  • CORS bypass attempts
  • Webhook signature bypass
  • Input validation bypass
  • Rate limiting bypass
  • Information disclosure
  • Authentication bypass
  • Authorization bypass

3. Security Monitoring

// Implement security event logging
use tracing::{warn, error};

// Log security events
warn!(
    user_id = %user_id,
    ip_address = %client_ip,
    event = "failed_authentication",
    "Authentication attempt failed"
);

Incident Response Plan

1. Security Incident Classification

  • P0 Critical: API key compromise, data breach
  • P1 High: Service disruption, authentication bypass
  • P2 Medium: Rate limiting bypass, information disclosure
  • P3 Low: Security configuration issues

2. Response Procedures

  1. Immediate Response (0-1 hour)

    • Isolate affected systems
    • Revoke compromised credentials
    • Enable emergency rate limiting
  2. Investigation (1-24 hours)

    • Analyze logs and traces
    • Determine scope of impact
    • Document findings
  3. Recovery (24-72 hours)

    • Implement fixes
    • Restore services
    • Update security controls
  4. Post-Incident (1-2 weeks)

    • Conduct post-mortem
    • Update security procedures
    • Implement preventive measures

Security Configuration Guide

Production Deployment Checklist

Environment Configuration

# Required security environment variables
STRIPE_SECRET_KEY=sk_live_...           # Production Stripe key
STRIPE_WEBHOOK_SECRET=whsec_...         # Webhook verification
IDENTIFY_API_KEY=identify_prod_...      # Production Identify key
CORS_ORIGINS=https://app.freezone.com   # Restrict origins

Build Configuration

# Production build with security features
cargo build --release --features prod --no-default-features

Runtime Security

# Run with restricted permissions
./portal-server \
  --host 0.0.0.0 \
  --port 3001 \
  --from-env \
  --cors-origins "https://app.freezone.com,https://portal.freezone.com"

Development Security

# Development build (permissive CORS)
cargo build --features dev

# Local development
./portal-server --from-env --verbose --cors-origins "*"

Security Metrics & Monitoring

Key Security Metrics

  1. Authentication Failures: Failed API key validations
  2. Webhook Verification Failures: Invalid signatures
  3. Rate Limit Violations: Exceeded request limits
  4. CORS Violations: Blocked cross-origin requests
  5. Input Validation Failures: Malformed requests

Monitoring Implementation

use prometheus::{Counter, Histogram, register_counter, register_histogram};

lazy_static! {
    static ref AUTH_FAILURES: Counter = register_counter!(
        "auth_failures_total",
        "Total number of authentication failures"
    ).unwrap();
    
    static ref REQUEST_DURATION: Histogram = register_histogram!(
        "request_duration_seconds",
        "Request duration in seconds"
    ).unwrap();
}

Conclusion

The Portal Server implements foundational security controls but requires significant enhancements for production deployment. Priority should be given to:

  1. Immediate: Implement proper webhook signature verification
  2. Short-term: Add API authentication and rate limiting
  3. Medium-term: Implement persistent encrypted storage
  4. Long-term: Achieve PCI DSS and GDPR compliance

Regular security assessments and penetration testing should be conducted to maintain security posture as the system evolves.


Document Version: 1.0
Last Updated: 2025-06-29
Next Review: 2025-09-29
Classification: Internal Use Only