]> source.dussan.org Git - rspamd.git/commitdiff
Improve CTYPE_MIXED_BOGUS and MIME_BASE64_TEXT rules
authorSteve Freegard <steve@stevefreegard.com>
Thu, 27 Jul 2017 12:22:36 +0000 (13:22 +0100)
committerAndrew Lewis <nerf@judo.za.org>
Mon, 28 Aug 2017 11:35:17 +0000 (13:35 +0200)
rules/headers_checks.lua
rules/regexp/headers.lua

index 7932afc9061f44dbf18eb81a1aa8013722e7b66a..2e4bae3073f52fdb56f7c709f8e1971b240fabb8 100644 (file)
@@ -916,14 +916,64 @@ rspamd_config.CTYPE_MIXED_BOGUS = {
     if (not ct) then return false end
     local parts = task:get_parts()
     if (not parts) then return false end
-    if (ct:lower():match('^multipart/mixed') ~= nil and #parts < 3)
-    then
-      return true, tostring(#parts)
+    if (not ct:lower():match('^multipart/mixed')) then return false end
+    local found = false
+    -- Check each part and look for a part that isn't multipart/* or text/plain or text/html
+    for _,p in ipairs(parts) do
+      local ct = p:get_header('Content-Type')
+      if (ct) then
+        ct = ct:lower()
+        if (ct:match('^multipart/') or 
+            ct:match('^text/plain') or 
+            ct:match('^text/html')) 
+        then
+          -- Nothing
+        else
+          found = true
+        end
+      end
+    end
+    if (not found) then return true end
+    return false
+  end,
+  description = 'multipart/mixed without non-textual part',
+  score = 1.0,
+  group = 'headers'
+}
+
+local function check_for_base64_text(part)
+  local ct = part:get_header('Content-Type')
+  if (not ct) then return false end
+  ct = ct:lower()
+  if (ct:match('^text')) then
+    -- Check encoding
+    local cte = part:get_header('Content-Transfer-Encoding')
+    if (cte and cte:lower():match('^base64')) then
+      return true
+    end
+  end
+  return false
+end
+
+rspamd_config.MIME_BASE64_TEXT = {
+  callback = function(task)
+    -- Check outer part
+    if (check_for_base64_text(task)) then
+      return true
+    else
+      local parts = task:get_parts()
+      if (not parts) then return false end
+      -- Check each part and look for base64 encoded text parts
+      for _, part in ipairs(parts) do
+        if (check_for_base64_text(part)) then
+          return true
+        end
+      end
     end
     return false
   end,
-  description = 'multipart/mixed with less than 3 total parts',
-  score = 0.1,
+  description = 'Has text part encoded in base64',
+  score = 1.0,
   group = 'headers'
 }
 
index a2e7f3829c9bdfcf4e878aa1ae991b9af9e21628..4d9d2c77df7216dd6f67b17f8ee4e480446a6da1 100644 (file)
@@ -901,14 +901,3 @@ reconf['HAS_XOIP'] = {
   score = 0.0,
   group = 'headers'
 }
-
-reconf['MIME_BASE64_TEXT'] = {
-  re = string.format('(%s && %s) || (%s && %s)',
-                     'Content-Type=/^text/Hi',
-                     'Content-Transfer-Encoding=/^base64/Hi',
-                     'Content-Type=/^text/Bi',
-                     'Content-Transfer-Encoding=/^base64/Bi'),
-  description = 'Message text disguised using base64 encoding',
-  score = 0.0,
-  group = 'headers'
-}