This document explains how file uploads behave in different scenarios with and without ClamAV virus scanning available.
YES, the upload workflow works even if you don't have the ClamAV Docker container running, but the behavior depends on your environment and configuration.
| Scenario | ClamAV Status | Environment | REQUIRE_VIRUS_SCAN | Upload Result |
|---|---|---|---|---|
| Development (Default) | โ Not Running | development | not set | โ ALLOWED with warning |
| Development (Strict) | โ Not Running | development | true |
โ BLOCKED |
| Development (Skip) | โ Not Running | development | any + SKIP_VIRUS_SCAN=true |
โ ALLOWED (no scan) |
| Production (Default) | โ Not Running | production | not set | โ BLOCKED |
| Production (Fail-Open) | โ Not Running | production | any + VIRUS_SCAN_FAIL_OPEN=true |
โ ALLOWED with warning |
| Any Environment | โ Running | any | any | โ ALLOWED (with scan) |
# Start server normally in development
bin/rails server
# Result: Uploads work WITHOUT ClamAV
# Response includes:
{
"file": {
"virus_scan": {
"status": "clean",
"safe": true,
"warning": "Virus scanning unavailable - allowed in development"
}
}
}# In production environment
RAILS_ENV=production bin/rails server
# Result: Uploads BLOCKED without ClamAV
# Response:
{
"message": "File upload rejected: Virus scanning service unavailable"
}# Force virus scanning requirement
REQUIRE_VIRUS_SCAN=true bin/rails server
# Behavior: Uploads blocked if ClamAV unavailable
# Use case: Security-critical development/staging# Completely skip virus scanning
SKIP_VIRUS_SCAN=true bin/rails server
# Behavior: No virus scanning attempted
# Use case: Fast local development, testing# Allow uploads when scanner unavailable (NOT RECOMMENDED for production)
VIRUS_SCAN_FAIL_OPEN=true bin/rails server
# Behavior: Uploads allowed with warning if ClamAV down
# Use case: Emergency production fallback# Setup
docker-compose stop clamav
bin/rails server
# Test Result
โ
File uploaded successfully in development mode
Scan status: clean
Safe: true
Warning: Virus scanning unavailable - allowed in development# Setup
docker-compose stop clamav
REQUIRE_VIRUS_SCAN=true bin/rails server
# Test Result
โ Upload correctly blocked in strict mode
Message: File upload rejected: Virus scanning service unavailable# Setup
docker-compose up -d clamav
bin/rails server
# Test Result
โ
File uploaded successfully with virus scanning
Scan status: clean (or infected if virus detected)
Safe: true (or false if virus detected)
Scanned at: 2025-06-19T13:28:32.459ZThe upload workflow follows this decision tree:
def perform_virus_scan(file)
# Skip in test environment if configured
if Rails.env.test? && ENV['SKIP_VIRUS_SCAN'] == 'true'
return safe_result_with_skip_reason
end
scanner = FileProcessing::VirusScanner.instance
# Check if ClamAV is available
unless scanner.service_available?
# In development, be lenient unless explicitly required
if Rails.env.development? && ENV['REQUIRE_VIRUS_SCAN'] != 'true'
return safe_result_with_warning # โ
ALLOW
else
return unsafe_result_with_error # โ BLOCK
end
end
# ClamAV is available - perform actual scan
scanner.scan_file(file)
end# Option 1: Default (works without ClamAV)
bin/rails server
# Option 2: Fast development (skip scanning)
SKIP_VIRUS_SCAN=true bin/rails server
# Option 3: Test with ClamAV
docker-compose up -d clamav
bin/rails server# Recommended: Always require ClamAV
RAILS_ENV=production REQUIRE_VIRUS_SCAN=true bin/rails server
# With ClamAV running
docker-compose up -d clamav
RAILS_ENV=production bin/rails server# Test without virus scanning (faster)
SKIP_VIRUS_SCAN=true bin/rails test
# Test with virus scanning
docker-compose up -d clamav
bin/rails test- Production with ClamAV: Full virus protection
- Development default: Allows development without ClamAV setup
- Strict mode: Ensures virus scanning when security is critical
- Fail-open in production: Could allow malware if ClamAV fails
- Skip scanning: No virus protection at all
- Production without ClamAV + fail-open: Security vulnerability
# Check if container is running
docker-compose ps clamav
# Test from Rails
bundle exec rails runner "puts FileProcessing::VirusScanner.instance.service_available?"# Quick test
ruby script/simple_virus_test.rb
# Comprehensive test
ruby script/test_virus_scanning.rb
# Test without ClamAV
ruby script/test_no_clamav.rb
# Test strict mode
ruby script/test_strict_mode.rb| Variable | Default | Effect |
|---|---|---|
REQUIRE_VIRUS_SCAN |
false |
Force virus scanning requirement |
SKIP_VIRUS_SCAN |
false |
Skip virus scanning entirely |
VIRUS_SCAN_FAIL_OPEN |
false |
Allow uploads when scanner fails |
CLAMAV_HOST |
localhost |
ClamAV server hostname |
CLAMAV_PORT |
3310 |
ClamAV server port |
- Default setup: Use normal development mode (works without ClamAV)
- Security testing: Periodically test with ClamAV enabled
- CI/CD: Use
SKIP_VIRUS_SCAN=truefor faster automated tests
- Always run ClamAV: Use
docker-compose up -d clamav - Set strict mode: Use
REQUIRE_VIRUS_SCAN=true - Monitor health: Check ClamAV container status regularly
- Never use fail-open: Avoid
VIRUS_SCAN_FAIL_OPEN=truein production
- Mandatory scanning: Always require ClamAV
- Fail-closed policy: Block uploads when scanning fails
- Regular testing: Use virus scanning test scripts
- Monitor logs: Watch for virus detection events
- Check if ClamAV container is running:
docker-compose ps clamav - Verify Rails can connect:
bundle exec rails runner "puts FileProcessing::VirusScanner.instance.service_available?" - Check environment variables:
echo $REQUIRE_VIRUS_SCAN
- Verify you're not in development mode with default settings
- Check if
VIRUS_SCAN_FAIL_OPEN=trueis set - Confirm ClamAV is actually scanning: check logs
- Wait for container to be healthy:
docker-compose logs -f clamav - Check port binding:
docker-compose ps clamav - Test direct connection:
telnet localhost 3310
VIRUS_SCANNING_TEST_RESULTS.md- Detailed test resultsscript/simple_virus_test.rb- Quick verification scriptscript/test_virus_scanning.rb- Comprehensive test suiteREADME.md- General setup and configuration