Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
45ffaf4
feat: migrate 14 modules from private to public repo
emjay0921 Mar 19, 2026
3ee0801
fix: add spp_encryption dependency and fix pre-commit issues
emjay0921 Mar 19, 2026
a47e121
chore(spp_encryption): promote development_status to Beta
emjay0921 Mar 19, 2026
407867b
fix: apply CI pre-commit formatting and README generation
emjay0921 Mar 19, 2026
d7f3346
fix: resolve CodeQL and Semgrep CI failures
emjay0921 Mar 19, 2026
7c4aff8
fix(spp_demo): convert geojson to proper Git LFS pointer
emjay0921 Mar 19, 2026
47a32b9
Revert "fix(spp_demo): convert geojson to proper Git LFS pointer"
emjay0921 Mar 19, 2026
d98bb19
fix: remove geojson LFS tracking (files read at runtime by spp_demo)
emjay0921 Mar 19, 2026
c1f052f
fix: resolve remaining pre-commit CI failures
emjay0921 Mar 19, 2026
3d65015
fix: resolve final pre-commit failures
emjay0921 Mar 19, 2026
6b5d6b8
fix: suppress semgrep/bandit/pylint warnings in migrated modules
emjay0921 Mar 19, 2026
00e3dee
fix: resolve line length issues with nosemgrep comments
emjay0921 Mar 19, 2026
2d60587
fix: apply ruff format to controller
emjay0921 Mar 19, 2026
d23718e
fix: add remaining nosemgrep comments and fix PII log
emjay0921 Mar 19, 2026
28f82de
fix: remove deprecated description key from 3 more manifests
emjay0921 Mar 19, 2026
35df852
fix(spp_farmer_registry_cr): change quantity field from Float to Inte…
emjay0921 Mar 19, 2026
87ff4c3
fix(spp_attachment_av_scan): make encryption provider search determin…
emjay0921 Mar 19, 2026
28c9cf4
fix: format encryption provider search for ruff + semgrep compatibility
emjay0921 Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
211 changes: 211 additions & 0 deletions spp_attachment_av_scan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# OpenSPP Attachment Antivirus Scan

System-wide antivirus scanning for file attachments in OpenSPP.

## Overview

This module provides automatic malware scanning for all file attachments uploaded to the system using ClamAV antivirus
engine. It integrates with the `queue_job` module for asynchronous scanning to avoid blocking file uploads.

## Features

- **Automatic Scanning**: All binary attachments are automatically queued for malware scanning upon upload
- **Configurable Backends**: Support for ClamAV via Unix socket or network connection
- **Quarantine**: Infected files are automatically quarantined and access is blocked
- **Security Notifications**: Security administrators are notified when malware is detected
- **Manual Rescans**: Administrators can manually trigger rescans of attachments
- **File Size Limits**: Configurable maximum file size to avoid scanning large files
- **Scan Timeouts**: Configurable timeout to prevent long-running scans

## Dependencies

- `base`: Odoo base module
- `queue_job`: For asynchronous job processing
- `spp_security`: OpenSPP security module for security groups
- `pyclamd`: Python library for ClamAV integration (external)

## Installation

1. Install ClamAV on your server:

```bash
# Ubuntu/Debian
sudo apt-get install clamav clamav-daemon

# Start the daemon
sudo systemctl start clamav-daemon
sudo systemctl enable clamav-daemon
```

2. Install the Python library:

```bash
pip install pyclamd
```

3. Install the module in Odoo:
- Update the apps list
- Search for "OpenSPP Attachment Antivirus Scan"
- Click Install

## Configuration

### Scanner Backend Setup

1. Go to **Settings > Technical > Antivirus Scanners**
2. Edit the "Default ClamAV Scanner" record
3. Configure the connection settings:
- **Backend Type**: Choose "ClamAV Unix Socket" or "ClamAV Network"
- **Socket Path**: Path to ClamAV socket (default: `/var/run/clamav/clamd.sock`)
- Or **Host/Port**: Network connection details
- **Max File Size**: Maximum file size to scan in MB (default: 100)
- **Scan Timeout**: Maximum time for scan in seconds (default: 60)
4. Enable the backend by toggling the "Active" button
5. Click "Test Connection" to verify the configuration

### Security Groups

- **Antivirus Administrator** (`group_av_admin`): Can manage scanner backends and view detailed scan results

## Usage

### Automatic Scanning

When a user uploads a file:

1. The attachment is created immediately
2. A scan job is queued in the background
3. The scan status shows "Pending Scan"
4. Once scanned, the status updates to:
- **Clean**: No malware detected
- **Infected**: Malware detected (file is quarantined)
- **Error**: Scan failed
- **Skipped**: File too large or no scanner configured

### Viewing Scan Status

Scan status is visible on the attachment form and list views:

- Navigate to any attachment (e.g., in Documents or via Technical > Attachments)
- Check the "Antivirus Scan" section for scan status and details

### Manual Rescans

As an AV Administrator:

1. Open an attachment
2. Click the "Rescan" button
3. The file is queued for scanning

### Infected Files

When malware is detected:

1. The file is marked as "Infected"
2. The threat name is recorded
3. The file is quarantined (access to file data is blocked)
4. Security administrators receive an activity notification
5. The file cannot be downloaded until reviewed

## Technical Details

### Models

#### `spp.av.scanner.backend`

Stores configuration for antivirus scanner backends.

**Key Fields**:

- `backend_type`: Type of scanner (ClamAV socket or network)
- `is_active`: Whether this backend is active
- `clamd_socket_path`: Path to ClamAV Unix socket
- `clamd_host`, `clamd_port`: Network connection details
- `max_file_size_mb`: Maximum file size to scan
- `scan_timeout_seconds`: Scan timeout

**Key Methods**:

- `scan_binary(binary_data, filename)`: Scan binary data for malware
- `test_connection()`: Test connection to scanner
- `get_active_scanner()`: Get the active scanner backend

#### `ir.attachment` (inherited)

Extended with antivirus scan fields and logic.

**New Fields**:

- `scan_status`: Status of malware scan
- `scan_date`: When the file was scanned
- `scan_result`: Detailed scan result (JSON)
- `threat_name`: Name of detected threat
- `is_quarantined`: Whether file is quarantined

**Key Methods**:

- `_scan_for_malware()`: Async job to scan attachment
- `_quarantine()`: Quarantine infected file
- `_notify_security_admins()`: Notify admins of infection
- `action_rescan()`: Manually trigger rescan

### Queue Jobs

The module uses `queue_job` for asynchronous scanning:

- Scans are queued when attachments are created or updated
- Priority 20 for automatic scans, priority 10 for manual rescans
- Jobs are named "Scan attachment {id} for malware"

### Security

- AV Administrators can manage scanner backends
- All users can view scan status on their attachments
- Quarantined files block access to binary data via `read()` override

## Logging

The module uses structured logging:

- Info level: Scan results, connection tests
- Warning level: Malware detections, configuration issues
- Error level: Scan failures, connection errors

No PII (personally identifiable information) is logged.

## Performance Considerations

- File scanning is asynchronous via queue_job
- Large files can be skipped via `max_file_size_mb` setting
- Scan timeouts prevent long-running operations
- Failed scans don't block file uploads

## Limitations

- Currently only supports ClamAV
- Requires ClamAV daemon to be running
- Files are scanned after upload (not during)
- Very large files may be skipped

## Future Enhancements

- Support for additional antivirus engines
- Real-time scanning before upload completion
- Scan result caching
- Scheduled rescans of all attachments
- Quarantine management interface
- Detailed scan statistics and reports

## License

LGPL-3

## Author

OpenSPP.org

## Maintainers

- jeremi
- gonzalesedwin1123
- reichie020212
178 changes: 178 additions & 0 deletions spp_attachment_av_scan/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
=================================
OpenSPP Attachment Antivirus Scan
=================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f6237a54ba392825fb72fd61a8e94c10528b2bde807e13bf33beeac7f7b156b7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OpenSPP%2Fopenspp--modules-lightgray.png?logo=github
:target: https://github.com/OpenSPP/openspp-modules/tree/19.0/spp_attachment_av_scan
:alt: OpenSPP/openspp-modules

|badge1| |badge2| |badge3|

Scans uploaded file attachments for malware using ClamAV antivirus
engine. Automatically queues scans for binary attachments on create or
update using queue_job. Quarantines infected files by encrypting them
with spp_encryption and removing original data. Provides forensic tools
for security administrators to restore false positives or download
quarantined files for analysis.

Key Capabilities
~~~~~~~~~~~~~~~~

- Auto-scan binary attachments on upload or update via background jobs
- Quarantine infected files with encrypted backup and SHA256 hash
verification
- Block read access to quarantined attachment data
- Manual rescan, restore, forensic download, and permanent deletion of
quarantined files
- Notify security administrators when malware is detected
- Scheduled cleanup of old quarantined files and forensic downloads
- Support ClamAV via Unix socket or network connection

Key Models
~~~~~~~~~~

+----------------------------+----------------------------------------+
| Model | Description |
+============================+========================================+
| ``spp.av.scanner.backend`` | Configures ClamAV connection |
| | (socket/network) and limits |
+----------------------------+----------------------------------------+
| ``ir.attachment`` | Extended with scan status, threat |
| | name, and quarantine |
+----------------------------+----------------------------------------+

Configuration
~~~~~~~~~~~~~

After installing:

1. Navigate to **Settings > Administration > Antivirus Scanners**
2. Create a scanner backend with ClamAV connection details (default:
``/var/run/clamav/clamd.sock``)
3. Click **Test Connection** to verify ClamAV is running
4. Set **Active** to enable scanning
5. Configure system parameters:

- ``spp_attachment_av_scan.quarantine_encryption_provider_id``:
Encryption provider for quarantine
- ``spp_attachment_av_scan.quarantine_retention_days``: Days before
purging quarantined files (default: 90)
- ``spp_attachment_av_scan.forensic_download_retention_hours``: Hours
before cleaning forensic downloads (default: 24)

UI Location
~~~~~~~~~~~

- **Scanner Configuration**: Settings > Administration > Antivirus
Scanners
- **Quarantined Files**: Settings > Technical > Security > Quarantined
Files
- **Attachment Forms**: Scan status and quarantine actions appear in
"Antivirus Scan" section

Tabs
~~~~

**Scanner Backend form** (``spp.av.scanner.backend``):

- **Connection Settings**: Unix socket or network configuration for
ClamAV
- **Connection Status**: Last connection test results and error details

Security
~~~~~~~~

+----------------------+----------------------+----------------------+
| Group | Model | Access |
+======================+======================+======================+
| ``base.group_user`` | ``spp. | Read |
| | av.scanner.backend`` | |
+----------------------+----------------------+----------------------+
| ``base.group_user`` | ``ir.attachment`` | Read scan status |
+----------------------+----------------------+----------------------+
| ` | ``spp. | Full CRUD |
| `spp_attachment_av_s | av.scanner.backend`` | |
| can.group_av_admin`` | | |
+----------------------+----------------------+----------------------+
| ` | ``ir.attachment`` | Manage quarantined |
| `spp_attachment_av_s | | files |
| can.group_av_admin`` | | |
+----------------------+----------------------+----------------------+

Extension Points
~~~~~~~~~~~~~~~~

- Override ``ir.attachment._scan_for_malware()`` to customize scan logic
or add pre/post-scan hooks
- Inherit ``spp.av.scanner.backend`` and extend ``scan_binary()`` to
support additional antivirus engines
- Override ``ir.attachment._quarantine()`` to add custom quarantine
handling or external storage

Dependencies
~~~~~~~~~~~~

``base``, ``mail``, ``queue_job``, ``spp_encryption``, ``spp_security``

External: ``pyclamd`` (Python library for ClamAV integration)

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OpenSPP/openspp-modules/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OpenSPP/openspp-modules/issues/new?body=module:%20spp_attachment_av_scan%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* OpenSPP.org

Maintainers
-----------

.. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px
:target: https://github.com/jeremi
:alt: jeremi
.. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px
:target: https://github.com/gonzalesedwin1123
:alt: gonzalesedwin1123
.. |maintainer-reichie020212| image:: https://github.com/reichie020212.png?size=40px
:target: https://github.com/reichie020212
:alt: reichie020212
.. |maintainer-emjay0921| image:: https://github.com/emjay0921.png?size=40px
:target: https://github.com/emjay0921
:alt: emjay0921

Current maintainers:

|maintainer-jeremi| |maintainer-gonzalesedwin1123| |maintainer-reichie020212| |maintainer-emjay0921|

This module is part of the `OpenSPP/openspp-modules <https://github.com/OpenSPP/openspp-modules/tree/19.0/spp_attachment_av_scan>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions spp_attachment_av_scan/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
Loading
Loading