This document outlines the comprehensive security measures implemented in the Portfolio Tracker application.
- Security Architecture
- Input Sanitization
- Rate Limiting & DDoS Protection
- HTTPS/TLS Configuration
- Database Security
- Security Headers
- Authentication & Authorization
- Security Auditing
- Graceful Shutdown
- Security Testing
- Production Deployment
- Incident Response
The Portfolio Tracker implements a multi-layered security approach:
┌─────────────────────────────────────────────────────────────┐
│ Load Balancer/CDN │
│ (DDoS Protection) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ API Gateway │
│ • Rate Limiting • Security Headers │
│ • Input Sanitization • CORS Configuration │
│ • Request Validation • SSL Termination │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Microservices │
│ • Authentication • Input Validation │
│ • Authorization • Database Security │
│ • Audit Logging • Graceful Shutdown │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Data Layer │
│ • Connection Pooling • Encrypted Connections │
│ • Query Optimization • Access Controls │
│ • Backup Encryption • Audit Trails │
└─────────────────────────────────────────────────────────────┘
The application implements comprehensive input sanitization using the InputSanitizer class:
import { SanitizationMiddleware } from '@portfolio/shared-types';
// Apply to all routes
app.use(
SanitizationMiddleware.sanitizeAll({
allowHtml: false,
maxLength: 5000,
trimWhitespace: true,
escapeHtml: true,
})
);- XSS Prevention: HTML entities are escaped or stripped
- SQL Injection Prevention: Parameterized queries and identifier validation
- Path Traversal Protection: File path sanitization
- Command Injection Prevention: Shell command character filtering
- Length Limits: Configurable maximum input lengths
- Type Validation: Strict type checking for all inputs
// Safe identifier sanitization
const columnName = SQLInjectionPrevention.sanitizeIdentifier(userInput);
// Safe parameter binding
const results = await db.query('SELECT * FROM users WHERE email = ?', [
sanitizedEmail,
]);- General API: 2000 requests per 15 minutes
- Authentication: 5 requests per 15 minutes
- Public Endpoints: Higher limits for non-sensitive operations
- Progressive Delays: Slow down responses for suspicious activity
- IP Blocking: Temporary blocks for repeated violations
- Pattern Detection: Identify and block malicious request patterns
- Request Size Limits: Prevent large payload attacks
- Connection Limits: Limit concurrent connections per IP
const ddosConfig = {
rateLimits: {
general: { windowMs: 15 * 60 * 1000, max: 2000 },
auth: { windowMs: 15 * 60 * 1000, max: 5 },
api: { windowMs: 15 * 60 * 1000, max: 1000 },
},
suspiciousActivity: {
maxFailedAttempts: 5,
blockDurationMs: 3600000, // 1 hour
},
};Generate development certificates:
./scripts/generate-ssl-certs.shFor production, use Let's Encrypt:
certbot certonly --standalone -d yourdomain.com- Protocol: TLS 1.2+ only
- Cipher Suites: Strong ciphers only (ECDHE, AES-GCM)
- HSTS: Enabled with preload
- Certificate Transparency: Monitored
- OCSP Stapling: Recommended for production
HTTPS_ENABLED=true
HTTPS_KEY_PATH=/path/to/private.key
HTTPS_CERT_PATH=/path/to/certificate.crt- Encrypted Connections: SSL/TLS for all database connections
- Connection Pooling: Optimized and secure connection management
- Authentication: Strong credentials and certificate-based auth
- Network Isolation: Database servers in private networks
const mysqlConfig = {
ssl: {
ca: process.env.MYSQL_SSL_CA,
cert: process.env.MYSQL_SSL_CERT,
key: process.env.MYSQL_SSL_KEY,
rejectUnauthorized: true,
},
connectionLimit: 100,
multipleStatements: false, // Prevent SQL injection
};const mongoConfig = {
uri: 'mongodb://user:pass@host:27017/db?authSource=admin&ssl=true',
ssl: true,
authSource: 'admin',
maxPoolSize: 200,
};const redisConfig = {
tls: {
ca: process.env.REDIS_TLS_CA,
cert: process.env.REDIS_TLS_CERT,
key: process.env.REDIS_TLS_KEY,
},
password: process.env.REDIS_PASSWORD,
};- Content-Security-Policy: Prevents XSS and code injection
- Strict-Transport-Security: Enforces HTTPS
- X-Frame-Options: Prevents clickjacking
- X-Content-Type-Options: Prevents MIME sniffing
- X-XSS-Protection: Browser XSS protection
- Referrer-Policy: Controls referrer information
- Permissions-Policy: Restricts browser features
const cspDirectives = {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
scriptSrc: ["'self'"],
imgSrc: ["'self'", 'data:', 'https:', 'blob:'],
connectSrc: ["'self'", 'wss:', 'ws:'],
objectSrc: ["'none'"],
frameAncestors: ["'none'"],
};- Strong Secrets: Minimum 32 character secrets
- Short Expiration: 15-minute access tokens
- Refresh Tokens: 7-day refresh tokens with rotation
- Secure Storage: HttpOnly cookies for refresh tokens
- Token Validation: Comprehensive token verification
- Hashing: bcrypt with salt rounds ≥ 12
- Complexity: Minimum requirements enforced
- Breach Detection: Check against known breached passwords
- Rate Limiting: Strict limits on authentication attempts
The security auditor logs various security events:
- Failed authentication attempts
- Rate limit violations
- Suspicious request patterns
- SQL injection attempts
- XSS attempts
- Unauthorized access attempts
const auditConfig = {
alertThresholds: {
failedAuthAttempts: 5,
suspiciousRequests: 10,
rateLimitViolations: 20,
},
};Security logs are structured JSON for easy analysis:
{
"id": "sec_1234567890_abcd1234",
"timestamp": "2024-01-01T12:00:00Z",
"type": "FAILED_AUTHENTICATION",
"severity": "MEDIUM",
"source": {
"ip": "192.168.1.100",
"userAgent": "Mozilla/5.0...",
"userId": null
},
"details": {
"method": "POST",
"url": "/auth/login",
"statusCode": 401
}
}const gracefulShutdown = new GracefulShutdown({
timeout: 30000,
signals: ['SIGTERM', 'SIGINT', 'SIGUSR2'],
});
// Add shutdown handlers
gracefulShutdown.addHandlers([
{ name: 'database-disconnect', handler: () => db.disconnect() },
{ name: 'cache-disconnect', handler: () => redis.disconnect() },
{ name: 'cleanup-temp-files', handler: () => cleanupTempFiles() },
]);- Stop accepting new connections
- Wait for existing requests to complete
- Close database connections
- Clean up resources
- Exit process
Run the security audit script:
./scripts/security-audit.sh- SQL Injection: Test with common payloads
- XSS: Test with script injection attempts
- Path Traversal: Test with directory traversal attempts
- Rate Limiting: Test with rapid requests
- Authentication: Test with invalid tokens
Use the built-in penetration testing utilities:
import { PenetrationTestingUtils } from '@portfolio/shared-types';
const result = PenetrationTestingUtils.comprehensiveSecurityTest(userInput);
if (result.overallRisk === 'HIGH' || result.overallRisk === 'CRITICAL') {
// Block request and log incident
}- SSL certificates installed and valid
- Environment variables configured
- Database connections secured
- Rate limiting configured
- Security headers enabled
- Audit logging configured
- Backup systems tested
- Monitoring alerts configured
Copy and configure the production environment file:
cp .env.production.example .env.production
# Edit .env.production with your actual valuesFor production with Let's Encrypt:
# Install certbot
sudo apt-get install certbot
# Generate certificate
sudo certbot certonly --standalone -d yourdomain.com
# Configure auto-renewal
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet- Create dedicated database users with minimal privileges
- Enable SSL/TLS for all database connections
- Configure firewalls to restrict database access
- Set up automated backups with encryption
- Enable audit logging for database operations
- Authentication Bypass
- Data Breach
- DDoS Attack
- SQL Injection
- XSS Attack
- Unauthorized Access
-
Immediate Response
- Identify and contain the threat
- Block malicious IPs if necessary
- Preserve evidence and logs
-
Investigation
- Analyze security logs
- Determine scope of impact
- Identify root cause
-
Recovery
- Apply security patches
- Update configurations
- Restore from backups if needed
-
Post-Incident
- Document lessons learned
- Update security procedures
- Implement additional controls
- Security Team: security@yourdomain.com
- System Administrator: admin@yourdomain.com
- On-Call Engineer: +1-XXX-XXX-XXXX
- Security Audit Logs:
/var/log/portfolio-tracker/security-audit.log - Application Logs:
/var/log/portfolio-tracker/app.log - Access Logs:
/var/log/nginx/access.log - Error Logs:
/var/log/nginx/error.log
- Failed authentication attempts per hour
- Rate limit violations per hour
- Suspicious request patterns
- Database connection failures
- SSL certificate expiration dates
- Critical: > 10 failed auth attempts in 5 minutes
- High: > 50 rate limit violations in 15 minutes
- Medium: > 100 suspicious requests in 1 hour
- Low: SSL certificate expires in < 30 days
- Prometheus: Metrics collection
- Grafana: Visualization and alerting
- ELK Stack: Log analysis
- Custom Security Dashboard: Real-time security status
- OWASP Top 10: All vulnerabilities addressed
- NIST Cybersecurity Framework: Implemented controls
- ISO 27001: Security management practices
- SOC 2: Security and availability controls
- Monthly: Security metrics review
- Quarterly: Penetration testing
- Annually: Full security audit
- As needed: Incident response reviews
For security-related questions or to report vulnerabilities:
- Email: security@portfoliotracker.com
- PGP Key: Available at https://portfoliotracker.com/.well-known/pgp-key.txt
- Bug Bounty: https://portfoliotracker.com/security/bug-bounty
This document is regularly updated to reflect the current security posture of the Portfolio Tracker application.