Skip to content

BriacDelaigue/clamav-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

clamav-api logo

Fast ClamAV daemon (clamd) REST API.

clamav-api is a REST API wrapper of ClamAV daemon made in Java Spring Boot. This API provides endpoints to upload and scan files for viruses using ClamAV, an open-source antivirus engine.

The API supports two scanning modes:

  • File upload: Upload a file directly for scanning
  • URL scanning: Provide a URL to download and scan a file

Upon receiving a file or URL, the API connects to a ClamAV server via a TCP socket and streams the file contents for analysis. It returns a detailed JSON response containing metadata about the file and the scan result.

Demo

File Upload Scan

Upload a file using multipart/form-data:

curl -X POST http://localhost:8080/api/v1/scans \
  -F "file=@/path/to/your/file.txt"

URL Scan

Scan a file from a URL:

curl -X POST http://localhost:8080/api/v1/scans \
  -d "url=https://example.com/file.zip"

Successful clean file

If the file is clean (no virus detected), the response will be:

{
  "filename": "clean.txt",
  "extension": "txt",
  "sizeInBytes": 45,
  "scanDurationMillis": 35,
  "isInfected": false,
  "virusName": null,
  "rawResponse": "stream: OK"
}

Response infected file

If the file is infected, the response will be:

{
  "filename": "eicar.txt",
  "extension": "txt",
  "sizeInBytes": 68,
  "scanDurationMillis": 78,
  "isInfected": true,
  "virusName": "Eicar-Test-Signature",
  "rawResponse": "stream: Eicar-Test-Signature FOUND"
}

Error response examples

If the uploaded file exceeds the configured ClamAV size limit:

{
  "error": "Scan failed",
  "message": "File size exceeds ClamAV limit: 50MB"
}

If neither file nor URL is provided:

{
  "error": "Bad Request",
  "message": "Either 'file' or 'url' parameter is required"
}

If the URL is blocked due to SSRF protection:

{
  "error": "Invalid URL",
  "message": "Access to private/local addresses is forbidden"
}

How it works

File Upload Mode

  1. File upload
    A client uploads a file to the API using a POST request with multipart/form-data.

  2. ClamAV integration
    The API opens a socket connection to the configured ClamAV server and sends the file using the INSTREAM protocol.

  3. Scan process
    The file is streamed in chunks to ClamAV. After the entire file is sent, ClamAV scans it and responds with either:

    • "stream: OK" if the file is clean, or
    • "stream: <VIRUS_NAME> FOUND" if a threat is detected.
  4. Detailed JSON response
    The API returns a structured response including:

    • filename: original name of the file
    • extension: file extension
    • sizeInBytes: file size
    • scanDurationMillis: time taken to scan the file
    • isInfected: boolean result
    • virusName: name of the detected virus (if any)
    • rawResponse: the original message from ClamAV

URL Scan Mode

  1. URL validation
    The API validates the provided URL to prevent Server-Side Request Forgery (SSRF) attacks by:

    • Allowing only HTTP/HTTPS protocols
    • Blocking private IP addresses (RFC 1918: 10.x.x.x, 172.16-31.x.x, 192.168.x.x)
    • Blocking loopback addresses (127.x.x.x, localhost)
    • Blocking cloud metadata services (169.254.169.254)
    • Validating redirect URLs to prevent bypasses
  2. File download
    The API downloads the file from the URL with configurable size limits and timeouts.

  3. ClamAV scanning
    The downloaded file is streamed to ClamAV using the same process as file upload mode.

  4. Response
    Returns the same detailed JSON response format as file upload mode.

Installation

Prerequisites

  • Java 21 or higher
  • ClamAV daemon (clamd) running and accessible
  • Maven

Configuration

Configure the maximum file size in application.properties:

# ClamAV Server Configuration
clamd.host=127.0.0.1
clamd.port=3310
clamd.maxfilesize=10MB

# Spring Boot Multipart Configuration
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

Running the API

# Using Maven
mvn spring-boot:run

# Or run the JAR
java -jar clamav-api.jar

Testing

Test with cURL

Scan a local file:

curl -X POST http://localhost:8080/api/v1/scans \
  -F "[email protected]"

Scan from URL:

curl -X POST http://localhost:8080/api/v1/scans \
  -d "url=https://secure.eicar.org/eicar.com.txt"

Test SSRF Protection

These requests should be blocked:

# Localhost
curl -X POST http://localhost:8080/api/v1/scans \
  -d "url=http://localhost:8080/admin"

# Private IP
curl -X POST http://localhost:8080/api/v1/scans \
  -d "url=http://192.168.1.1"

# AWS Metadata service
curl -X POST http://localhost:8080/api/v1/scans \
  -d "url=http://169.254.169.254/latest/meta-data/"

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

😈 ClamAV API – Simple, Fast, and Reliable File Scans ⚑️

Topics

Resources

Stars

Watchers

Forks

Contributors 2

  •  
  •