Skip to content

Latest commit

 

History

History
180 lines (134 loc) · 9.3 KB

README.md

File metadata and controls

180 lines (134 loc) · 9.3 KB

Quarkus Antivirus


Version License Build

A Quarkus extension that lets you scan files for viruses using a pluggable engine architecture.

Out of the box these engines are supported by this extension:

  • ClamAV which is a Linux Native antivirus server
  • VirusTotal which is a REST API to check the Hash of a file to see if it has already been reported for viruses

Getting started

Read the full Antivirus documentation.

Prerequisite

  • Create or use an existing Quarkus application
  • Add the Antivirus extension

Installation

Create a new Antivirus project (with a base Antivirus starter code):

quarkus create app antivirus-app -x=io.quarkiverse.antivirus:quarkus-antivirus

Or add to you pom.xml directly:

<dependency>
    <groupId>io.quarkiverse.antivirus</groupId>
    <artifactId>quarkus-antivirus</artifactId>
    <version>{project-version}</version>
</dependency>

Configuration

Now that you configured your POM to use the service, now you need to configure which scanner(s) you want to use in application.properties:

ClamAV

ClamAV is an open source Linux based virus scanning engine. If you don't set a host quarkus.antivirus.clamav.host a DevService will start a ClamAV instance for you on a dynamic free port, so you can test locally during development.

quarkus.antivirus.clamav.enabled=true

ClamAV Health Check

If you are using the quarkus-smallrye-health extension, quarkus-vault can add a readiness health check to validate the connection to the ClamAV server.

If enabled (by default) and the extension is present, when you access the /q/health/ready endpoint of your application you will have information about the connection validation status.

You can disable this behavior by setting the property quarkus.antivirus.clamav.health.enabled to false in your application.properties.

VirusTotal

VirusTotal is a REST API that analyses suspicious files to detect malware using over 70 antivirus scanners. VirusTotal checks the hash of a file to see if it has been scanned and what the results are. You can set the threshold of how many of the 70+ engines you want to report the file as malicious before you consider it a malicious file using the minimum-votes property.

quarkus.antivirus.virustotal.enabled=true
quarkus.antivirus.virustotal.key=<YOUR API KEY>
quarkus.antivirus.virustotal.minimum-votes=1

Usage

Simply inject the Antivirus service, and it will run the scan against all configured services. It works against InputStream so it can be used in any Quarkus application it is not constrained to REST applications only.

@Path("/antivirus")
@ApplicationScoped
public class AntivirusResource {

    @Inject
    Antivirus antivirus;

    @PUT
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/upload")
    public Response upload(@MultipartForm @Valid final UploadRequest fileUploadRequest) {
        final String fileName = fileUploadRequest.getFileName();
        final InputStream data = fileUploadRequest.getData();
        try {
            // copy the stream to make it resettable
            final ByteArrayInputStream inputStream = new ByteArrayInputStream(
                    IOUtils.toBufferedInputStream(data).readAllBytes());

            // scan the file and check the results
            List<AntivirusScanResult> results = antivirus.scan(fileName, inputStream);
            for (AntivirusScanResult result : results) {
                if (result.getStatus() != Response.Status.OK.getStatusCode()) {
                    throw new WebApplicationException(result.getMessage(), result.getStatus());
                }
            }

            // write the file out to disk
            final File tempFile = File.createTempFile("fileName", "tmp");
            IOUtils.copy(inputStream, new FileOutputStream(tempFile));
        } catch (IOException e) {
            throw new BadRequestException(e);
        }

        return Response.ok().build();
    }
}

Pluggable

We can't anticipate every antivirus engine out there and some may be proprietary. However, the architecture is designed to be pluggable, so you can plug your own engine in. Simply produce a bean that extends the AntivirusEngine interface and it will be picked up and used.

@ApplicationScoped
public class MyCustomEngine implements AntivirusEngine {
    
    @Override
    public boolean isEnabled() {
        return true;
    }
    
    @Override
    public AntivirusScanResult scan(final String filename, final InputStream inputStream) {
        // scan your file here
    }
}

🧑‍💻 Contributing

  • Contribution is the best way to support and get involved in community!
  • Please, consult our Code of Conduct policies for interacting in our community.
  • Contributions to quarkus-antivirus Please check our CONTRIBUTING.md

If you have any idea or question 🤷

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Melloware
Melloware

🚧 💻
Sauli Ketola
Sauli Ketola

⚠️ 🤔
Geoffrey GREBERT
Geoffrey GREBERT

💻
Negoita Silviu
Negoita Silviu

🤔 🐛
Martin Stefanko
Martin Stefanko

💬
Richard Bischof
Richard Bischof

🐛

This project follows the all-contributors specification. Contributions of any kind welcome!