]> git.ipfire.org Git - thirdparty/rspamd.git/log
thirdparty/rspamd.git
4 weeks ago[Fix] Fix memory leak in rspamd_shingles_from_html
Vsevolod Stakhov [Sun, 5 Oct 2025 16:01:48 +0000 (17:01 +0100)] 
[Fix] Fix memory leak in rspamd_shingles_from_html

The struct_sgl object from generate_shingles_from_string_tokens() was only
deleted when pool == nullptr, causing memory leaks when a memory pool was
active. Now struct_sgl is always deleted after copying to res, regardless
of pool allocation method.

4 weeks ago[Fix] Update HTML fuzzy encryption to use helper functions
Vsevolod Stakhov [Sun, 5 Oct 2025 15:36:23 +0000 (16:36 +0100)] 
[Fix] Update HTML fuzzy encryption to use helper functions

The fuzzy_cmd_from_html_part() function was using legacy encryption logic
that only checked rule->peer_key. Updated to use fuzzy_rule_has_encryption()
and fuzzy_select_encryption_keys() helpers for consistency with other fuzzy
command functions and to support separate read/write encryption keys.

4 weeks agoMerge branch 'master' into vstakhov-html-fuzzy
Vsevolod Stakhov [Sun, 5 Oct 2025 15:27:00 +0000 (16:27 +0100)] 
Merge branch 'master' into vstakhov-html-fuzzy

4 weeks agoMerge pull request #5665 from rspamd/vstakhov-fuzzy-rw-split
Vsevolod Stakhov [Sun, 5 Oct 2025 15:15:46 +0000 (16:15 +0100)] 
Merge pull request #5665 from rspamd/vstakhov-fuzzy-rw-split

[Feature] Add separate encryption keys for read/write operations in fuzzy_check

4 weeks ago[Minor] Stop early when found a correct key 5665/head
Vsevolod Stakhov [Sun, 5 Oct 2025 15:05:24 +0000 (16:05 +0100)] 
[Minor] Stop early when found a correct key

4 weeks ago[Fix] Add fallback when only one specific encryption key is set
Vsevolod Stakhov [Sun, 5 Oct 2025 14:57:35 +0000 (15:57 +0100)] 
[Fix] Add fallback when only one specific encryption key is set

When only read_encryption_key or write_encryption_key is configured without
a general encryption_key, the unspecified operation type was left with NULL
keys. Now if only one specific key is set, it's used for both read and write
operations as a fallback, ensuring encryption works in all configurations.

4 weeks ago[Fix] Fix duplicate key filtering in reply decryption
Vsevolod Stakhov [Sun, 5 Oct 2025 14:45:53 +0000 (15:45 +0100)] 
[Fix] Fix duplicate key filtering in reply decryption

When read/write encryption keys fall back to common encryption_key,
rspamd_pubkey_ref() returns pointer to the same object. Previous duplicate
checks using pointer comparison incorrectly filtered out these keys,
causing decryption failures. Now properly checks if key was already added
to the decryption attempt list before adding it.

4 weeks ago[Minor] Refactor encryption key selection into helper functions
Vsevolod Stakhov [Sun, 5 Oct 2025 14:32:09 +0000 (15:32 +0100)] 
[Minor] Refactor encryption key selection into helper functions

Extract repeated key selection logic into fuzzy_select_encryption_keys()
and fuzzy_rule_has_encryption() helper functions. This reduces code
duplication and improves readability across fuzzy_cmd_stat(),
fuzzy_cmd_ping(), fuzzy_cmd_hash(), fuzzy_cmd_from_text_part(),
fuzzy_cmd_from_data_part(), and fuzzy_process_reply() functions.

4 weeks ago[Fix] Fix reply decryption when using only separate read/write keys
Vsevolod Stakhov [Sun, 5 Oct 2025 14:03:48 +0000 (15:03 +0100)] 
[Fix] Fix reply decryption when using only separate read/write keys

In fuzzy_process_reply(), the tag was accessed from encrypted data before
decryption, leading to incorrect key selection. When only separate
read_encryption_key and write_encryption_key were configured (without common
encryption_key), the fallback to NULL keys caused crashes.

Now the function tries decryption with all available key pairs (read, write,
and common) until MAC verification succeeds, properly handling all key
configuration scenarios.

4 weeks ago[Fix] Ensure encryption works with separate read/write keys in fuzzy_check
Vsevolod Stakhov [Sun, 5 Oct 2025 13:51:24 +0000 (14:51 +0100)] 
[Fix] Ensure encryption works with separate read/write keys in fuzzy_check

Fix condition checks that determine whether to use encryption. Previously,
functions checked only rule->peer_key, causing encryption to be disabled
when using only read_encryption_key and write_encryption_key without a
common encryption_key. Now checks for any encryption keys (peer_key,
read_peer_key, or write_peer_key) to properly enable encryption.

4 weeks ago[Feature] Add separate encryption keys for read and write operations in fuzzy_check
Vsevolod Stakhov [Sun, 5 Oct 2025 13:38:24 +0000 (14:38 +0100)] 
[Feature] Add separate encryption keys for read and write operations in fuzzy_check

Allow using different encryption keys for read (CHECK, STAT, PING) and write
(WRITE, DEL) operations by introducing read_encryption_key and write_encryption_key
configuration parameters. Falls back to encryption_key if separate keys are not
specified for backward compatibility.

4 weeks ago[Fix] Allow read/write servers in fuzzy_ping
Vsevolod Stakhov [Sun, 5 Oct 2025 13:29:25 +0000 (14:29 +0100)] 
[Fix] Allow read/write servers in fuzzy_ping

4 weeks agoMerge pull request #5653 from croessner/patch-1
Vsevolod Stakhov [Sun, 5 Oct 2025 12:16:53 +0000 (13:16 +0100)] 
Merge pull request #5653 from croessner/patch-1

Feat: Added rua address exclusion in dmarc.lua

4 weeks ago[Minor] Add safety checks for short HTML to prevent false positives
Vsevolod Stakhov [Sun, 5 Oct 2025 07:32:54 +0000 (08:32 +0100)] 
[Minor] Add safety checks for short HTML to prevent false positives

Require minimum complexity for HTML fuzzy matching:
- At least 2 links (single-link emails too generic)
- At least DOM depth 3 (flat structures too common)

This prevents false positives on trivial HTML like:
  <html><body><p>text <a href="...">link</a></p></body></html>

Such simple structures are not unique enough for reliable fuzzy matching.

4 weeks ago[Minor] Forgotten file
Vsevolod Stakhov [Sat, 4 Oct 2025 21:44:04 +0000 (22:44 +0100)] 
[Minor] Forgotten file

4 weeks ago[Fix] Fix CSS class normalization in HTML fuzzy tokens
Vsevolod Stakhov [Sat, 4 Oct 2025 21:22:52 +0000 (22:22 +0100)] 
[Fix] Fix CSS class normalization in HTML fuzzy tokens

Multiple CSS classes (space-separated) were concatenated incorrectly,
causing token instability. Now take only first class for consistency.

Example:
- Before: class="button primary" → token "a.buttonprimary"
- After:  class="button primary" → token "a.button"

This ensures HTML structure tokens are stable across variations.

4 weeks ago[Minor] Use FUZZY_INCLUDE for HTML fuzzy test configuration
Vsevolod Stakhov [Sat, 4 Oct 2025 20:35:19 +0000 (21:35 +0100)] 
[Minor] Use FUZZY_INCLUDE for HTML fuzzy test configuration

Create fuzzy-html.conf with HTML-specific settings and use
RSPAMD_FUZZY_INCLUDE variable to include it in the fuzzy rule.
This is the correct way to add per-test rule settings.

4 weeks ago[Minor] Add debug logging to HTML fuzzy hash generation
Vsevolod Stakhov [Sat, 4 Oct 2025 20:30:53 +0000 (21:30 +0100)] 
[Minor] Add debug logging to HTML fuzzy hash generation

Add detailed debug messages to track HTML fuzzy hash generation flow:
- Log when fuzzy_cmd_from_html_part is called
- Log HTML shingles enabled/disabled status
- Log HTML part detection
- Log tag count checks
- Log successful/failed hash generation

This helps diagnose issues with HTML fuzzy matching in tests.

4 weeks ago[Minor] Fix HTML fuzzy test to use standard flags and keywords
Vsevolod Stakhov [Sat, 4 Oct 2025 18:46:05 +0000 (19:46 +0100)] 
[Minor] Fix HTML fuzzy test to use standard flags and keywords

Use RSPAMD_FLAG1_NUMBER (50) instead of custom flag 100 to match
existing fuzzy.conf configuration. Add proper test flow with setup
checks and standard Robot Framework keywords.

4 weeks ago[Test] Add functional tests for HTML fuzzy hashing
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:27 +0000 (19:41 +0100)] 
[Test] Add functional tests for HTML fuzzy hashing

Add Robot Framework tests for HTML fuzzy matching:
- html_template_1.eml: legitimate newsletter template
- html_template_1_variation.eml: same structure, different text
- html_phishing.eml: same structure, phishing CTA domains
- html-fuzzy.robot: test suite with add/check/phishing scenarios

Tests verify:
- HTML fuzzy hash generation and matching
- Template variation detection (same structure, different content)
- Phishing detection (same structure, different CTA domains)
- Integration with fuzzy storage backend

4 weeks ago[Minor] Fix luacheck warnings in HTML fuzzy Lua modules
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:25 +0000 (19:41 +0100)] 
[Minor] Fix luacheck warnings in HTML fuzzy Lua modules

- Remove unused variables (rspamd_logger, text_matches, etc.)
- Remove trailing whitespace
- Fix unused return value from register_symbol

4 weeks ago[Minor] Add html_features.h include to fuzzy_check.c
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:22 +0000 (19:41 +0100)] 
[Minor] Add html_features.h include to fuzzy_check.c

Required for accessing rspamd_html_features->tags_count field
when checking HTML fuzzy hash thresholds.

4 weeks ago[Feature] Integrate HTML fuzzy hashing into fuzzy_check module
Vsevolod Stakhov [Sat, 4 Oct 2025 18:34:48 +0000 (19:34 +0100)] 
[Feature] Integrate HTML fuzzy hashing into fuzzy_check module

Add support for HTML structure fuzzy hashing in fuzzy_check plugin:

Core integration:
- Add FUZZY_CMD_FLAG_HTML flag and FUZZY_RESULT_HTML result type
- Add html_shingles, min_html_tags, html_weight options to fuzzy_rule
- Implement fuzzy_cmd_from_html_part() to generate HTML fuzzy commands
- Integrate into fuzzy_generate_commands() for automatic hash generation
- Handle HTML results with configurable weight multiplier

Configuration:
- html_shingles: enable/disable HTML fuzzy hashing per rule
- min_html_tags: minimum HTML tags threshold (default 10)
- html_weight: score multiplier for HTML matches (default 1.0)

Use cases:
1. Brand protection: detect phishing with copied HTML but fake CTA
2. Spam campaigns: group messages by HTML structure
3. Template detection: identify newsletters/notifications
4. Phishing: text match + HTML CTA mismatch = suspicious

Files added:
- lualib/lua_fuzzy_html.lua: helper functions for mismatch detection
- conf/modules.d/fuzzy_check_html.conf: configuration examples
- test/functional/configs/fuzzy_html_test.conf: test configuration
- rules/fuzzy_html_phishing.lua: phishing detection rules

HTML fuzzy works alongside text fuzzy:
- Both hashes generated and sent to storage
- Separate result types allow different handling
- CTA domain verification prevents false positives

Next steps:
- Performance testing on real email corpus
- Fine-tune weights and thresholds
- Collect legitimate brand templates for whitelisting

4 weeks agoMerge branch 'master' into vstakhov-html-fuzzy
Vsevolod Stakhov [Sat, 4 Oct 2025 18:24:49 +0000 (19:24 +0100)] 
Merge branch 'master' into vstakhov-html-fuzzy

4 weeks agoMerge pull request #5662 from rspamd/cursor/RSP-259-fix-dkim-relaxed-bodyhash-calcula...
Vsevolod Stakhov [Sat, 4 Oct 2025 15:04:35 +0000 (21:04 +0600)] 
Merge pull request #5662 from rspamd/cursor/RSP-259-fix-dkim-relaxed-bodyhash-calculation-for-spaces-d7b8

Fix dkim relaxed bodyhash calculation for spaces

4 weeks agoMerge pull request #5664 from rspamd/cursor/RSP-108-fix-rspamd-dkim-key-loading-for...
Vsevolod Stakhov [Sat, 4 Oct 2025 15:02:05 +0000 (21:02 +0600)] 
Merge pull request #5664 from rspamd/cursor/RSP-108-fix-rspamd-dkim-key-loading-for-ed25519-da48

Fix rspamd dkim key loading for ed25519

4 weeks agoMerge pull request #5597 from fatalbanana/sentinel_options
Vsevolod Stakhov [Sat, 4 Oct 2025 14:50:16 +0000 (20:50 +0600)] 
Merge pull request #5597 from fatalbanana/sentinel_options

[Fix] Propagate unused Redis Sentinel options

4 weeks ago[Fix] Fix union handling in ED25519 key loading to prevent memory corruption 5664/head
Vsevolod Stakhov [Sat, 4 Oct 2025 14:48:05 +0000 (15:48 +0100)] 
[Fix] Fix union handling in ED25519 key loading to prevent memory corruption

When loading ED25519 keys from PEM, the code was writing to key_eddsa in the
union and then attempting to free key_ssl pointers, which corrupted the
key_eddsa pointer and caused use-after-free/double-free during cleanup.

The fix saves the EVP_PKEY and BIO pointers to temporary variables, extracts
the raw key, frees the OpenSSL objects, and only then assigns to the union.
This prevents memory corruption and resource leaks.

4 weeks ago[Feature] Add ED25519 support for DKIM signing with OpenSSL version checks
Vsevolod Stakhov [Sat, 4 Oct 2025 14:06:27 +0000 (15:06 +0100)] 
[Feature] Add ED25519 support for DKIM signing with OpenSSL version checks

This commit adds support for ED25519 DKIM signatures when OpenSSL 1.1.1+ is available.
Key changes:

- Added HAVE_ED25519 detection in CMake to check for EVP_PKEY_ED25519 support
- All ED25519-specific code is conditionally compiled based on HAVE_ED25519
- When ED25519 is not supported, informative error messages are returned
ED25519 keys loaded from PEM files are extracted and converted to libsodium format
- Fixed union handling to prevent double-free issues
- Updated tests to dynamically select key type based on request header
- Removed unused dkim-ed25519-pem.conf (cannot be passed via rspamc)

The implementation gracefully degrades on older OpenSSL versions while maintaining
full functionality when ED25519 support is available.

4 weeks agofeat: Add ED25519 support for DKIM signing and verification
Vsevolod Stakhov [Sat, 4 Oct 2025 13:28:19 +0000 (14:28 +0100)] 
feat: Add ED25519 support for DKIM signing and verification

This commit introduces support for ED25519 keys in DKIM signing and verification. It includes changes to the DKIM library to handle ED25519 keys, along with new test cases and configuration files to demonstrate and test this functionality.

Co-authored-by: Vsevolod Stakhov <v@rspamd.com>
4 weeks agoMerge pull request #5660 from rspamd/vstakhov-another-maps-timeouts
Vsevolod Stakhov [Sat, 4 Oct 2025 13:23:05 +0000 (19:23 +0600)] 
Merge pull request #5660 from rspamd/vstakhov-another-maps-timeouts

[Fix] Enforce server-controlled HTTP map refresh intervals

4 weeks agoFix DKIM: Handle lines with only spaces correctly 5662/head
Cursor Agent [Sat, 4 Oct 2025 12:23:40 +0000 (12:23 +0000)] 
Fix DKIM: Handle lines with only spaces correctly

Co-authored-by: v <v@rspamd.com>
4 weeks ago[Fix] Improve HTTP map interval logic for cache validation 5660/head
Vsevolod Stakhov [Sat, 4 Oct 2025 10:56:18 +0000 (11:56 +0100)] 
[Fix] Improve HTTP map interval logic for cache validation

Properly differentiate between maps with and without cache validation:
- With ETag/Last-Modified: use 4x multiplier (cheap conditional requests)
- Without cache validation: enforce strict 10 minute minimum
- Add overflow protection for interval multiplication
- Actually use has_etag/has_last_modified parameters

This avoids overly aggressive slowdown (120x -> 4x) for maps with cache
validation while still preventing abuse of maps without validation.

4 weeks ago[CritFix] Prevent time_t overflow in HTTP map expires header processing
Vsevolod Stakhov [Fri, 3 Oct 2025 21:25:02 +0000 (22:25 +0100)] 
[CritFix] Prevent time_t overflow in HTTP map expires header processing

Add validation to detect and reject absurdly invalid or overflow-inducing
expires headers (>1 year in future). When expires header is invalid or
causes overflow, properly call rspamd_http_map_process_next_check with
expires=0 instead of setting map->next_check=0 which left stale overflow
values.

This prevents crashes and invalid scheduling like 'next check at Thu,
09 Nov 438498967' when servers send malformed Expires headers.

4 weeks ago[Minor] Fix compilation errors and simplify HTML shingles
Vsevolod Stakhov [Sat, 4 Oct 2025 10:24:46 +0000 (11:24 +0100)] 
[Minor] Fix compilation errors and simplify HTML shingles

- Export rspamd_shingles_get_keys_cached() for use in HTML shingles
- Simplify extract_etld1_from_url(): use existing url->tld field
  (in Rspamd, tld already contains eTLD+1/eSLD, no need to parse)
- Add proper reinterpret_cast for const char* to unsigned char*
- Fix variable name conflict (html_content parameter vs local var)
- Use rspamd_url_tld_unsafe() and rspamd_url_host_unsafe() macros

4 weeks ago[Minor] Move HTML shingles implementation to separate C++ file
Vsevolod Stakhov [Sat, 4 Oct 2025 10:12:57 +0000 (11:12 +0100)] 
[Minor] Move HTML shingles implementation to separate C++ file

The HTML shingles code requires C++ (html_content, std::variant, etc.)
but was placed in #ifdef __cplusplus block in shingles.c (a C file),
causing linker errors.

Solution: Move all HTML-specific code to shingles_html.cxx which is
compiled as C++ and properly exports symbols with extern "C" linkage.

Files:
- shingles.c: Keep only C code (text/image shingles)
- shingles_html.cxx: New file with HTML shingles implementation
- CMakeLists.txt: Add shingles_html.cxx to build

4 weeks ago[Minor] Add missing cryptobox.h include in shingles.h
Vsevolod Stakhov [Sat, 4 Oct 2025 10:08:59 +0000 (11:08 +0100)] 
[Minor] Add missing cryptobox.h include in shingles.h

The rspamd_cryptobox_HASHBYTES constant used in rspamd_html_shingle
structure requires cryptobox.h to be included.

4 weeks ago[Feature] Add HTML fuzzy hashing for structural similarity matching
Vsevolod Stakhov [Sat, 4 Oct 2025 08:57:26 +0000 (09:57 +0100)] 
[Feature] Add HTML fuzzy hashing for structural similarity matching

Implement fuzzy hashing algorithm for HTML content to enable efficient
matching of messages by HTML structure, independent of text content.

This feature allows:
- Detecting similar HTML emails (newsletters, notifications, spam campaigns)
- Phishing protection: similar structure but different CTA domains
- Brand protection: identify legitimate vs fake branded emails
- Template detection: group emails from the same template

Implementation details:

1. Multi-layer hash approach:
   - Direct hash: blake2b of all HTML tokens (for exact matching)
   - Structure shingles: sliding window over DOM tags (for fuzzy matching)
   - CTA domains hash: critical for phishing detection (30% weight)
   - All domains hash: top-10 most frequent domains (15% weight)
   - Features hash: bucketed HTML statistics (5% weight)

2. Token format: "tagname[.class][@domain]"
   - Example: "a.button@facebook.com", "div.header", "img@cdn.example.com"
   - Tracking classes filtered (utm, analytics, etc.)
   - Dynamic classes normalized (UUIDs, digits removed)

3. CTA domain detection:
   - Integrated with existing url_button_weights from lua_cta
   - Links with weight > 0.3 considered as CTA
   - CTA mismatch heavily penalizes similarity (×0.3)

4. Comparison algorithm:
   - 50% structure similarity (DOM skeleton)
   - 30% CTA domains (must match for legitimate similarity)
   - 15% all domains similarity
   - 5% statistical features

5. API:
   C: rspamd_shingles_from_html() / rspamd_html_shingles_compare()
   Lua: text_part:get_html_fuzzy_hashes(mempool)

6. Memory efficient:
   - Uses mempool for temporary allocations
   - Final structure: ~304 bytes (32 shingles + metadata + hashes)
   - Performance: <1ms for typical HTML (100-200 tags)

7. Compatible with existing fuzzy storage infrastructure:
   - Structure shingles use same format as text shingles
   - Can be sent to fuzzy storage via standard protocol
   - Additional hashes (CTA, domains, features) can be stored as extensions

Key design decisions:

- Direct hash prevents false positives from MinHash collisions
  (like text parts: crypto_hash(all_tokens) for exact match)
- Sliding window (size 3) provides tolerance to small structural changes
- Bucketing of numeric features ensures stability
- CTA domain verification critical for phishing prevention

Use cases:
- Whitelisting legitimate branded emails by HTML structure
- Blacklisting spam campaigns with varying personalized text
- Detecting phishing: legitimate structure + different CTA = suspicious
- Fuzzy storage integration for distributed matching

Files changed:
- src/libutil/shingles.h: Add rspamd_html_shingle structure and API
- src/libutil/shingles.c: Implement HTML fuzzy hashing (~540 lines)
- src/lua/lua_mimepart.c: Add text_part:get_html_fuzzy_hashes() method

Future work:
- Integration with fuzzy_check module
- Configuration options (min_html_tags, similarity_threshold)
- Rules for phishing detection based on HTML similarity
- Separate fuzzy storage type for HTML hashes

5 weeks ago[Fix] Enforce server-controlled HTTP map refresh intervals
Vsevolod Stakhov [Fri, 3 Oct 2025 21:00:44 +0000 (22:00 +0100)] 
[Fix] Enforce server-controlled HTTP map refresh intervals

Prevent aggressive HTTP map polling by implementing proper interval bounds:
- Cap absurdly high Expires headers (>8h) to min(map_interval * 10, 8h)
- Enforce configured map_interval as minimum when server requests faster refresh
- Apply 10 minute minimum interval when no Expires header and low map_interval
- Simplify logic by consolidating interval calculation in single function

This change ensures servers can control refresh rates and prevents clients
from causing issues with overly aggressive polling behavior.

5 weeks agoMerge pull request #5658 from rspamd/cursor/RSP-268-fix-duplicate-symbol-in-once...
Vsevolod Stakhov [Fri, 3 Oct 2025 20:27:19 +0000 (02:27 +0600)] 
Merge pull request #5658 from rspamd/cursor/RSP-268-fix-duplicate-symbol-in-once-received-plugin-624d

Fix duplicate symbol in once_received plugin

5 weeks agoFix: Return early in check_quantity_received to avoid unnecessary checks 5658/head
Cursor Agent [Fri, 3 Oct 2025 19:22:18 +0000 (19:22 +0000)] 
Fix: Return early in check_quantity_received to avoid unnecessary checks

Co-authored-by: v <v@rspamd.com>
5 weeks agoMerge pull request #5654 from rspamd/cursor/RSP-251-add-vault-kv-version-2-support...
Vsevolod Stakhov [Fri, 3 Oct 2025 19:21:56 +0000 (01:21 +0600)] 
Merge pull request #5654 from rspamd/cursor/RSP-251-add-vault-kv-version-2-support-6402

Add vault kv version 2 support

5 weeks agoMerge pull request #5656 from rspamd/cursor/RSP-271-implement-metadefender-hash-looku...
Vsevolod Stakhov [Fri, 3 Oct 2025 19:21:29 +0000 (01:21 +0600)] 
Merge pull request #5656 from rspamd/cursor/RSP-271-implement-metadefender-hash-lookup-module-09c0

Implement Metadefender hash lookup module

5 weeks ago[Feature] Add symbol categories for MetaDefender and VirusTotal 5656/head
Vsevolod Stakhov [Fri, 3 Oct 2025 14:43:27 +0000 (15:43 +0100)] 
[Feature] Add symbol categories for MetaDefender and VirusTotal

Implemented a category-based symbol system for hash lookup antivirus
scanners (MetaDefender and VirusTotal) to replace dynamic scoring:

- Added 4 symbol categories: CLEAN (-0.5), LOW (2.0), MEDIUM (5.0), HIGH (8.0)
- Replaced full_score_engines with threshold-based categorization (low_category, medium_category)
- Fixed symbol registration in antivirus.lua to use rule instead of config
- Updated cache format to preserve symbol category across requests
- Added backward compatibility for old cache format
- Added symbols registration and metric score assignment
- Updated configuration documentation with examples

The new system provides:
- Clear threat categorization instead of linear interpolation
- Proper symbol weights applied automatically
- Consistent behavior between MetaDefender and VirusTotal
- Cache that preserves symbol categories

Configuration example:
metadefender {
  apikey = "KEY";
  type = "metadefender";
  minimum_engines = 3;
  low_category = 5;
  medium_category = 10;
}

5 weeks agoRefactor: Clean up MetaDefender scanner code
Cursor Agent [Fri, 3 Oct 2025 12:30:33 +0000 (12:30 +0000)] 
Refactor: Clean up MetaDefender scanner code

Co-authored-by: v <v@rspamd.com>
5 weeks agofeat: Add MetaDefender antivirus scanner
Cursor Agent [Fri, 3 Oct 2025 12:13:07 +0000 (12:13 +0000)] 
feat: Add MetaDefender antivirus scanner

Co-authored-by: v <v@rspamd.com>
5 weeks ago[Minor] Add some of my cursor rules
Vsevolod Stakhov [Fri, 3 Oct 2025 11:26:50 +0000 (12:26 +0100)] 
[Minor] Add some of my cursor rules

5 weeks ago[Minor] Don't touch ChangeLog 5654/head
Vsevolod Stakhov [Fri, 3 Oct 2025 11:17:45 +0000 (12:17 +0100)] 
[Minor] Don't touch ChangeLog

5 weeks ago[Fix] Add nil check for vault_data in show_handler
Vsevolod Stakhov [Fri, 3 Oct 2025 11:08:26 +0000 (12:08 +0100)] 
[Fix] Add nil check for vault_data in show_handler

Prevent runtime errors when parsing Vault KV v2 responses if obj.data.data is nil.
This adds a safety check before accessing vault_data.selectors, consistent with
other handlers in the file (newkey_handler and roll_handler).

5 weeks ago[Fix] Fix luacheck warnings in vault.lua
Vsevolod Stakhov [Fri, 3 Oct 2025 11:06:36 +0000 (12:06 +0100)] 
[Fix] Fix luacheck warnings in vault.lua

Remove trailing whitespace from lines 132, 145, 156, 166

5 weeks agofeat: Add Vault KV v2 support for DKIM key management
Cursor Agent [Fri, 3 Oct 2025 09:52:51 +0000 (09:52 +0000)] 
feat: Add Vault KV v2 support for DKIM key management

Co-authored-by: v <v@rspamd.com>
5 weeks agoMerge pull request #5647 from rspamd/vstakhov-llm-context
Vsevolod Stakhov [Thu, 2 Oct 2025 15:54:25 +0000 (21:54 +0600)] 
Merge pull request #5647 from rspamd/vstakhov-llm-context

[Feature] Add user/domain context support for LLM-based classification

5 weeks agoFeat: Added rua address exclusion in dmarc.lua 5653/head
Christian Rößner [Thu, 2 Oct 2025 15:53:51 +0000 (17:53 +0200)] 
Feat: Added rua address exclusion in dmarc.lua

Added a new configuration option exclude_rua_addresses in the dmarc reporting section.

See #5220

5 weeks ago[Feature] Improve LLM prompt and add sender frequency tracking 5647/head
Vsevolod Stakhov [Thu, 2 Oct 2025 13:53:25 +0000 (14:53 +0100)] 
[Feature] Improve LLM prompt and add sender frequency tracking

* Update default prompt to reduce false positives on legitimate emails
  - Explicitly recognize verification emails as legitimate
  - Require MULTIPLE red flags for phishing classification
  - Add guidance on known/frequent senders
* Add sender frequency detection in context
  - Classify senders as: new, occasional, known, frequent
  - Based on sender_counts from user context
  - Passed to LLM via context snippet
* Prompt instructs LLM to reduce phishing score for known senders
* Helps avoid false positives on transactional/verification emails

5 weeks ago[Feature] Improve GPT module with uncertain caching and server timeout
Vsevolod Stakhov [Thu, 2 Oct 2025 13:32:22 +0000 (14:32 +0100)] 
[Feature] Improve GPT module with uncertain caching and server timeout

* Add GPT_UNCERTAIN symbol for caching uncertain classifications
  - Cache results even when no consensus is reached
  - Avoid repeated expensive LLM queries for borderline cases
  - Set X-GPT-Reason header with detailed vote statistics
* Add server-side timeout support for OpenAI API requests
  - New request_timeout parameter (optional, multiplied by 0.95)
  - Only sent if explicitly configured (not all APIs support this)
  - Accounts for connection setup and data transfer overhead
* Fix max_ham_prob initialization (was 0, now correctly 1.0)
* Add pcall protection for fold_header_with_encoding with raw fallback
* Improve error messages for token limit exceeded
* Add detailed logging for context snippets and consensus decisions
* Pass debug_module parameter to llm_context functions

5 weeks ago[Feature] Add cache expiration timestamps to debug logs
Vsevolod Stakhov [Thu, 2 Oct 2025 13:32:02 +0000 (14:32 +0100)] 
[Feature] Add cache expiration timestamps to debug logs

* Show when cached data will expire in human-readable format
* Log expiration time both when caching and after successful write
* Helps with debugging cache TTL issues

5 weeks ago[Feature] Add bidirectional context support for LLM
Vsevolod Stakhov [Thu, 2 Oct 2025 13:30:20 +0000 (14:30 +0100)] 
[Feature] Add bidirectional context support for LLM

* Unify context for incoming and outgoing mail
* Same identity used for authenticated/local sender and recipient
* Follows replies module pattern for direction detection
* Make llm_context.lua module-agnostic with debug_module parameter
* Improve userdata handling (use :sub instead of string.sub)
* Add nil-safety to all debug logging calls
* Add cache expiration timestamps to context logs

5 weeks ago[Fix] Add full Lua traceback to HTTP callback errors
Vsevolod Stakhov [Thu, 2 Oct 2025 13:28:32 +0000 (14:28 +0100)] 
[Fix] Add full Lua traceback to HTTP callback errors

Improved error diagnostics in lua_http_finish_handler by adding
rspamd_lua_traceback handler. Now shows complete call stack with
file names and line numbers when Lua HTTP callbacks fail, making
debugging much easier.

5 weeks ago[Feature] Add user/domain context support for LLM-based classification
Vsevolod Stakhov [Wed, 1 Oct 2025 09:49:41 +0000 (10:49 +0100)] 
[Feature] Add user/domain context support for LLM-based classification

* Add llm_context.lua module for Redis-based conversation context
* Context features: sliding window, top senders, keywords, flagged phrases
* Use low-level word API (get_words('full')) with stop_word flags
* Flexible gating via maps/selectors (enable_map/enable_expression)
* Update context even when GPT condition not met (BAYES_SPAM/HAM)
* Add min_messages warm-up threshold to prevent weak context injection
* Configurable scope: user/domain/esld with TTL and sliding window

5 weeks ago[Minor] Update version of rspamd to 3.13.2
Vsevolod Stakhov [Tue, 30 Sep 2025 10:30:09 +0000 (11:30 +0100)] 
[Minor] Update version of rspamd to 3.13.2

5 weeks agoRelease 3.13.1 3.13.1
Vsevolod Stakhov [Tue, 30 Sep 2025 10:18:55 +0000 (11:18 +0100)] 
Release 3.13.1

* [Feature] Archive module: Full support for encrypted ZIP archives with ZipCrypto and AES encryption
* [Feature] Archive module: Both reading and writing of AES-encrypted ZIP archives is supported
* [Feature] Archive module: Updated Lua bindings for libarchive
* [Feature] Encrypted maps: Support for encrypted maps to enable new distribution scenarios
* [Feature] Redis TLS: Configurable TLS connections in Redis backend
* [Feature] Map helpers alignment: Enforce 64-byte alignment to prevent unaligned memory access
* [Feature] Enhanced CLI for secretbox with additional security test coverage
* [Fix] MIME encoding: Major overhauls and multiple fixes for MIME encoding logic
* [Fix] MIME encoding: Improved handling and decoding of UTF-8 in MIME headers
* [Fix] Learning system: Numerous fixes to learn checks and autolearn flag handling
* [Fix] Learning system: Prevention of duplicate message learning
* [Fix] Learning system: Extended multiclass learning test coverage
* [Fix] Critical: Fixed bug when converting zero-length strings to numbers
* [Fix] Critical: Fixed XML prolog detection in lua_magic module
* [Fix] Build: Fixed build issues on 32-bit platforms
* [Fix] Compatibility: Improved compatibility with Lua versions above 5.1
* [Fix] Empty input: Addressed issues with empty input handling in lua_magic
* [Fix] Testing: Improved stability of automated testing with multiple test fixes
* [Fix] Minor compatibility improvements (buffer allocation, missing cmath include)

5 weeks agoMerge pull request #5644 from rspamd/vstakhov-encrypted-maps
Vsevolod Stakhov [Mon, 29 Sep 2025 13:51:36 +0000 (19:51 +0600)] 
Merge pull request #5644 from rspamd/vstakhov-encrypted-maps

[Feature] Add support for encrypted maps

5 weeks ago[Feature] Add support for encrypted maps 5644/head
Vsevolod Stakhov [Mon, 29 Sep 2025 12:59:50 +0000 (13:59 +0100)] 
[Feature] Add support for encrypted maps

5 weeks agoMerge pull request #5642 from rspamd/vstakhov-secretbox-features
Vsevolod Stakhov [Mon, 29 Sep 2025 08:05:16 +0000 (14:05 +0600)] 
Merge pull request #5642 from rspamd/vstakhov-secretbox-features

[Feature] Improve secretbox CLI

5 weeks agoMerge pull request #5643 from moisseev/e2e
Vsevolod Stakhov [Mon, 29 Sep 2025 08:05:05 +0000 (14:05 +0600)] 
Merge pull request #5643 from moisseev/e2e

[Test] Handle multiple alerts in E2E scan test

5 weeks ago[Fix] Fix allocation of the control buffer
Vsevolod Stakhov [Sun, 28 Sep 2025 21:06:01 +0000 (22:06 +0100)] 
[Fix] Fix allocation of the control buffer

* Refactored rspamd_control_fill_msghdr to accept
  a caller-provided control buffer, fixing the
  lifetime bug where a pointer to a local array
  was stored in msg_control.
* Replaced static buffers with automatic (stack)
  buffers at the exact call sites of sendmsg/recvmsg,
  so PowerPC and similar platforms won’t choke on
  non-constant expressions.

Issue: #5637

5 weeks ago[Minor] Fix compatibility 5642/head
Vsevolod Stakhov [Sun, 28 Sep 2025 20:20:56 +0000 (21:20 +0100)] 
[Minor] Fix compatibility

5 weeks agoMerge branch 'master' into vstakhov-secretbox-features
Vsevolod Stakhov [Sun, 28 Sep 2025 19:34:36 +0000 (01:34 +0600)] 
Merge branch 'master' into vstakhov-secretbox-features

5 weeks agoMerge branch 'master' into e2e 5643/head
Vsevolod Stakhov [Sun, 28 Sep 2025 19:34:24 +0000 (01:34 +0600)] 
Merge branch 'master' into e2e

5 weeks ago[Fix] Avoid invocation of strlcpy on string_view
Vsevolod Stakhov [Sun, 28 Sep 2025 19:27:50 +0000 (20:27 +0100)] 
[Fix] Avoid invocation of strlcpy on string_view

5 weeks ago[Minor] Add missing cmath include
Vsevolod Stakhov [Sun, 28 Sep 2025 19:04:18 +0000 (20:04 +0100)] 
[Minor] Add missing cmath include

5 weeks ago[Feature] Improve secretbox CLI
Vsevolod Stakhov [Sun, 28 Sep 2025 18:56:34 +0000 (19:56 +0100)] 
[Feature] Improve secretbox CLI

5 weeks ago[Test] Handle multiple alerts in E2E scan test
Alexander Moisseev [Sun, 28 Sep 2025 17:13:20 +0000 (20:13 +0300)] 
[Test] Handle multiple alerts in E2E scan test

by waiting for new alert appearance

5 weeks ago[Fix] Align map helpers to 64 bytes
Vsevolod Stakhov [Sun, 28 Sep 2025 14:39:18 +0000 (15:39 +0100)] 
[Fix] Align map helpers to 64 bytes

5 weeks ago[CritFix] Handle 0 length strings when converting to numbers
Vsevolod Stakhov [Sun, 28 Sep 2025 10:25:07 +0000 (11:25 +0100)] 
[CritFix] Handle 0 length strings when converting to numbers

Issue: #5640

5 weeks agoMerge pull request #5639 from rspamd/vstakhov-learn-cache-fix
Vsevolod Stakhov [Sat, 27 Sep 2025 16:55:22 +0000 (22:55 +0600)] 
Merge pull request #5639 from rspamd/vstakhov-learn-cache-fix

[Fix] Learn cache fix

5 weeks ago[Test] Update test cases for multiclass learning 5639/head
Vsevolod Stakhov [Sat, 27 Sep 2025 16:38:25 +0000 (17:38 +0100)] 
[Test] Update test cases for multiclass learning

5 weeks ago[Test] Avoid relearning the same message
Vsevolod Stakhov [Sat, 27 Sep 2025 16:09:31 +0000 (17:09 +0100)] 
[Test] Avoid relearning the same message

5 weeks ago[Fix] Reset autolearn flag when doing manual learn
Vsevolod Stakhov [Sat, 27 Sep 2025 14:02:06 +0000 (15:02 +0100)] 
[Fix] Reset autolearn flag when doing manual learn

5 weeks ago[Fix] Another learn checks fix
Vsevolod Stakhov [Sat, 27 Sep 2025 09:56:47 +0000 (10:56 +0100)] 
[Fix] Another learn checks fix

6 weeks ago[Fix] Learn cache fix
Vsevolod Stakhov [Fri, 26 Sep 2025 15:18:28 +0000 (16:18 +0100)] 
[Fix] Learn cache fix

6 weeks agoMerge pull request #5586 from japc/rbl_pipeline
Vsevolod Stakhov [Fri, 26 Sep 2025 13:34:39 +0000 (19:34 +0600)] 
Merge pull request #5586 from japc/rbl_pipeline

[Minor] Minor RBL pipeline fixes

6 weeks agoMerge pull request #5626 from laudable-labs/feat/redis-tls
Vsevolod Stakhov [Fri, 26 Sep 2025 13:25:47 +0000 (19:25 +0600)] 
Merge pull request #5626 from laudable-labs/feat/redis-tls

[Feature] Redis - add configurable TLS for connections

6 weeks agoMerge pull request #5636 from rspamd/vstakhov-fix-mime-encoding
Vsevolod Stakhov [Fri, 26 Sep 2025 12:18:33 +0000 (18:18 +0600)] 
Merge pull request #5636 from rspamd/vstakhov-fix-mime-encoding

Fix mime encoding

6 weeks agoStore TLS opts in lua stack, no strdup/free 5626/head
Justin Dossey [Thu, 25 Sep 2025 16:52:45 +0000 (09:52 -0700)] 
Store TLS opts in lua stack, no strdup/free

- Removed g_strdup/g_free of TLS paths in src/lua/lua_redis.c.
- Now we:
  - Keep TLS values (booleans + strings) on the Lua stack temporarily.
  - Use an absolute table index (so gettable calls aren’t confused by
    the growing stack).
  - Call rspamd_redis_pool_connect_ext while those values are on the
    stack.
  - Pop all postponed values and then the table in one go immediately
    after the connect call.
- The C++ pool still copies into std::string on element creation; we
  only ensure Lua strings live through the call without extra
  allocations.

6 weeks ago[Fix] Fix bad utf8 decoding in mime headers 5636/head
Vsevolod Stakhov [Thu, 25 Sep 2025 13:14:48 +0000 (14:14 +0100)] 
[Fix] Fix bad utf8 decoding in mime headers

6 weeks ago[Fix] More rework on mime encoding
Vsevolod Stakhov [Thu, 25 Sep 2025 12:53:53 +0000 (13:53 +0100)] 
[Fix] More rework on mime encoding

6 weeks ago[CritFix] Fix mime encoding logic
Vsevolod Stakhov [Thu, 25 Sep 2025 11:48:13 +0000 (12:48 +0100)] 
[CritFix] Fix mime encoding logic

6 weeks ago[Fix] Fix build on 32 bit platforms
Vsevolod Stakhov [Thu, 25 Sep 2025 10:48:32 +0000 (11:48 +0100)] 
[Fix] Fix build on 32 bit platforms

6 weeks ago[Fix] Fix XML prolog detection in lua_magic
Vsevolod Stakhov [Thu, 25 Sep 2025 09:40:22 +0000 (10:40 +0100)] 
[Fix] Fix XML prolog detection in lua_magic

6 weeks ago[Fix] Fix empty input in lua_magic
Vsevolod Stakhov [Thu, 25 Sep 2025 08:31:08 +0000 (09:31 +0100)] 
[Fix] Fix empty input in lua_magic

Issue: #5633

6 weeks agoMerge pull request #5628 from rspamd/vstakhov-encrypted-zip
Vsevolod Stakhov [Wed, 24 Sep 2025 10:07:09 +0000 (16:07 +0600)] 
Merge pull request #5628 from rspamd/vstakhov-encrypted-zip

[Project] Add encrypted zip support to archives module

6 weeks ago[Project] Switch to libarchive for encrypted zip archives 5628/head
Vsevolod Stakhov [Tue, 23 Sep 2025 19:34:38 +0000 (20:34 +0100)] 
[Project] Switch to libarchive for encrypted zip archives

6 weeks ago[Project] Switch to ZipCrypto for encrypted zip archives (AES is not supported by...
Vsevolod Stakhov [Tue, 23 Sep 2025 17:18:03 +0000 (18:18 +0100)] 
[Project] Switch to ZipCrypto for encrypted zip archives (AES is not supported by libarchive)

6 weeks ago[Minor] Some tests fixes
Vsevolod Stakhov [Tue, 23 Sep 2025 10:56:54 +0000 (11:56 +0100)] 
[Minor] Some tests fixes

6 weeks ago[Minor] Add tests for encrypted zip support + fix some memory issues
Vsevolod Stakhov [Tue, 23 Sep 2025 10:51:20 +0000 (11:51 +0100)] 
[Minor] Add tests for encrypted zip support + fix some memory issues

6 weeks ago[Project] Add Lua bindings for encrypted zip support
Vsevolod Stakhov [Tue, 23 Sep 2025 09:10:13 +0000 (10:10 +0100)] 
[Project] Add Lua bindings for encrypted zip support

6 weeks ago[Project] Add encrypted zip support to archives module
Vsevolod Stakhov [Mon, 22 Sep 2025 20:31:46 +0000 (21:31 +0100)] 
[Project] Add encrypted zip support to archives module

This commit adds encrypted zip support to the archives module.

It adds a new function to the archives module that encrypts a zip file using AES-256-CBC.

It also adds a new function to the archives module that decrypts a zip file using AES-256-CBC.

6 weeks agoUse clang-format-18 to address indentation mismatches
Justin Dossey [Mon, 22 Sep 2025 15:35:16 +0000 (08:35 -0700)] 
Use clang-format-18 to address indentation mismatches

6 weeks agoFix errors found by @vstakhov in #5626
Justin Dossey [Mon, 22 Sep 2025 15:25:46 +0000 (08:25 -0700)] 
Fix errors found by @vstakhov in #5626

- remove redundant `ensure_ssl_inited` function and calls. Core SSL init
  should suffice.
- Refactor TLS initiation into `redis_pool_elt::initiate_tls(...)` to
  eliminate duplication
- Switch TLS flags to `bool` in the public struct
- Fix ephemeral string usage in lua by duplicating the values into
  locals and freeing after connect. Flags are boolean. (it's not super
  likely that Lua will GC the strings before we connect to Redis, but
  this ensures that it won't be a problem)
- Remove the redis TLS options propagation unit test

Build succeeds and C++ unit tests pass.