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.
Upload a file using multipart/form-data:
curl -X POST http://localhost:8080/api/v1/scans \
-F "file=@/path/to/your/file.txt"
Scan a file from a URL:
curl -X POST http://localhost:8080/api/v1/scans \
-d "url=https://example.com/file.zip"
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"
}
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"
}
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"
}
-
File upload
A client uploads a file to the API using aPOST
request withmultipart/form-data
. -
ClamAV integration
The API opens a socket connection to the configured ClamAV server and sends the file using theINSTREAM
protocol. -
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.
-
Detailed JSON response
The API returns a structured response including:filename
: original name of the fileextension
: file extensionsizeInBytes
: file sizescanDurationMillis
: time taken to scan the fileisInfected
: boolean resultvirusName
: name of the detected virus (if any)rawResponse
: the original message from ClamAV
-
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
-
File download
The API downloads the file from the URL with configurable size limits and timeouts. -
ClamAV scanning
The downloaded file is streamed to ClamAV using the same process as file upload mode. -
Response
Returns the same detailed JSON response format as file upload mode.
- Java 21 or higher
- ClamAV daemon (clamd) running and accessible
- Maven
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
# Using Maven
mvn spring-boot:run
# Or run the JAR
java -jar clamav-api.jar
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"
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/"
MIT
Contributions are welcome! Please feel free to submit a Pull Request.