Sistema NEXUS v3.4 migrado con: Estructura principal: - core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles) - core/catalog: Catalogo de funcionalidades reutilizables - shared/knowledge-base: Base de conocimiento compartida - devtools/scripts: Herramientas de desarrollo - control-plane/registries: Control de servicios y CI/CD - orchestration/: Configuracion de orquestacion de agentes Proyectos incluidos (11): - gamilit (submodule -> GitHub) - trading-platform (OrbiquanTIA) - erp-suite con 5 verticales: - erp-core, construccion, vidrio-templado - mecanicas-diesel, retail, clinicas - betting-analytics - inmobiliaria-analytics - platform_marketing_content - pos-micro, erp-basico Configuracion: - .gitignore completo para Node.js/Python/Docker - gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git) - Sistema de puertos estandarizado (3005-3199) Generated with NEXUS v3.4 Migration System EPIC-010: Configuracion Git y Repositorios
814 lines
18 KiB
Markdown
814 lines
18 KiB
Markdown
# Security Guide
|
|
|
|
## Overview
|
|
|
|
OrbiQuant IA maneja datos financieros sensibles (fondos de usuarios, órdenes de trading, información personal) por lo que la seguridad es **crítica**. Este documento describe las medidas de seguridad implementadas y best practices.
|
|
|
|
## Threat Model
|
|
|
|
### Assets to Protect
|
|
|
|
1. **User Funds:** Dinero en wallets internos y exchanges
|
|
2. **Personal Data:** Email, nombre, dirección, documentos KYC
|
|
3. **Trading Data:** Posiciones, órdenes, estrategias
|
|
4. **API Keys:** Claves de exchanges de usuarios
|
|
5. **Financial Data:** Transacciones, balances, historial
|
|
6. **ML Models:** Modelos propietarios de predicción
|
|
|
|
### Attack Vectors
|
|
|
|
1. **Credential Theft:** Phishing, keyloggers, brute force
|
|
2. **API Abuse:** Rate limiting bypass, scraping, DDoS
|
|
3. **SQL Injection:** Malicious queries
|
|
4. **XSS:** Cross-site scripting attacks
|
|
5. **CSRF:** Cross-site request forgery
|
|
6. **Man-in-the-Middle:** Traffic interception
|
|
7. **Insider Threats:** Malicious employees
|
|
8. **Supply Chain:** Compromised dependencies
|
|
|
|
## Authentication & Authorization
|
|
|
|
### Multi-Factor Authentication (MFA)
|
|
|
|
**Implementation:** TOTP (Time-based One-Time Password) using Speakeasy
|
|
|
|
```typescript
|
|
// Enable 2FA
|
|
POST /api/auth/2fa/enable
|
|
Response: {
|
|
"secret": "JBSWY3DPEHPK3PXP",
|
|
"qrCode": "data:image/png;base64,..."
|
|
}
|
|
|
|
// Verify 2FA setup
|
|
POST /api/auth/2fa/verify
|
|
{
|
|
"token": "123456"
|
|
}
|
|
|
|
// Login with 2FA
|
|
POST /api/auth/login
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "password",
|
|
"totpCode": "123456" // Required if 2FA enabled
|
|
}
|
|
```
|
|
|
|
**Enforcement:**
|
|
- Mandatory for withdrawals > $1000
|
|
- Mandatory for API key generation
|
|
- Mandatory for admin accounts
|
|
- Optional for regular trading
|
|
|
|
### OAuth2 Integration
|
|
|
|
**Supported Providers:**
|
|
- Google (OAuth 2.0)
|
|
- Facebook
|
|
- Apple Sign-In
|
|
- GitHub
|
|
|
|
**Security Features:**
|
|
- State parameter for CSRF protection
|
|
- PKCE (Proof Key for Code Exchange) for mobile
|
|
- Token validation with provider APIs
|
|
- Automatic account linking
|
|
|
|
```typescript
|
|
// OAuth flow
|
|
GET /api/auth/oauth/google
|
|
→ Redirects to Google
|
|
→ User authorizes
|
|
→ Callback to /api/auth/oauth/google/callback
|
|
→ Validates state and code
|
|
→ Exchanges code for tokens
|
|
→ Creates/links user account
|
|
→ Returns JWT
|
|
```
|
|
|
|
### JWT (JSON Web Tokens)
|
|
|
|
**Token Types:**
|
|
|
|
1. **Access Token**
|
|
- Lifetime: 1 hour
|
|
- Used for API requests
|
|
- Stored in memory (not localStorage)
|
|
|
|
2. **Refresh Token**
|
|
- Lifetime: 30 days
|
|
- Used to get new access tokens
|
|
- Stored in httpOnly cookie
|
|
- Rotation on each use
|
|
|
|
**Token Structure:**
|
|
|
|
```json
|
|
{
|
|
"header": {
|
|
"alg": "HS256",
|
|
"typ": "JWT"
|
|
},
|
|
"payload": {
|
|
"sub": "user-uuid",
|
|
"email": "user@example.com",
|
|
"role": "user",
|
|
"iat": 1670832000,
|
|
"exp": 1670835600
|
|
},
|
|
"signature": "..."
|
|
}
|
|
```
|
|
|
|
**Security Measures:**
|
|
- Strong secret (256-bit minimum)
|
|
- Short-lived access tokens
|
|
- Refresh token rotation
|
|
- Token revocation on logout
|
|
- Blacklist for compromised tokens
|
|
|
|
### Role-Based Access Control (RBAC)
|
|
|
|
**Roles:**
|
|
|
|
| Role | Permissions |
|
|
|------|-------------|
|
|
| **user** | Trading, portfolio, courses |
|
|
| **premium** | Advanced features, higher limits |
|
|
| **trader** | Create strategies, copy trading |
|
|
| **admin** | User management, system config |
|
|
| **super_admin** | Full system access |
|
|
|
|
**Permission Checking:**
|
|
|
|
```typescript
|
|
// Middleware
|
|
const requireRole = (roles: string[]) => {
|
|
return (req, res, next) => {
|
|
if (!roles.includes(req.user.role)) {
|
|
return res.status(403).json({ error: 'Forbidden' });
|
|
}
|
|
next();
|
|
};
|
|
};
|
|
|
|
// Usage
|
|
router.post('/admin/users', requireRole(['admin', 'super_admin']), createUser);
|
|
```
|
|
|
|
### Session Management
|
|
|
|
**Features:**
|
|
- Device tracking (browser, OS, IP)
|
|
- Active session list
|
|
- Concurrent session limits (max 5)
|
|
- Session revocation (logout other devices)
|
|
- Automatic logout after 24h inactivity
|
|
|
|
```typescript
|
|
GET /api/auth/sessions
|
|
Response: {
|
|
"sessions": [
|
|
{
|
|
"id": "session-uuid",
|
|
"device": "Chrome on Windows",
|
|
"ip": "192.168.1.1",
|
|
"lastActivity": "2025-12-12T10:00:00Z",
|
|
"current": true
|
|
}
|
|
]
|
|
}
|
|
|
|
DELETE /api/auth/sessions/:sessionId // Logout specific session
|
|
DELETE /api/auth/sessions // Logout all except current
|
|
```
|
|
|
|
## Data Protection
|
|
|
|
### Encryption at Rest
|
|
|
|
**Database:**
|
|
- PostgreSQL with pgcrypto extension
|
|
- Encrypted columns for sensitive data:
|
|
- API keys (AES-256)
|
|
- Social security numbers
|
|
- Bank account numbers
|
|
- Private keys
|
|
|
|
```sql
|
|
-- Encrypt API key
|
|
UPDATE users
|
|
SET exchange_api_key = pgp_sym_encrypt('secret_key', 'encryption_password');
|
|
|
|
-- Decrypt API key
|
|
SELECT pgp_sym_decrypt(exchange_api_key, 'encryption_password')
|
|
FROM users WHERE id = 'user-uuid';
|
|
```
|
|
|
|
**File Storage:**
|
|
- KYC documents encrypted with AES-256
|
|
- Encryption keys stored in AWS KMS (future)
|
|
- Per-user encryption keys
|
|
|
|
### Encryption in Transit
|
|
|
|
**TLS/SSL:**
|
|
- Enforce HTTPS in production
|
|
- TLS 1.3 minimum
|
|
- Strong cipher suites only
|
|
- HSTS (HTTP Strict Transport Security)
|
|
|
|
**Certificate Management:**
|
|
- Let's Encrypt for SSL certificates
|
|
- Auto-renewal with Certbot
|
|
- Certificate pinning for mobile apps
|
|
|
|
```nginx
|
|
# Nginx configuration
|
|
server {
|
|
listen 443 ssl http2;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/orbiquant.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/orbiquant.com/privkey.pem;
|
|
|
|
ssl_protocols TLSv1.3;
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
|
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
}
|
|
```
|
|
|
|
### Password Security
|
|
|
|
**Hashing:**
|
|
- Algorithm: bcrypt
|
|
- Salt rounds: 12
|
|
- Automatic rehashing on login if rounds < 12
|
|
|
|
```typescript
|
|
import bcrypt from 'bcryptjs';
|
|
|
|
// Hash password
|
|
const hash = await bcrypt.hash(password, 12);
|
|
|
|
// Verify password
|
|
const isValid = await bcrypt.compare(password, hash);
|
|
```
|
|
|
|
**Password Policy:**
|
|
- Minimum 8 characters
|
|
- At least 1 uppercase letter
|
|
- At least 1 lowercase letter
|
|
- At least 1 number
|
|
- At least 1 special character
|
|
- Not in common password list
|
|
- Cannot be same as email
|
|
|
|
**Password Reset:**
|
|
- Token valid for 1 hour only
|
|
- One-time use tokens
|
|
- Email verification required
|
|
- Rate limited (3 attempts per hour)
|
|
|
|
### API Key Security
|
|
|
|
**User API Keys (for exchanges):**
|
|
- Encrypted at rest (AES-256)
|
|
- Never logged
|
|
- Permissions scope (read-only vs trading)
|
|
- IP whitelisting option
|
|
- Automatic rotation reminders
|
|
|
|
**Platform API Keys (internal services):**
|
|
- Separate keys per service
|
|
- Stored in environment variables
|
|
- Rotated every 90 days
|
|
- Revoked immediately if compromised
|
|
|
|
**Best Practices:**
|
|
```typescript
|
|
// ❌ Bad
|
|
const apiKey = "sk_live_1234567890";
|
|
logger.info(`Using API key: ${apiKey}`);
|
|
|
|
// ✅ Good
|
|
const apiKey = process.env.EXCHANGE_API_KEY;
|
|
logger.info('Exchange API key loaded');
|
|
```
|
|
|
|
## Input Validation & Sanitization
|
|
|
|
### Schema Validation
|
|
|
|
Using Zod for runtime type checking:
|
|
|
|
```typescript
|
|
import { z } from 'zod';
|
|
|
|
const OrderSchema = z.object({
|
|
symbol: z.string().regex(/^[A-Z]{6,10}$/),
|
|
side: z.enum(['BUY', 'SELL']),
|
|
type: z.enum(['MARKET', 'LIMIT', 'STOP_LOSS']),
|
|
quantity: z.number().positive().max(1000000),
|
|
price: z.number().positive().optional(),
|
|
});
|
|
|
|
// Validate input
|
|
const validatedOrder = OrderSchema.parse(req.body);
|
|
```
|
|
|
|
### SQL Injection Prevention
|
|
|
|
**ORM (TypeORM):**
|
|
- Parameterized queries by default
|
|
- Never use raw queries with user input
|
|
- Input validation before queries
|
|
|
|
```typescript
|
|
// ❌ Bad (SQL Injection vulnerable)
|
|
const users = await db.query(`SELECT * FROM users WHERE email = '${email}'`);
|
|
|
|
// ✅ Good (Parameterized)
|
|
const users = await userRepository.find({ where: { email } });
|
|
```
|
|
|
|
### XSS Prevention
|
|
|
|
**Frontend:**
|
|
- React auto-escapes by default
|
|
- DOMPurify for user-generated HTML
|
|
- CSP (Content Security Policy) headers
|
|
|
|
**Backend:**
|
|
- Sanitize HTML in user inputs
|
|
- Escape output in templates
|
|
- Set secure headers (Helmet.js)
|
|
|
|
```typescript
|
|
import helmet from 'helmet';
|
|
import DOMPurify from 'dompurify';
|
|
|
|
// Helmet middleware
|
|
app.use(helmet({
|
|
contentSecurityPolicy: {
|
|
directives: {
|
|
defaultSrc: ["'self'"],
|
|
scriptSrc: ["'self'", "'unsafe-inline'"],
|
|
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
imgSrc: ["'self'", "data:", "https:"],
|
|
},
|
|
},
|
|
}));
|
|
|
|
// Sanitize HTML
|
|
const cleanHTML = DOMPurify.sanitize(userInput);
|
|
```
|
|
|
|
### CSRF Protection
|
|
|
|
**Token-based:**
|
|
- CSRF tokens for state-changing requests
|
|
- SameSite cookie attribute
|
|
- Double-submit cookie pattern
|
|
|
|
```typescript
|
|
// Generate CSRF token
|
|
const csrfToken = crypto.randomBytes(32).toString('hex');
|
|
req.session.csrfToken = csrfToken;
|
|
|
|
// Validate CSRF token
|
|
if (req.body.csrfToken !== req.session.csrfToken) {
|
|
return res.status(403).json({ error: 'Invalid CSRF token' });
|
|
}
|
|
```
|
|
|
|
## Rate Limiting & DDoS Protection
|
|
|
|
### API Rate Limiting
|
|
|
|
**Implementation:** express-rate-limit
|
|
|
|
```typescript
|
|
import rateLimit from 'express-rate-limit';
|
|
|
|
// General rate limit
|
|
const generalLimiter = rateLimit({
|
|
windowMs: 60 * 1000, // 1 minute
|
|
max: 100, // 100 requests per minute
|
|
message: 'Too many requests, please try again later',
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
});
|
|
|
|
// Auth rate limit (stricter)
|
|
const authLimiter = rateLimit({
|
|
windowMs: 60 * 1000,
|
|
max: 5,
|
|
skipSuccessfulRequests: true, // Only count failed attempts
|
|
});
|
|
|
|
// Trading rate limit
|
|
const tradingLimiter = rateLimit({
|
|
windowMs: 60 * 1000,
|
|
max: 60,
|
|
keyGenerator: (req) => req.user.id, // Per user
|
|
});
|
|
|
|
app.use('/api', generalLimiter);
|
|
app.use('/api/auth', authLimiter);
|
|
app.use('/api/trading', tradingLimiter);
|
|
```
|
|
|
|
### DDoS Protection
|
|
|
|
**Cloudflare (recommended for production):**
|
|
- DDoS mitigation
|
|
- WAF (Web Application Firewall)
|
|
- Bot detection
|
|
- Rate limiting at edge
|
|
|
|
**Nginx:**
|
|
```nginx
|
|
# Connection limits
|
|
limit_conn_zone $binary_remote_addr zone=addr:10m;
|
|
limit_conn addr 10;
|
|
|
|
# Request rate limiting
|
|
limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
|
|
limit_req zone=req burst=20 nodelay;
|
|
```
|
|
|
|
## Payment Security
|
|
|
|
### Stripe Integration
|
|
|
|
**PCI Compliance:**
|
|
- Never store credit card numbers
|
|
- Use Stripe.js for card tokenization
|
|
- PCI DSS SAQ-A compliance
|
|
|
|
**Webhook Security:**
|
|
```typescript
|
|
// Verify Stripe webhook signature
|
|
const signature = req.headers['stripe-signature'];
|
|
const event = stripe.webhooks.constructEvent(
|
|
req.body,
|
|
signature,
|
|
process.env.STRIPE_WEBHOOK_SECRET
|
|
);
|
|
|
|
if (event.type === 'payment_intent.succeeded') {
|
|
// Handle payment
|
|
}
|
|
```
|
|
|
|
**Best Practices:**
|
|
- Idempotency keys for payment retries
|
|
- 3D Secure for high-value transactions
|
|
- Fraud detection (Stripe Radar)
|
|
- Refund policies
|
|
|
|
### Cryptocurrency Payments (Future)
|
|
|
|
**Security Considerations:**
|
|
- HD wallets (Hierarchical Deterministic)
|
|
- Multi-signature wallets
|
|
- Cold storage for majority of funds
|
|
- Hot wallet limits ($10k max)
|
|
|
|
## Audit Logging
|
|
|
|
### What to Log
|
|
|
|
**Security Events:**
|
|
- Login attempts (success/failure)
|
|
- Password changes
|
|
- 2FA enable/disable
|
|
- API key creation/revocation
|
|
- Permission changes
|
|
- Suspicious activity
|
|
|
|
**Financial Events:**
|
|
- Deposits/withdrawals
|
|
- Trades
|
|
- Order placements
|
|
- Balance changes
|
|
|
|
**System Events:**
|
|
- Errors
|
|
- Service failures
|
|
- Database queries (slow/failed)
|
|
|
|
### Log Format
|
|
|
|
```json
|
|
{
|
|
"timestamp": "2025-12-12T10:00:00.000Z",
|
|
"level": "info",
|
|
"event": "login_success",
|
|
"userId": "user-uuid",
|
|
"ip": "192.168.1.1",
|
|
"userAgent": "Mozilla/5.0...",
|
|
"metadata": {
|
|
"2faUsed": true,
|
|
"device": "Chrome on Windows"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Log Storage
|
|
|
|
**Database Table:** `audit.api_logs`
|
|
|
|
```sql
|
|
CREATE TABLE audit.api_logs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
user_id UUID REFERENCES auth.users(id),
|
|
event_type VARCHAR(100) NOT NULL,
|
|
ip_address INET,
|
|
user_agent TEXT,
|
|
request_path TEXT,
|
|
request_method VARCHAR(10),
|
|
status_code INTEGER,
|
|
response_time_ms INTEGER,
|
|
metadata JSONB,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_api_logs_user_id ON audit.api_logs(user_id);
|
|
CREATE INDEX idx_api_logs_timestamp ON audit.api_logs(timestamp);
|
|
CREATE INDEX idx_api_logs_event_type ON audit.api_logs(event_type);
|
|
```
|
|
|
|
### Log Retention
|
|
|
|
- Security logs: 1 year
|
|
- Transaction logs: 7 years (regulatory)
|
|
- System logs: 90 days
|
|
- Archived to S3 after 30 days
|
|
|
|
## Dependency Security
|
|
|
|
### npm audit
|
|
|
|
```bash
|
|
# Check for vulnerabilities
|
|
npm audit
|
|
|
|
# Fix vulnerabilities automatically
|
|
npm audit fix
|
|
|
|
# Force fix (may introduce breaking changes)
|
|
npm audit fix --force
|
|
```
|
|
|
|
### Automated Scanning
|
|
|
|
**GitHub Dependabot:**
|
|
- Automatic PRs for security updates
|
|
- Weekly vulnerability scans
|
|
|
|
**Snyk:**
|
|
- Real-time vulnerability monitoring
|
|
- License compliance checking
|
|
|
|
```yaml
|
|
# .github/dependabot.yml
|
|
version: 2
|
|
updates:
|
|
- package-ecosystem: "npm"
|
|
directory: "/apps/backend"
|
|
schedule:
|
|
interval: "weekly"
|
|
open-pull-requests-limit: 10
|
|
```
|
|
|
|
### Supply Chain Security
|
|
|
|
**Best Practices:**
|
|
- Lock file commits (package-lock.json)
|
|
- Verify package integrity (npm signatures)
|
|
- Use package-lock.json for reproducible builds
|
|
- Review new dependencies carefully
|
|
- Minimize dependencies
|
|
|
|
## Infrastructure Security
|
|
|
|
### Server Hardening
|
|
|
|
**Firewall (ufw):**
|
|
```bash
|
|
# Allow only necessary ports
|
|
ufw default deny incoming
|
|
ufw default allow outgoing
|
|
ufw allow 22/tcp # SSH
|
|
ufw allow 80/tcp # HTTP
|
|
ufw allow 443/tcp # HTTPS
|
|
ufw enable
|
|
```
|
|
|
|
**SSH:**
|
|
```bash
|
|
# Disable password authentication
|
|
PasswordAuthentication no
|
|
PubkeyAuthentication yes
|
|
|
|
# Disable root login
|
|
PermitRootLogin no
|
|
|
|
# Change default port
|
|
Port 2222
|
|
```
|
|
|
|
**Automatic Updates:**
|
|
```bash
|
|
# Ubuntu
|
|
apt install unattended-upgrades
|
|
dpkg-reconfigure --priority=low unattended-upgrades
|
|
```
|
|
|
|
### Database Security
|
|
|
|
**PostgreSQL:**
|
|
```sql
|
|
-- Create dedicated user with limited permissions
|
|
CREATE USER orbiquant_app WITH PASSWORD 'strong_password';
|
|
GRANT CONNECT ON DATABASE orbiquant_platform TO orbiquant_app;
|
|
GRANT USAGE ON SCHEMA auth, trading TO orbiquant_app;
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA auth, trading TO orbiquant_app;
|
|
|
|
-- Revoke public access
|
|
REVOKE ALL ON DATABASE orbiquant_platform FROM PUBLIC;
|
|
|
|
-- Enable SSL
|
|
ssl = on
|
|
ssl_cert_file = '/path/to/server.crt'
|
|
ssl_key_file = '/path/to/server.key'
|
|
```
|
|
|
|
**Redis:**
|
|
```conf
|
|
# Require password
|
|
requirepass strong_redis_password
|
|
|
|
# Bind to localhost only
|
|
bind 127.0.0.1
|
|
|
|
# Disable dangerous commands
|
|
rename-command FLUSHDB ""
|
|
rename-command FLUSHALL ""
|
|
rename-command CONFIG ""
|
|
```
|
|
|
|
### Container Security
|
|
|
|
**Docker:**
|
|
```dockerfile
|
|
# Use non-root user
|
|
FROM node:18-alpine
|
|
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
|
|
USER nodejs
|
|
|
|
# Read-only file system
|
|
docker run --read-only ...
|
|
|
|
# Drop capabilities
|
|
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ...
|
|
```
|
|
|
|
**Docker Compose:**
|
|
```yaml
|
|
services:
|
|
backend:
|
|
image: orbiquant-backend
|
|
read_only: true
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
```
|
|
|
|
## Compliance & Regulations
|
|
|
|
### GDPR (General Data Protection Regulation)
|
|
|
|
**Requirements:**
|
|
- Data minimization
|
|
- Right to access (download data)
|
|
- Right to erasure (delete account)
|
|
- Data portability
|
|
- Consent management
|
|
|
|
**Implementation:**
|
|
```typescript
|
|
// Export user data
|
|
GET /api/users/me/export
|
|
Response: JSON file with all user data
|
|
|
|
// Delete account (GDPR)
|
|
DELETE /api/users/me
|
|
- Anonymize user data
|
|
- Delete PII (personally identifiable information)
|
|
- Keep transaction history (regulatory)
|
|
```
|
|
|
|
### KYC/AML (Know Your Customer / Anti-Money Laundering)
|
|
|
|
**Verification Levels:**
|
|
|
|
| Level | Limits | Requirements |
|
|
|-------|--------|--------------|
|
|
| **Level 0** | $100/day | Email verification |
|
|
| **Level 1** | $1,000/day | Name, DOB, address |
|
|
| **Level 2** | $10,000/day | ID document, selfie |
|
|
| **Level 3** | Unlimited | Proof of address, video call |
|
|
|
|
**Monitoring:**
|
|
- Suspicious transaction patterns
|
|
- Large withdrawals
|
|
- Rapid account changes
|
|
- Regulatory reporting
|
|
|
|
## Incident Response
|
|
|
|
### Security Incident Procedure
|
|
|
|
1. **Detection:** Monitoring alerts, user reports
|
|
2. **Containment:** Isolate affected systems
|
|
3. **Investigation:** Root cause analysis
|
|
4. **Remediation:** Fix vulnerability, patch systems
|
|
5. **Recovery:** Restore normal operations
|
|
6. **Post-Mortem:** Document lessons learned
|
|
|
|
### Breach Notification
|
|
|
|
**Timeline:**
|
|
- Internal notification: Immediate
|
|
- User notification: Within 72 hours
|
|
- Regulatory notification: As required by law
|
|
|
|
**Template:**
|
|
```
|
|
Subject: Security Incident Notification
|
|
|
|
We are writing to inform you of a security incident that may have affected your account.
|
|
|
|
What happened: [Description]
|
|
What data was affected: [List]
|
|
What we are doing: [Actions taken]
|
|
What you should do: [User actions]
|
|
|
|
We sincerely apologize for this incident.
|
|
```
|
|
|
|
## Security Checklist
|
|
|
|
### Development
|
|
|
|
- [ ] Input validation on all endpoints
|
|
- [ ] Parameterized SQL queries
|
|
- [ ] Error messages don't leak sensitive info
|
|
- [ ] Secrets in environment variables
|
|
- [ ] Dependencies scanned for vulnerabilities
|
|
- [ ] Code review before merge
|
|
- [ ] No hardcoded credentials
|
|
|
|
### Deployment
|
|
|
|
- [ ] HTTPS enforced
|
|
- [ ] Security headers configured (Helmet)
|
|
- [ ] Rate limiting enabled
|
|
- [ ] CORS properly configured
|
|
- [ ] Database backups enabled
|
|
- [ ] Logging configured
|
|
- [ ] Monitoring alerts set up
|
|
|
|
### Operations
|
|
|
|
- [ ] Rotate API keys every 90 days
|
|
- [ ] Review access logs weekly
|
|
- [ ] Security patches applied within 48h
|
|
- [ ] Backup tested monthly
|
|
- [ ] Incident response plan updated
|
|
- [ ] Team security training quarterly
|
|
|
|
## Security Contacts
|
|
|
|
**Report vulnerabilities:** security@orbiquant.com
|
|
|
|
**Bug Bounty Program (future):**
|
|
- $100-$5000 depending on severity
|
|
- Responsible disclosure required
|
|
|
|
## References
|
|
|
|
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
|
- [OWASP API Security](https://owasp.org/www-project-api-security/)
|
|
- [CWE Top 25](https://cwe.mitre.org/top25/)
|
|
- [PCI DSS](https://www.pcisecuritystandards.org/)
|
|
- [GDPR](https://gdpr.eu/)
|
|
- [Stripe Security](https://stripe.com/docs/security)
|