]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Restore strict ARC header ordering to comply with RFC 8617
authorVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 15 Oct 2025 17:44:55 +0000 (18:44 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 15 Oct 2025 17:44:55 +0000 (18:44 +0100)
The split of ARC header insertion into two separate lua_mime.modify_headers
calls removed the explicit ordering enforcement. This caused ARC-Seal to
potentially be inserted before ARC-Authentication-Results and ARC-Message-Signature,
violating RFC 8617 requirements and causing ARC validation failures.

Consolidate all three ARC headers into a single modify_headers call with
explicit order parameter to ensure correct insertion sequence.

src/plugins/lua/arc.lua

index 39fb874fd1976d4d036a1d7636769a61b4bf691d..c3438b8e41a73e24d46ad5970f65daf93718b917 100644 (file)
@@ -581,17 +581,6 @@ local function arc_sign_seal(task, params, header)
     cur_auth_results,
     { stop_chars = ';', structured = true, encode = false })
 
-  -- Add AAR and AMS headers first
-  lua_util.debugm(N, task, 'adding ARC-Authentication-Results: %s', cur_auth_results)
-  lua_util.debugm(N, task, 'adding ARC-Message-Signature: %s', header)
-
-  lua_mime.modify_headers(task, {
-    add = {
-      ['ARC-Authentication-Results'] = { order = 1, value = cur_auth_results },
-      ['ARC-Message-Signature'] = { order = 1, value = header },
-    },
-  })
-
   -- Create ARC-Seal signature manually using SHA256 hash
   -- We must canonicalize all ARC headers in order and sign them
   local sha_ctx = hash.create_specific('sha256')
@@ -681,10 +670,15 @@ local function arc_sign_seal(task, params, header)
   local folded_sig = rspamd_util.encode_base64(rspamd_util.decode_base64(sig_b64), 70, nl_type)
   cur_arc_seal = cur_arc_seal .. folded_sig
 
+  -- Add all ARC headers in a single call with explicit ordering
+  lua_util.debugm(N, task, 'adding ARC-Authentication-Results: %s', cur_auth_results)
+  lua_util.debugm(N, task, 'adding ARC-Message-Signature: %s', header)
   lua_util.debugm(N, task, 'adding ARC-Seal: %s', cur_arc_seal)
 
   lua_mime.modify_headers(task, {
     add = {
+      ['ARC-Authentication-Results'] = { order = 1, value = cur_auth_results },
+      ['ARC-Message-Signature'] = { order = 1, value = header },
       ['ARC-Seal'] = {
         order = 1,
         value = lua_util.fold_header_with_encoding(task,
@@ -692,6 +686,8 @@ local function arc_sign_seal(task, params, header)
           { structured = true, encode = false })
       }
     },
+    -- RFC 8617 requires strict ordering of ARC headers
+    order = { 'ARC-Authentication-Results', 'ARC-Message-Signature', 'ARC-Seal' },
   })
   task:insert_result(settings.sign_symbol, 1.0,
     string.format('%s:s=%s:i=%d', params.domain, params.selector, cur_idx))