Skip to content

Security: thefiredev-cloud/VideoGenMessenger

Security

docs/SECURITY.md

Security Best Practices

Security guidelines and best practices for VideoGen Messenger.

Table of Contents

Authentication & Authorization

JWT Tokens

Best Practices:

  • Use strong, random secrets (minimum 32 characters)
  • Set appropriate expiration times (24 hours recommended)
  • Rotate secrets periodically
  • Store tokens securely on client side

Implementation:

// Generate token
const token = jwt.sign(
  { userId, email },
  process.env.JWT_SECRET,
  {
    expiresIn: '24h',
    issuer: 'videogen-messenger',
    audience: 'videogen-api'
  }
);

// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
  issuer: 'videogen-messenger',
  audience: 'videogen-api'
});

Security Checklist:

  • JWT_SECRET is at least 32 characters
  • Secrets are stored in AWS Secrets Manager
  • Tokens include expiration
  • Tokens are validated on every request
  • Refresh token mechanism implemented

API Keys

Generation:

const crypto = require('crypto');

function generateApiKey() {
  return `vgm_${crypto.randomBytes(32).toString('hex')}`;
}

Storage:

const bcrypt = require('bcrypt');

// Hash API key before storing
const hashedKey = await bcrypt.hash(apiKey, 10);

// Store hash in database, give user the plain key once

Validation:

// Compare provided key with stored hash
const isValid = await bcrypt.compare(providedKey, storedHash);

Password Security

Requirements:

  • Minimum 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number
  • At least one special character

Hashing:

const bcrypt = require('bcrypt');

// Hash password (10 rounds)
const passwordHash = await bcrypt.hash(password, 10);

// Verify password
const isValid = await bcrypt.compare(password, passwordHash);

Password Validation:

function validatePassword(password) {
  const minLength = 8;
  const hasUpperCase = /[A-Z]/.test(password);
  const hasLowerCase = /[a-z]/.test(password);
  const hasNumbers = /\d/.test(password);
  const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(password);

  return password.length >= minLength &&
         hasUpperCase &&
         hasLowerCase &&
         hasNumbers &&
         hasSpecial;
}

API Security

Rate Limiting

Configuration:

// Per-user limits
const userLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  keyGenerator: (req) => req.user?.id || req.ip,
  message: 'Too many requests, please try again later'
});

// Aggressive limiting for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // 5 attempts per 15 minutes
  skipSuccessfulRequests: true
});

Protection Against:

  • Brute force attacks
  • DDoS attacks
  • API abuse
  • Credential stuffing

Input Validation

Joi Schema Example:

const generationSchema = Joi.object({
  prompt: Joi.string().min(3).max(500).required(),
  quality: Joi.string().valid('sd', 'hd', '4k').required(),
  duration: Joi.number().min(1).max(30).required(),
  style: Joi.string().optional()
});

// Validate
const { error, value } = generationSchema.validate(req.body);
if (error) {
  return res.status(400).json({ error: error.details[0].message });
}

Always Validate:

  • Request body
  • Query parameters
  • Path parameters
  • Headers
  • File uploads

SQL Injection Prevention

Use Parameterized Queries:

// BAD - Vulnerable to SQL injection
const query = `SELECT * FROM users WHERE email = '${email}'`;

// GOOD - Parameterized query
const query = 'SELECT * FROM users WHERE email = $1';
const result = await db.query(query, [email]);

XSS Prevention

Content Security Policy:

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", 'data:', 'https:'],
    connectSrc: ["'self'"],
    fontSrc: ["'self'"],
    objectSrc: ["'none'"],
    mediaSrc: ["'self'", 'https://cdn.yourdomain.com'],
    frameSrc: ["'none'"]
  }
}));

Sanitize User Input:

const sanitize = require('sanitize-html');

const clean = sanitize(userInput, {
  allowedTags: [],
  allowedAttributes: {}
});

CORS Configuration

const corsOptions = {
  origin: function (origin, callback) {
    const whitelist = [
      'https://yourdomain.com',
      'https://app.yourdomain.com'
    ];

    if (process.env.NODE_ENV === 'development') {
      whitelist.push('http://localhost:3000');
    }

    if (!origin || whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

Data Protection

Encryption at Rest

Database:

  • Enable RDS encryption
  • Use AWS KMS for key management
  • Encrypt backups
# Enable encryption on RDS
aws rds modify-db-instance \
  --db-instance-identifier videogen-db \
  --storage-encrypted \
  --kms-key-id arn:aws:kms:region:account:key/key-id

S3:

  • Server-side encryption (SSE-S3 or SSE-KMS)
  • Bucket policies enforce encryption
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::videogen-videos-prod/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    }
  ]
}

Encryption in Transit

TLS 1.3:

  • All API endpoints use HTTPS
  • Database connections use SSL
  • Redis connections use TLS
  • No plain HTTP in production

Certificate Management:

# Use AWS Certificate Manager
aws acm request-certificate \
  --domain-name api.yourdomain.com \
  --subject-alternative-names *.yourdomain.com \
  --validation-method DNS

Secrets Management

AWS Secrets Manager:

const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();

async function getSecret(secretName) {
  const data = await secretsManager.getSecretValue({
    SecretId: secretName
  }).promise();

  return JSON.parse(data.SecretString);
}

// Usage
const dbCreds = await getSecret('videogen/database');
const apiKeys = await getSecret('videogen/api-keys');

Never:

  • Commit secrets to Git
  • Log secrets
  • Include secrets in error messages
  • Store secrets in plain text

Personal Data Handling

GDPR Compliance:

  • User consent for data collection
  • Right to be forgotten implementation
  • Data portability
  • Data minimization

Data Deletion:

async function deleteUserData(userId) {
  // Delete user record
  await db.query('DELETE FROM users WHERE id = $1', [userId]);

  // Delete videos
  await db.query('DELETE FROM videos WHERE user_id = $1', [userId]);

  // Delete from S3
  const videos = await s3.listObjects({
    Bucket: 'videogen-videos',
    Prefix: `${userId}/`
  }).promise();

  for (const obj of videos.Contents) {
    await s3.deleteObject({
      Bucket: 'videogen-videos',
      Key: obj.Key
    }).promise();
  }

  // Remove from search index
  await elasticsearch.deleteByQuery({
    index: 'videos',
    body: {
      query: { term: { user_id: userId } }
    }
  });
}

Infrastructure Security

Network Security

VPC Configuration:

  • Private subnets for databases
  • Public subnets for load balancers only
  • NAT Gateway for outbound traffic
  • Network ACLs

Security Groups:

# API Server Security Group
# Inbound: Port 3000 from ALB only
# Outbound: All traffic

# Database Security Group
# Inbound: Port 5432 from API servers only
# Outbound: None

# Redis Security Group
# Inbound: Port 6379 from API servers only
# Outbound: None

IAM Roles & Policies

Principle of Least Privilege:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::videogen-videos-prod/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:*:*:secret:videogen/*"
    }
  ]
}

Container Security

Docker Best Practices:

  • Use official base images
  • Run as non-root user
  • Scan images for vulnerabilities
  • Keep images updated
FROM node:18-alpine

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001

# Set working directory
WORKDIR /app

# Copy files
COPY --chown=nodejs:nodejs . .

# Install dependencies
RUN npm ci --production

# Switch to non-root user
USER nodejs

# Start application
CMD ["node", "api/server.js"]

Monitoring & Alerting

Security Monitoring:

  • Failed login attempts
  • Unusual API patterns
  • Privilege escalation attempts
  • Data export activities

CloudWatch Alarms:

# Alert on high 4xx errors
aws cloudwatch put-metric-alarm \
  --alarm-name high-4xx-errors \
  --alarm-description "Alert on high 4xx error rate" \
  --metric-name 4XXError \
  --namespace AWS/ApplicationELB \
  --statistic Sum \
  --period 300 \
  --threshold 100 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1

Content Moderation

Text Content Filtering

Unsafe Keywords:

const UNSAFE_KEYWORDS = [
  'violence', 'explicit', 'nsfw', 'gore',
  'weapon', 'drug', 'hate', 'terrorism'
];

function checkContentSafety(prompt) {
  const lowerPrompt = prompt.toLowerCase();

  for (const keyword of UNSAFE_KEYWORDS) {
    if (lowerPrompt.includes(keyword)) {
      throw new Error('Prompt contains potentially unsafe content');
    }
  }
}

Azure Content Safety API

const { ContentSafetyClient } = require('@azure/ai-content-safety');

async function moderateContent(text) {
  const client = new ContentSafetyClient(
    process.env.AZURE_CONTENT_SAFETY_ENDPOINT,
    process.env.AZURE_CONTENT_SAFETY_KEY
  );

  const result = await client.analyzeText({
    text: text,
    categories: ['Hate', 'Sexual', 'Violence', 'SelfHarm']
  });

  // Check severity levels
  for (const category of result.categories) {
    if (category.severity >= 4) { // High severity
      throw new Error(`Content flagged for ${category.category}`);
    }
  }
}

Video Content Moderation

AWS Rekognition:

const rekognition = new AWS.Rekognition();

async function moderateVideo(videoUrl) {
  const result = await rekognition.startContentModeration({
    Video: {
      S3Object: {
        Bucket: 'videogen-videos',
        Name: 'video.mp4'
      }
    }
  }).promise();

  // Poll for results
  // Block videos with inappropriate content
}

Incident Response

Security Incident Process

  1. Detection: Monitor for security events
  2. Containment: Isolate affected systems
  3. Eradication: Remove threat
  4. Recovery: Restore normal operations
  5. Lessons Learned: Post-incident review

Breach Response Plan

Immediate Actions:

  1. Identify scope of breach
  2. Contain the breach
  3. Preserve evidence
  4. Notify security team

Communication:

  • Internal stakeholders
  • Affected users (within 72 hours for GDPR)
  • Regulatory bodies if required
  • Law enforcement if necessary

Post-Incident:

  • Root cause analysis
  • Update security measures
  • Document lessons learned
  • Update response plan

Security Checklist

Development

  • All dependencies up to date
  • No secrets in code
  • Input validation on all endpoints
  • Error messages don't leak sensitive info
  • Secure defaults everywhere

Deployment

  • HTTPS only (TLS 1.3)
  • Security headers configured
  • Rate limiting enabled
  • CORS properly configured
  • Secrets in Secrets Manager
  • IAM roles follow least privilege
  • Security groups properly configured
  • Encryption at rest enabled
  • Encryption in transit enabled
  • Monitoring and alerting active

Operations

  • Regular security audits
  • Dependency scanning automated
  • Penetration testing scheduled
  • Incident response plan tested
  • Team security training current
  • Backup and recovery tested

Security Tools

Recommended Tools:

  • OWASP ZAP: Web application security scanner
  • Snyk: Dependency vulnerability scanning
  • npm audit: Built-in npm security auditing
  • AWS Inspector: Infrastructure assessment
  • AWS GuardDuty: Threat detection
  • Trivy: Container image scanning

Regular Audits:

# Check for vulnerable dependencies
npm audit

# Fix vulnerabilities
npm audit fix

# Container scanning
trivy image videogen-backend:latest

# Infrastructure scanning
aws inspector create-assessment-target

Reporting Security Issues

If you discover a security vulnerability:

  1. DO NOT open a public issue
  2. Email: [email protected]
  3. Include:
    • Description of vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if any)

We will acknowledge within 24 hours and provide updates every 48 hours.

There aren’t any published security advisories