Skip to content

Security Guide

Comprehensive security practices for all HandyManny projects and infrastructure.

Security Principles

  1. Defense in Depth - Multiple layers of security
  2. Least Privilege - Minimum necessary permissions
  3. Zero Trust - Verify everything, trust nothing
  4. Secure by Default - Security built-in, not bolted-on
  5. Monitor Everything - Continuous security monitoring

Automated Security Monitoring

CHAROS Auditor (Scheduled Task)

Runs: Daily at 7 AM Location: Windows Task Scheduler Script: ~/projects/charos-expediente/security/auditor.ps1

Checks:

  1. SSL certificate expiration (30-day warning)
  2. Unauthorized file changes (checksum verification)
  3. Suspicious process detection
  4. Port scan detection
  5. Failed login attempts
  6. Environment variable leaks

Notifications:

  • Email alerts to admin
  • Telegram notifications for critical issues
  • Logs to security-audit.log

Session Monitor (Hourly)

Runs: Every 1 hour Monitors:

  • Active Claude Code sessions
  • MCP server processes
  • Resource usage
  • Unauthorized process spawning

Actions:

  • Kills orphaned processes
  • Cleans up temp files
  • Alerts on anomalies

SSL Health Check (Every 2 hours)

Runs: Every 2 hours Checks:

  • Certificate validity
  • Certificate expiration
  • SSL configuration
  • HTTPS redirect working
  • Mixed content issues

Alerts when:

  • Certificate expires < 14 days
  • Certificate invalid
  • HTTP not redirecting to HTTPS

Application Security

Authentication Best Practices

1. Password Requirements

typescript
// Enforce strong passwords
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{12,}$/;

// Minimum 12 characters
// At least 1 uppercase, 1 lowercase, 1 number, 1 special char

2. Password Hashing

typescript
// Use bcrypt with high cost factor
import bcrypt from 'bcrypt';

const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);

// NEVER store plain text passwords
// NEVER use MD5 or SHA1

3. JWT Token Security

typescript
// Short expiration times
const accessToken = jwt.sign(payload, secret, {
  expiresIn: '15m'  // 15 minutes
});

const refreshToken = jwt.sign(payload, refreshSecret, {
  expiresIn: '7d'   // 7 days
});

// Use different secrets for access and refresh tokens
// Rotate secrets quarterly

4. Session Management

typescript
// Secure session configuration
{
  secret: process.env.SESSION_SECRET,  // 256-bit random string
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,      // Prevent XSS
    secure: true,        // HTTPS only
    sameSite: 'strict',  // CSRF protection
    maxAge: 86400000     // 24 hours
  }
}

API Security

1. Rate Limiting

typescript
// Prevent brute force and DDoS
import rateLimit from 'express-rate-limit';

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 minutes
  max: 100,                   // 100 requests per window
  message: 'Too many requests'
});

app.use('/api/', limiter);

2. Input Validation

typescript
// ALWAYS validate user input
import { z } from 'zod';

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(12),
  name: z.string().max(100).regex(/^[a-zA-Z\s]+$/)
});

// Validate before using
const result = schema.safeParse(req.body);
if (!result.success) {
  return res.status(400).json({ error: result.error });
}

3. SQL Injection Prevention

typescript
// ✓ Use parameterized queries
await prisma.shipment.findMany({
  where: { status: userInput }  // Safe - Prisma handles escaping
});

// ✓ For raw SQL, use parameters
await prisma.$executeRaw`
  SELECT * FROM shipments WHERE status = ${userInput}
`;

// ✗ NEVER concatenate user input
await prisma.$executeRawUnsafe(
  `SELECT * FROM shipments WHERE status = '${userInput}'`  // UNSAFE!
);

4. XSS Prevention

typescript
// Sanitize HTML input
import DOMPurify from 'isomorphic-dompurify';

const clean = DOMPurify.sanitize(userInput);

// Use Content Security Policy headers
res.setHeader('Content-Security-Policy',
  "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
);

5. CORS Configuration

typescript
// Restrict origins
app.use(cors({
  origin: ['https://handymanny.cloud', 'https://charos.handymanny.cloud'],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

// NEVER use origin: '*' in production

Security Headers

Essential headers for all applications:

typescript
// Express.js
import helmet from 'helmet';
app.use(helmet());

// OR manually:
app.use((req, res, next) => {
  // Prevent clickjacking
  res.setHeader('X-Frame-Options', 'DENY');

  // Prevent MIME sniffing
  res.setHeader('X-Content-Type-Options', 'nosniff');

  // Enable XSS filter
  res.setHeader('X-XSS-Protection', '1; mode=block');

  // HSTS - Force HTTPS
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');

  // Referrer policy
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');

  // Permissions policy
  res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');

  next();
});

Infrastructure Security

SSH Security

1. Key-Based Authentication Only

bash
# Disable password authentication
sudo nano /etc/ssh/sshd_config

# Set these values:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password

2. SSH Key Management

bash
# Generate strong SSH key
ssh-keygen -t ed25519 -C "your_email@example.com"

# Use passphrase-protected keys
# Store keys securely (not in git)

3. SSH Hardening

bash
# Disable empty passwords
PermitEmptyPasswords no

# Limit SSH users
AllowUsers admin deploy

# Change default SSH port (security through obscurity)
Port 2222

# Use fail2ban for brute force protection
sudo apt install fail2ban

Firewall Configuration

bash
# Allow only necessary ports
ufw default deny incoming
ufw default allow outgoing

# Allow SSH (custom port)
ufw allow 2222/tcp

# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

# Enable firewall
ufw enable

# Check status
ufw status verbose

Docker Security

1. Run as Non-Root User

dockerfile
# Dockerfile
FROM node:18-alpine

# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Switch to non-root user
USER appuser

# Rest of Dockerfile...

2. Use Official Images

yaml
# docker-compose.yml
services:
  app:
    image: node:18-alpine  # ✓ Official image
    # NOT: some-random/node:latest  # ✗ Untrusted

3. Limit Container Resources

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          memory: 256M

4. Scan Images for Vulnerabilities

bash
# Use Trivy to scan images
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image [image-name]

Environment Variables

1. Never Commit Secrets

bash
# .gitignore
.env
.env.local
.env.production
*.pem
*.key
id_rsa*

2. Use .env Files

bash
# .env (NOT committed)
DATABASE_URL=postgresql://user:pass@localhost:5432/db
JWT_SECRET=256-bit-random-string
API_KEY=secret-api-key

# .env.example (committed)
DATABASE_URL=postgresql://user:pass@localhost:5432/db
JWT_SECRET=your-secret-here
API_KEY=your-api-key-here

3. Encrypt Secrets at Rest

bash
# Use git-crypt for encrypted secrets
git-crypt init
git-crypt add-gpg-user your-key-id

# Add to .gitattributes
.env filter=git-crypt diff=git-crypt

Database Security

PostgreSQL Hardening

1. Strong Passwords

sql
-- Create users with strong passwords
CREATE USER appuser WITH ENCRYPTED PASSWORD 'RandomLongPassword123!@#';

-- Grant minimal permissions
GRANT CONNECT ON DATABASE mydb TO appuser;
GRANT USAGE ON SCHEMA public TO appuser;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO appuser;

2. Connection Security

bash
# postgresql.conf
ssl = on
ssl_cert_file = '/etc/ssl/certs/server.crt'
ssl_key_file = '/etc/ssl/private/server.key'

# Require SSL connections
# pg_hba.conf
hostssl all all 0.0.0.0/0 md5

3. Regular Backups

bash
# Automated daily backups
0 2 * * * pg_dump -U postgres dbname > /backups/db-$(date +\%Y\%m\%d).sql

# Encrypt backups
gpg --encrypt /backups/db-20260228.sql

# Store offsite (S3, Backblaze, etc)

Database Access Control

typescript
// Connection pool limits
{
  max: 20,           // Maximum connections
  min: 2,            // Minimum connections
  idle: 10000,       // Idle timeout
  connectionTimeoutMillis: 2000
}

// NEVER use root/postgres user in applications
// Create dedicated app users with minimal permissions

Secrets Management

Where to Store Secrets

❌ Never:

  • Git repositories (even private)
  • Docker images
  • Client-side code
  • Logs or error messages
  • Screenshots or documentation

✓ Use:

  • Environment variables
  • Secret management services (AWS Secrets Manager, HashiCorp Vault)
  • Encrypted files (git-crypt)
  • Password managers (1Password, LastPass)

Rotating Secrets

Quarterly rotation schedule:

Secret TypeRotation FrequencyLast Rotated
API KeysEvery 90 days-
JWT SecretsEvery 90 days-
Database PasswordsEvery 90 days-
SSH KeysAnnually-
SSL CertificatesAuto (Let's Encrypt)-

Incident Response

Security Incident Checklist

If you discover a security issue:

  1. Contain

    • [ ] Disable affected service immediately
    • [ ] Revoke compromised credentials
    • [ ] Block malicious IP addresses
  2. Assess

    • [ ] Identify what was compromised
    • [ ] Check logs for unauthorized access
    • [ ] Determine scope of breach
  3. Remediate

    • [ ] Patch vulnerability
    • [ ] Rotate all potentially compromised secrets
    • [ ] Update security configurations
  4. Verify

    • [ ] Test fix thoroughly
    • [ ] Scan for additional vulnerabilities
    • [ ] Monitor for suspicious activity
  5. Document

    • [ ] Write incident report
    • [ ] Document lessons learned
    • [ ] Update security procedures
  6. Notify

    • [ ] Inform affected users (if applicable)
    • [ ] Report to stakeholders
    • [ ] Update team on mitigation

Emergency Contacts

Security Incident Escalation:

  1. Disable affected system immediately
  2. Notify team via Telegram
  3. Begin incident response checklist
  4. Document everything

Security Auditing

Regular Security Checks

Weekly:

  • [ ] Review access logs for anomalies
  • [ ] Check for failed login attempts
  • [ ] Verify SSL certificates valid
  • [ ] Review Docker container security

Monthly:

  • [ ] Update all dependencies
  • [ ] Run vulnerability scans
  • [ ] Review user permissions
  • [ ] Audit API keys in use
  • [ ] Check for exposed secrets in git history

Quarterly:

  • [ ] Rotate API keys and secrets
  • [ ] Security training/review
  • [ ] Penetration testing
  • [ ] Third-party security audit

Security Scanning Tools

bash
# npm audit (Node.js projects)
npm audit
npm audit fix

# Snyk (comprehensive)
npx snyk test

# OWASP Dependency Check
dependency-check --project myapp --scan .

# Git secret scanning
git-secrets --scan-history

# Trivy (Docker images)
trivy image myapp:latest

Compliance & Best Practices

OWASP Top 10 Prevention

  1. Broken Access Control - Implement proper authorization checks
  2. Cryptographic Failures - Use strong encryption, HTTPS everywhere
  3. Injection - Parameterized queries, input validation
  4. Insecure Design - Security by design, threat modeling
  5. Security Misconfiguration - Secure defaults, minimal permissions
  6. Vulnerable Components - Keep dependencies updated
  7. Identification and Authentication Failures - Strong passwords, MFA
  8. Software and Data Integrity Failures - Verify dependencies, signed commits
  9. Security Logging Failures - Comprehensive logging and monitoring
  10. Server-Side Request Forgery - Validate and sanitize URLs

Security Checklist for New Projects

  • [ ] HTTPS enabled (SSL certificate)
  • [ ] Security headers configured
  • [ ] Authentication implemented
  • [ ] Authorization implemented
  • [ ] Input validation on all endpoints
  • [ ] SQL injection prevention (parameterized queries)
  • [ ] XSS prevention (sanitize output)
  • [ ] CSRF protection enabled
  • [ ] Rate limiting configured
  • [ ] Error handling (no sensitive data in errors)
  • [ ] Secrets in environment variables (not code)
  • [ ] Dependencies up to date
  • [ ] Docker security (non-root user, resource limits)
  • [ ] Logging configured
  • [ ] Monitoring configured

Last Updated: 2026-02-28 Related SOPs: Deployment SOP, Rollback SOP

HandyManny Documentation System