ClamAV filter icon
Module Id
clamav-filter
Group Id
org.jahia.community
Updated
Requires Jahia
8.2.1.0
Author
Florent BOURASSE
Category
Tools and Utilities
Status
COMMUNITY info

ClamAV filter group_work

security

A Jahia module that scans uploaded files against a ClamAV antivirus daemon and blocks any upload containing detected malware.

Dependencies & Dependants

Dependants
  • NONE

Changelog 1.0.1

Highlights

  • Security hardening of the ClamAV filter pipeline: bounded request buffering, fail-closed on scanner unavailability, SSRF input validation, and TOCTOU mitigation.
  • Full WCAG 2.1 AA audit remediation plus push to AAA 7:1 contrast across the admin UI.
  • Dependency vulnerability fixes (Dependabot/CVE) on @babel/plugin-transform-modules-systemjs and systeminformation.
  • Project guidance docs (AGENTS.md / CLAUDE.md) added for AI-assisted development.

Fixes

Security (431fe9d)

  • MultiReadHttpServletRequest: bound buffered body by configurable max size; throws RequestTooLargeException → HTTP 413 to prevent unauthenticated heap DoS.
  • ClamavFilter: scoped to scan-eligible requests, forwards the wrapped request downstream so scanned bytes equal consumed bytes (closes TOCTOU); fails-closed with HTTP 503 when ClamAV is unreachable instead of silently passing uploads.
  • clamavSaveSettings mutation: validates host charset/length, port range and timeout bounds to block scanner-rewrite SSRF that could bypass scanning.
  • clamavScanTest: caps base64 input length to prevent decode DoS.
  • ClamavServiceImpl: bounded INSTREAM reply reads, CRLF-stripped/truncated log messages, explicit US-ASCII/UTF-8, defensive bounds checks in populateVirusScanResult.
  • ClamavConfig: atomic full-update validation; fields made volatile.

Accessibility — WCAG 2.1 AA (ec95a77c275ea8)

  • aria-hidden="true" on alert icon spans (✓ / ✕) to stop AT reading Unicode names.
  • aria-live="polite" on filename display; kept always in DOM so selection is announced.
  • Replaced 3 dynamic-role live regions with 6 fixed alert+status pairs (save / ping / scan) for stable AT subscriptions.
  • Removed focus() calls on sr-only divs after async ops; aria-live announces without stealing focus.
  • 4 px left accent border on alert boxes for boundary contrast.
  • aria-describedby host-input format hint; tooltip colour darkened #767676 → #6b6b6b.
  • aria-describedby + sr-only rationale on disabled scan section.

Accessibility — WCAG 2 AAA 7:1 contrast (0833b6b3979225)

  • Alert success text: #2e7d32 → #1b5e20 → #175217 (final ~8.3:1 on #e8f5e9).
  • Alert error text: #c62828 → #9e1a1a (~7.1:1 on #fdecea).
  • Buttons/labels: #0077cc → #004a80 (~9.2:1 on white).
  • Input focus borders/outlines aligned for consistency.

Dependency / CVE

  • 2229fbc — upgrade systeminformation 5.31.5 → 5.31.6 via resolution (CVE fix).
  • c5c9a42 — upgrade @babel/plugin-transform-modules-systemjs (Dependabot alert).

Refactoring

  • ClamavFilter / MultiReadHttpServletRequest / ClamavServiceImpl / ClamavConfig substantially reworked alongside the security fix (431fe9d) — clearer scoping, explicit charsets, atomic config swaps.
  • ClamavConstants extended with new bounds/error constants.
  • GraphQL extensions (ClamavMutationExtensionClamavQueryExtension) reorganised around input validation and error reporting.
  • UI components (ClamavFilter.jsx / .scss) restructured around fixed live-region pairs and contrast-compliant tokens.
  • Locale en.json updated for new validation and accessibility messages.

Tests

  • tests/package.json and tests/yarn.lock updated (dependency bumps); no new test commits identified in range.

Docs / Tooling

  • cba8b9d — add Claude basic context.
  • 38113e3 — rename CLAUDE.md to AGENTS.md, add CLAUDE.md reference shim.

Full Changelog1_0_0...1_0_1

FAQ

Configuration

The module reads its settings from the OSGi configuration file:

$JAHIA_DATA_DIR/karaf/etc/org.jahia.community.clamav.cfg
Property Default Description
host localhost Hostname or IP address of the ClamAV daemon
port 3310 Port of the ClamAV daemon
connection_timeout 2000 Maximum time (ms) to wait when connecting to the daemon
read_timeout 20000 Maximum time (ms) to wait for the scan response

Changes to the configuration file are applied immediately — no restart required.

Admin UI

Settings can also be edited directly in the Jahia administration panel:

Administration → Server Health → ClamAV Antivirus Settings

The UI allows editing all four settings, saving them, and testing the connection to the daemon. The connection is tested automatically when the page opens. The file scan test section is disabled when the daemon is not reachable.

How it works

 

  1. When a file is uploaded through Jahia (Media Manager, Forms, etc.), the upload filter intercepts the stream.
  2. The file content is forwarded to the ClamAV daemon over TCP using the INSTREAM command.
  3. If ClamAV reports a threat, the upload is rejected and the virus signature is logged.
  4. If ClamAV is unreachable (daemon down, wrong host/port, timeout), the upload is blocked by default to prevent unscanned files from reaching the repository.

Testing

Start a local ClamAV daemon with Docker:

docker run --interactive --tty --rm --publish 3310:3310 --name clamav clamav/clamav:stable

Wait for the container to print socket found, clamd started. before testing.

To trigger a detection, use the EICAR test file — a standard, harmless file that every compliant antivirus engine flags as malware.

Building from source

 

Requirements: JDK 17+, Maven 3.x, Node.js v22, Yarn v1.22

mvn clean install

The frontend assets are built automatically via the frontend-maven-plugin as part of the Maven build.

How To Install

Requirements

  • Jahia 8.2.1 or later
  • A running ClamAV daemon reachable from the Jahia server
  • graphql-dxm-provider module

Installation

  1. In Jahia, go to Administration → Server settings → System components → Modules
  2. Upload the JAR clamav-filter-X.X.X.jar
  3. Verify the module status is Started

Images

License

MIT License

Copyright (c) 2026 - present Florent BOURASSÉ

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.