Skip to main content

Malware Scanning System

Torvus Platform includes a comprehensive malware scanning system that automatically scans all uploaded documents for viruses and malware threats using ClamAV, an open-source antivirus engine.

System Overview​

The malware scanning system protects your organization by:

  • Automatic Scanning: Every uploaded document is scanned before being made available
  • Real-Time Detection: ClamAV engine detects threats using an up-to-date virus signature database
  • Automatic Quarantine: Infected files are immediately quarantined and isolated
  • Compliance Support: Audit logs and compliance reports for SOC 2, ISO 27001, GDPR
  • Management UI: Security administrators can review and manage quarantined documents
  • Performance: Scans complete in 200-500ms for most documents

Architecture​

Document Upload
↓
Platform API
↓
DocumentScanner ──→ ClamAV Daemon (Railway)
↓ ↓
Database Virus Database
(Supabase) (CVD files)
↓
Quarantine Storage
(Supabase)

Components​

  1. ClamAV Client (clam-client.ts): Low-level TCP client for ClamAV daemon communication
  2. Document Scanner (scanner.ts): Orchestration layer managing scan lifecycle and database updates
  3. Quarantine Manager (quarantine.ts): Handles file quarantine and storage isolation
  4. Database Schema: Tracks scan results, quarantine events, and audit logs
  5. Console UI: Management interface for security administrators
  6. Metrics Dashboard: Real-time monitoring and compliance reporting

Key Features​

Real-Time Scanning​

Every document upload triggers an automatic scan:

  1. User uploads document to vault
  2. Platform API creates scan record (status: PENDING)
  3. File contents sent to ClamAV daemon
  4. ClamAV scans against virus signature database
  5. Result stored in database (CLEAN, INFECTED, or FAILED)
  6. Infected files automatically quarantined

Quarantine System​

When malware is detected:

  • Automatic Isolation: File is immediately moved to quarantine storage
  • Access Prevention: Document marked as inaccessible to all users
  • Audit Trail: Quarantine event logged with virus signature
  • Management: Security admins can review, release, or delete quarantined files
  • Compliance: Generate reports for regulatory requirements

Monitoring & Compliance​

Security administrators have access to:

  • Metrics Dashboard: Real-time statistics on scans, infections, failures
  • Top Threats: Most common virus signatures detected
  • Affected Vaults: Which vaults have quarantined documents
  • Timeline: Historical scan activity over 30 days
  • Compliance Reports: Automated reports for SOC 2, ISO 27001, GDPR audits

Quick Start​

Local Development​

  1. Start ClamAV with Docker Compose:

    cd apps/platform
    docker-compose up -d clamav

    First startup takes 2-5 minutes as ClamAV downloads virus definitions (200+ MB).

  2. Add environment variables to .env.local:

    CLAMAV_HOST=localhost
    CLAMAV_PORT=3310
    CLAMAV_TIMEOUT=5000
    ENABLE_DOCUMENT_SCANNING=true
    SCAN_EMIT_ON_FINALIZE=true
  3. Wait for ClamAV to be ready:

    docker-compose logs -f clamav
    # Wait for: "clamd[1]: Self checking every 3600 seconds."
  4. Test the connection:

    import { createClamAVClientFromEnv } from '@/lib/malware-scanning/clam-client';

    const client = createClamAVClientFromEnv();
    const isAlive = await client.ping();
    console.log('ClamAV is ready:', isAlive);

Production Setup​

See the Deployment Guide for complete production deployment instructions including:

  • Railway ClamAV setup
  • Vercel environment configuration
  • Health checks and testing
  • Rollback procedures

Usage Examples​

Scanning a File​

import { DocumentScanner } from '@/lib/malware-scanning/scanner';

const scanner = new DocumentScanner();
const result = await scanner.scanDocument(
documentId,
fileBuffer,
vaultId
);

if (result.isInfected) {
console.log(`Malware detected: ${result.viruses.join(', ')}`);
// Automatically quarantined if autoQuarantine is enabled
} else {
console.log('File is clean');
}

Testing with EICAR​

The EICAR test file is a standard malware test signature that's safe but detected by all antivirus engines.

// EICAR test virus (safe, but detected as malware)
const eicar = Buffer.from(
'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
);

const result = await scanner.scanDocument('test-doc', eicar, 'test-vault');
console.log(result.isInfected); // true
console.log(result.viruses); // ["Eicar-Test-Signature"]

Health Check​

import { ClamAVClient } from '@/lib/malware-scanning/clam-client';

const client = new ClamAVClient({ host: 'localhost' });

// Ping ClamAV
const isAlive = await client.ping(); // true if responding

// Get version
const version = await client.version();
// e.g., "ClamAV 1.0.0/26000/Mon Oct 16 2023"

Performance​

  • Average scan time: 200-500ms per file (10MB PDF)
  • Throughput: ~50-100 files/second (depends on file size)
  • Memory: ClamAV requires 2GB RAM minimum (4GB recommended)
  • Startup time: 2-5 minutes (initial virus definition download)
  • Success rate: > 95% (target)
  • P95 latency: < 2 seconds
  • P99 latency: < 5 seconds

Security Considerations​

Virus Definition Updates​

ClamAV automatically updates virus definitions:

  • Frequency: Every 2-4 hours
  • Source: ClamAV virus database (CVD files)
  • Size: ~400MB signature database
  • Manual Update: freshclam command for immediate update

False Positives​

Occasionally, clean files may be flagged:

  • Review: Security admins can review quarantined files
  • Release: False positives can be released from quarantine
  • Reporting: Report false positives to ClamAV project

Network Security​

  • Internal Communication: ClamAV uses internal Railway network
  • Port: 3310 (not exposed publicly)
  • Protocol: TCP with INSTREAM command
  • Encryption: No TLS required for internal network

Error Handling​

The system gracefully handles failures:

  • Connection Timeout: Retries with exponential backoff (up to 3 attempts)
  • ClamAV Down: Marks scan as FAILED, allows manual review
  • Invalid Files: Reports error without blocking upload
  • Resource Limits: Respects file size limits (100MB default)
import { ClamAVClient, ClamAVError } from '@/lib/malware-scanning/clam-client';

try {
const result = await client.scanBuffer(fileBuffer);
} catch (error) {
if (error instanceof ClamAVError) {
switch (error.code) {
case 'TIMEOUT':
// Retry or alert
break;
case 'CONNECTION_ERROR':
// Check if ClamAV is running
break;
case 'SCAN_ERROR':
// Log and alert
break;
}
}
}

Troubleshooting​

ClamAV Not Responding​

# Check if container is running
docker ps | grep clamav

# Check logs
docker-compose logs clamav

# Restart container
docker-compose restart clamav

Connection Timeout​

  • Increase CLAMAV_TIMEOUT environment variable (default: 5000ms)
  • Check network connectivity to Railway service
  • Verify ClamAV is fully started (wait for "Self checking" log)

Outdated Virus Definitions​

Force an update:

docker-compose exec clamav freshclam

Or in Railway:

railway run -- freshclam

Resources​

Support​

For malware scanning issues:


Last Updated: October 2025