Platform Security

Security Architecture

A transparent overview of how MAISNER protects user data, credentials, and platform integrity. We believe security should be visible, not hidden.

Automated Security Audit Passed — MAISNER codebase scanned with Bandit v1.9.4 on 11 Apr 2026. Result: 0 High severity issues in application code (21,923 lines scanned).

Transport & Network

HTTPS / TLS

All traffic is encrypted via TLS 1.2 and 1.3. HTTP requests are permanently redirected to HTTPS. HSTS is enforced with a 1-year max-age, preventing protocol downgrade attacks.

LET'S ENCRYPT · AUTO-RENEW
Rate Limiting

Two-layer rate limiting: nginx blocks excessive requests at the network edge (30 req/min general, 60/min API per IP). FastAPI middleware adds per-user limits on compute-intensive endpoints.

NGINX + PYTHON LAYER
Security Headers

All responses include: Strict-Transport-Security, X-Frame-Options (DENY), X-Content-Type-Options (nosniff), X-XSS-Protection, Referrer-Policy, and Permissions-Policy.

OWASP RECOMMENDED
Reverse Proxy

Nginx sits in front of the application server, handling TLS termination, rate limiting, and request forwarding. The application port (8000) is not exposed publicly.

NGINX · UBUNTU 24.04

Authentication & Access Control

JWT Authentication

User sessions are managed via signed JSON Web Tokens. Tokens are short-lived and validated server-side on every request. No session state is stored on the server.

HS256 · STATELESS
Password Storage

Passwords are hashed using bcrypt with a cost factor of 12. Plain-text passwords are never stored or logged. Even in the event of a data breach, passwords cannot be recovered.

BCRYPT · COST 12
Role-Based Access

Admin endpoints are protected server-side with role verification on every request. Admin UI elements are hidden client-side, but access is enforced at the API level (HTTP 403 for unauthorized requests).

SERVER-SIDE ENFORCEMENT
Portfolio Isolation

Each user's portfolios are stored in isolated directories scoped to their username. API endpoints validate ownership on every read/write operation. Cross-user data access is not possible.

PATH ISOLATION

Data Protection

Automated Backups

Full platform backups run nightly at 03:00 UTC via cron. Rotation policy: 7 daily, 8 weekly, 12 monthly snapshots. Backups include all user portfolios, configurations, and application files.

DAILY · 7+8+12 ROTATION
Action Logging

All significant user actions are logged with timestamps, user identity, and operation details. Logs are retained and accessible via the admin panel for audit purposes.

JSONL · APPEND-ONLY
No Third-Party Tracking

Platform analytics are self-hosted (Umami) on the same infrastructure. No data is sent to Google, Meta, or any advertising platform. Analytics are GDPR-compliant and privacy-first.

SELF-HOSTED · GDPR
Market Data

Market data is fetched from FMP Professional and Polygon APIs over HTTPS. API keys are stored as environment variables and never exposed in application code or client-side responses.

ENV VARS · NEVER CLIENT-SIDE

Automated Security Audit Results

MAISNER application code (21,923 lines across all Python modules) was scanned with Bandit v1.9.4 on 11 April 2026. Only issues in MAISNER's own code are reported — third-party library internals are excluded.

OVERALL 0 High Severity Issues Found PASS
No critical vulnerabilities detected in application code. No SQL injection, no command injection, no hardcoded credentials, no insecure deserialization of untrusted data.
B307 eval() in Strategy Builder (backtest_engine.py) MEDIUM · KNOWN
The Strategy Builder allows authenticated users to define custom factor expressions using eval(). This is intentional functionality (DSL for quant strategies) accessible only to logged-in users. Mitigation in progress: sandboxed expression parser with operator whitelist.
B314 XML parsing in IB integration (stock_updater_ib.py) MEDIUM · LOW RISK
Interactive Brokers XML responses are parsed with stdlib xml.etree. Data source is trusted (IB API over authenticated connection). Scheduled for migration to defusedxml in next release.
B104 host="0.0.0.0" binding FALSE POSITIVE
Application binds to all interfaces as required for nginx proxy configuration. Port 8000 is not exposed publicly — nginx handles all external traffic. This is standard production deployment practice.

Infrastructure

ServerDigitalOcean · Amsterdam (AMS3) · Ubuntu 24.04 LTS
KernelLinux 6.8.0-107-generic (latest)
TLS CertificateLet's Encrypt · Expires 2026-07-06 · Auto-renewal enabled
ApplicationPython 3.13 · FastAPI · Uvicorn · systemd managed
ProxyNginx · TLS 1.2 + 1.3 · Rate limiting · Security headers
AnalyticsUmami (self-hosted) · PostgreSQL · No external tracking
BackupsDaily cron 03:00 UTC · 7 daily / 8 weekly / 12 monthly
Audit ToolBandit v1.9.4 · Last scan: 11 Apr 2026 · 0 High issues

Responsible Disclosure

If you discover a security vulnerability in MAISNER, please report it responsibly. Do not publicly disclose issues before we have had the opportunity to address them. Contact: maisnerplatform@gmail.com