# Ensure plugin-based rules used for FP avoidance exist # even if the plugin is not loaded, or an older version is loaded # __KAM_BODY_LENGTH_LT_128 ifplugin Mail::SpamAssassin::Plugin::BodyEval if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) meta __LCL__KAM_BODY_LENGTH_LT_128 __KAM_BODY_LENGTH_LT_128 else meta __LCL__KAM_BODY_LENGTH_LT_128 0 endif else meta __LCL__KAM_BODY_LENGTH_LT_128 0 endif # __KAM_BODY_LENGTH_LT_512 ifplugin Mail::SpamAssassin::Plugin::BodyEval if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) meta __LCL__KAM_BODY_LENGTH_LT_512 __KAM_BODY_LENGTH_LT_512 else meta __LCL__KAM_BODY_LENGTH_LT_512 0 endif else meta __LCL__KAM_BODY_LENGTH_LT_512 0 endif # __KAM_BODY_LENGTH_LT_1024 ifplugin Mail::SpamAssassin::Plugin::BodyEval if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) meta __LCL__KAM_BODY_LENGTH_LT_1024 __KAM_BODY_LENGTH_LT_1024 else meta __LCL__KAM_BODY_LENGTH_LT_1024 0 endif else meta __LCL__KAM_BODY_LENGTH_LT_1024 0 endif # __ENV_AND_HDR_FROM_MATCH ifplugin Mail::SpamAssassin::Plugin::HeaderEval meta __LCL__ENV_AND_HDR_FROM_MATCH __ENV_AND_HDR_FROM_MATCH else meta __LCL__ENV_AND_HDR_FROM_MATCH 0 endif # __TVD_SPACE_RATIO ifplugin Mail::SpamAssassin::Plugin::BodyEval # else meta __TVD_SPACE_RATIO 0 endif # #header REPLYTO_MANY_AT Reply-To =~ /\@.+\@/ #describe REPLYTO_MANY_AT More than one @ in Reply-To: # #header SENDER_MANY_AT Sender =~ /\@.+\@/ #describe SENDER_MANY_AT More than one @ in Sender: # #header FROM_MANY_AT From =~ /\@.+\@/ #describe FROM_MANY_AT More than one @ in From: # header RDNS_LOCALHOST X-Spam-Relays-External =~ /^\[ ip=(?!127)\d+\.\d+\.\d+\.\d+ rdns=localhost(?:\.localdomain)? /i describe RDNS_LOCALHOST Sender's public rDNS is "localhost" #body EU_SPAM_LAW m,Directive 2000/31/EC of the European Parliament,i #describe EU_SPAM_LAW Quoting "European Parliament" spam law ifplugin Mail::SpamAssassin::Plugin::MIMEHeader mimeheader __HTML_ATTACH_01 Content-Type =~ m,\btext/html\b.+\.html?\b,i mimeheader __HTML_ATTACH_02 Content-Disposition =~ m,\bfilename="?[^"]+\.html?\b,i meta HTML_ATTACH __HTML_ATTACH_01 || __HTML_ATTACH_02 describe HTML_ATTACH HTML attachment to bypass scanning? mimeheader OBFU_HTML_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.html?\b,i describe OBFU_HTML_ATTACH HTML attachment with non-text MIME type mimeheader OBFU_TEXT_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.txt\b,i describe OBFU_TEXT_ATTACH Text attachment with non-text MIME type #score OBFU_TEXT_ATTACH 2.5 tflags OBFU_TEXT_ATTACH publish mimeheader OBFU_DOC_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.(?:doc|rtf)\b,i describe OBFU_DOC_ATTACH MS Document attachment with generic MIME type #score OBFU_DOC_ATTACH 0.25 mimeheader OBFU_PDF_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.pdf\b,i describe OBFU_PDF_ATTACH PDF attachment with generic MIME type #score OBFU_PDF_ATTACH 0.25 mimeheader OBFU_JPG_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.jpe?g\b,i describe OBFU_JPG_ATTACH JPG attachment with generic MIME type #score OBFU_JPG_ATTACH 1.50 mimeheader OBFU_GIF_ATTACH Content-Type =~ m,\bapplication/octet-stream\b.+\.gif\b,i describe OBFU_GIF_ATTACH GIF attachment with generic MIME type #score OBFU_GIF_ATTACH 1.50 meta OBFU_ATTACH_MISSP __FROM_RUNON && (OBFU_HTML_ATTACH || OBFU_TEXT_ATTACH || OBFU_DOC_ATTACH || OBFU_PDF_ATTACH || OBFU_JPG_ATTACH || OBFU_GIF_ATTACH) describe OBFU_ATTACH_MISSP Obfuscated attachment type and misspaced From # mimeheader ECMSNGR_MH X-ecm-part-format =~ /./ # describe ECMSNGR_MH eC-Messenger header mimeheader __CTYPE_NULL Content-Type =~ /^\s*;/ meta CTYPE_NULL __CTYPE_NULL describe CTYPE_NULL Malformed Content-Type header mimeheader __ZIP_ATTACH_NOFN Content-Type =~ m,\bapplication/(?:zip|x-(?:zip-)?compress(?:ed)?)[;\s]*$,i meta OBFU_HTML_ATT_MALW __ZIP_ATTACH_NOFN && __HTML_ATTACH_02 describe OBFU_HTML_ATT_MALW HTML attachment with incorrect MIME type - possible malware mimeheader __PDF_ATTACH Content-Type =~ m,\bapplication/pdf\b,i mimeheader __ATTACH_NAME_NO_EXT Content-Type =~ m,\bname\s?=\s?"(?!=\?)[^."]+",i meta DOC_ATTACH_NO_EXT __ATTACH_NAME_NO_EXT && (__PDF_ATTACH || __DOC_ATTACH_MT) describe DOC_ATTACH_NO_EXT Document attachment with suspicious name mimeheader __ZIP_ATTACH_MT Content-Type =~ m,\bapplication/(?:zip|x-(?:zip-)?compress(?:ed)?)\b,i else meta __HTML_ATTACH_01 0 meta __HTML_ATTACH_02 0 meta __CTYPE_NULL 0 meta __ZIP_ATTACH_NOFN 0 meta __PDF_ATTACH 0 meta __ATTACH_NAME_NO_EXT 0 meta __ZIP_ATTACH_MT 0 endif # general case of spample observation #header MUA_ONE_WORD X-Mailer =~ /^[A-Za-z][a-z]*$/ #describe MUA_ONE_WORD Single word X-Mailer: not CamelCase body DEAR_EMAIL_USER /^\s?(?:Dear\s|Attention:?\s?)(?:E|Web)-?mail\s(?:account\s)?User\b/i describe DEAR_EMAIL_USER Dear Email User: #score DEAR_EMAIL_USER 3.0 # from users list spamples 8/2009 uri URI_NUMERIC_CCTLD m;^[a-z]+://(?:\d+\.){2,}[a-z][a-z]/;i describe URI_NUMERIC_CCTLD CCTLD URI with multiple numeric subdomains # various MUAs header __PHP_NOVER_MUA X-Mailer =~ /^PHP$/ header __PHPMAILER_MUA X-Mailer =~ /^PHPMailer\b/ ifplugin Mail::SpamAssassin::Plugin::DKIM meta PHP_NOVER_MUA __PHP_NOVER_MUA && !__DKIM_DEPENDABLE && !__TO_NO_BRKTS_HTML_ONLY && !__MSGID_OK_DIGITS && !__UPPERCASE_25_50 && !__RP_MATCHES_RCVD && !__GIF_ATTACH else meta PHP_NOVER_MUA __PHP_NOVER_MUA && !__TO_NO_BRKTS_HTML_ONLY && !__MSGID_OK_DIGITS && !__UPPERCASE_25_50 && !__RP_MATCHES_RCVD && !__GIF_ATTACH endif describe PHP_NOVER_MUA Mail from PHP with no version number score PHP_NOVER_MUA 3.50 # limit tflags PHP_NOVER_MUA publish # From should have whitespace between the comment and the address # Better S/O, good enough for standalone rule header __FROM_MISSPACED From =~ /^\s*"[^"]*" 10 points already #meta __FROM_MISSP_URI __FROM_RUNON_UNCODED && __HAS_ANY_URI #meta FROM_MISSP_URI __FROM_MISSP_URI && !__NOT_SPOOFED && !__RCD_RDNS_MTA_MESSY && !MISSING_MIMEOLE && !__REPTO_QUOTE && !__UNSUB_LINK && !__MSGID_OK_HEX && !__MAIL_LINK && !__MIME_QP && !__BUGGED_IMG && !MIME_BASE64_TEXT && !__CTYPE_MULTIPART_ALT && !__MTLANDROID_MUA && !__XEROXWORKCTR_MUA && !__PHP_MUA && !__AMADEUSMS_MUA && !__FLASHMAIL_MUA && !__DKIM_EXISTS && !__HAS_SENDER && !__RP_MATCHES_RCVD && !__THREADED && !__TAG_EXISTS_META #describe FROM_MISSP_URI From misspaced, has URI #score FROM_MISSP_URI 2.00 # max meta FROM_MISSP_USER (__FROM_RUNON && NSL_RCVD_FROM_USER) describe FROM_MISSP_USER From misspaced, from "User" # all hits > 10 points already #meta FROM_MISSP_NO_TO (__FROM_RUNON && MISSING_HEADERS) #describe FROM_MISSP_NO_TO From misspaced, To missing meta FROM_MISSP_TO_UNDISC (__FROM_RUNON && __TO_UNDISCLOSED) describe FROM_MISSP_TO_UNDISC From misspaced, To undisclosed ifplugin Mail::SpamAssassin::Plugin::DKIM meta __FROM_MISSP_DKIM (__FROM_RUNON_UNCODED && __DKIM_DEPENDABLE) tflags __FROM_MISSP_DKIM net meta FROM_MISSP_DKIM __FROM_MISSP_DKIM && !__CTYPE_MULTIPART_ALT && !__MIME_QP && !__BUGGED_IMG && !__DOS_HAS_LIST_UNSUB && !__MIME_BASE64 && !__MTLANDROID_MUA && !__XEROXWORKCTR_MUA && !__PHP_MUA && !__AMADEUSMS_MUA && !__FLASHMAIL_MUA describe FROM_MISSP_DKIM From misspaced, DKIM dependable else meta __FROM_MISSP_DKIM 0 endif meta __FROM_MISSP_REPLYTO __FROM_RUNON && __REPLYTO_EXISTS meta FROM_MISSP_REPLYTO __FROM_MISSP_REPLYTO && !__NOT_SPOOFED && !__RCD_RDNS_MTA_MESSY && !__TO___LOWER && !__COMMENT_EXISTS && !__UNSUB_LINK && !__MIME_QP && !__CTYPE_MULTIPART_ALT && !__JM_REACTOR_DATE && !__PLING_QUERY describe FROM_MISSP_REPLYTO From misspaced, has Reply-To ## To the same #header TO_MISSPACED To =~ /^\s*"[^"]*"]+>\n.*Organization: \1\n/ism header __FROM_EQ_ORG_2 ALL =~ /\nOrganization: ([^\n]+)\n.*From: "?\1"?/ism #meta FROM_EQ_ORG __FROM_EQ_ORG_1 || __FROM_EQ_ORG_2 #describe FROM_EQ_ORG From: same as Organization: #tflags FROM_EQ_ORG publish # observed in UCE 9/2009 #header __HDRS_LCASE ALL =~ /\n(?:Reply-to|Message-id|Content-type|X-MSMail-priority|from|subject|to|Disposition-notification-to):/sm header __HDRS_LCASE ALL =~ /\n(?:Message-id|Content-type|X-MSMail-priority|from|subject|to|cc|Disposition-notification-to):/sm tflags __HDRS_LCASE multiple maxhits=3 # __MSGID_APPLEMAIL is uppercase-only GUID message_id. This may be redundant. header __MSGID_GUID Message-ID =~ /^ 1 meta __TOOMANY_HDRS_LCASE __HDRS_LCASE > 2 ifplugin Mail::SpamAssassin::Plugin::FreeMail meta MANY_HDRS_LCASE __MANY_HDRS_LCASE && !__HDRS_LCASE_KNOWN && !__VIA_ML && !__freemail_safe && !__THREADED && !__UNUSABLE_MSGID && !__DOS_SINGLE_EXT_RELAY && !__DKIM_EXISTS && !__NOT_SPOOFED && !__BUGGED_IMG && !__MIME_QP && !__RDNS_NONE else meta MANY_HDRS_LCASE __MANY_HDRS_LCASE && !__HDRS_LCASE_KNOWN && !__VIA_ML && !__THREADED && !__UNUSABLE_MSGID && !__DOS_SINGLE_EXT_RELAY && !__DKIM_EXISTS && !__NOT_SPOOFED && !__BUGGED_IMG && !__MIME_QP && !__RDNS_NONE endif describe MANY_HDRS_LCASE Odd capitalization of multiple message headers score MANY_HDRS_LCASE 0.10 # limit # Some metas that appear to perform well in masscheck #meta __HDRS_LCASE_1K __HDRS_LCASE && __SINGLE_HEADER_1K #meta HDRS_LCASE_1K __HDRS_LCASE_1K && !__HDRS_LCASE_KNOWN && !__VIA_ML && !__MIME_QP && !__BUGGED_IMG && !__BOUNCE_RPATH_NULL && !__NOT_SPOOFED && !__DKIM_EXISTS && !__RDNS_NONE #describe HDRS_LCASE_1K Odd capitalization of message headers + long header #score HDRS_LCASE_1K 0.50 # limit meta HDRS_LCASE_IMGONLY __HDRS_LCASE && __HTML_IMG_ONLY && !__HDRS_LCASE_KNOWN describe HDRS_LCASE_IMGONLY Odd capitalization of message headers + image-only HTML score HDRS_LCASE_IMGONLY 0.10 # limit # observed in UCE from India, 9/2009 header MDN_BOTCHED Disposition-notification-to =~ /<>/ describe MDN_BOTCHED Malformed return receipt header # observed in spam 9/2009 header __HDRS_MISSP ALL =~ /\n(?:Subject|From|To):\S/ism meta HDRS_MISSP __HDRS_MISSP && !__TAG_EXISTS_HEAD && !__DKIM_EXISTS && !__RP_MATCHES_RCVD && !__NOT_SPOOFED && !__LCL__ENV_AND_HDR_FROM_MATCH describe HDRS_MISSP Misspaced headers score HDRS_MISSP 2.000 # limit header SPAMMY_MIME_BDRY_01 Content-Type =~ /boundary="\@\@BOUNDARY"/ describe SPAMMY_MIME_BDRY_01 Spammy MIME boundary string #score SPAMMY_MIME_BDRY_01 0.10 # testing header __TB_MIME_BDRY_NO_Z Content-Type =~ /boundary="-{8,}(?:[1-9]){16}/ meta TBIRD_SUSP_MIME_BDRY __MUA_TBIRD && __TB_MIME_BDRY_NO_Z describe TBIRD_SUSP_MIME_BDRY Unlikely Thunderbird MIME boundary # too dangerous even if it has a good S/O and hits >20% of spam in masschecks #meta TBIRD_SPOOF __MUA_TBIRD && !__HAS_IN_REPLY_TO && !__HAS_X_REF && !__THREADED && !__VIA_ML && !__NOT_SPOOFED && !__HAS_SENDER && !__HAS_ERRORS_TO && !__HAS_X_BEEN_THERE && !__RP_MATCHES_RCVD && !ALL_TRUSTED && !__TO_EQ_FROM_DOM && !__RCD_RDNS_MAIL_MESSY && !__MIME_BASE64 && !__S25R_1 #describe TBIRD_SPOOF Claims Thunderbird mail client but looks suspicious #score TBIRD_SPOOF 2.00 # limit # seen in a few HTML fraud spams rawbody RUNON_SHY /(?:\­){3}/i describe RUNON_SHY Repeating soft hyphens #score RUNON_SHY 0.1 tflags RUNON_SHY nopublish # Seen all too often header LAZY_LISTWASHING To =~ /\@(?:example\.com|example\.domain|your\.domain|some\.domain|domain\.dom|somewhere\.tld|somewhere\.com|your\.?domain\.com|your\.favorite\.machine)\b/i describe LAZY_LISTWASHING Lazy spammer, painfully obvious bogus addresses #score LAZY_LISTWASHING 0.25 # Little to work with body __PLS_REVIEW /\b(?:please|kindly)\s(?:(?:re)?view|see)(?:\s\w+)?\sattach(?:ed|ment)\b/i body __DLND_ATTACH /\bdownload\sthe\sattach(?:ed|ment)\b/i ifplugin Mail::SpamAssassin::Plugin::MIMEHeader mimeheader __DOC_ATTACH_MT Content-Type =~ m,\bapplication/(?:msword|rtf|vnd\.ms-word|vnd\.openxmlformats-officedocument\.wordprocessingml\.document)\b,i mimeheader __DOC_ATTACH_FN1 Content-Type =~ /="[^"]+\.(?:docx?|rtf)"/i mimeheader __DOC_ATTACH_FN2 Content-Disposition =~ /="[^"]+\.(?:docx?|rtf)"/i meta __DOC_ATTACH (__DOC_ATTACH_MT || __DOC_ATTACH_FN1 || __DOC_ATTACH_FN2) mimeheader __PDF_ATTACH_MT Content-Type =~ m,\bapplication/pdf\b,i mimeheader __PDF_ATTACH_FN1 Content-Type =~ /="[^"]+\.pdf"/i mimeheader __PDF_ATTACH_FN2 Content-Disposition =~ /="[^"]+\.pdf"/i meta __PDF_ATTACH (__PDF_ATTACH_MT || __PDF_ATTACH_FN1 || __PDF_ATTACH_FN2) # observed in 419 spam mimeheader CDISP_SZ_MANY Content-Disposition =~ /\bsize\s?=\s?\d.*\bsize\s?=\s?\d/ describe CDISP_SZ_MANY Suspicious MIME header score CDISP_SZ_MANY 2.0 # limit else meta __DOC_ATTACH_MT 0 meta __DOC_ATTACH_FN1 0 meta __DOC_ATTACH_FN2 0 meta __DOC_ATTACH 0 meta __PDF_ATTACH_MT 0 meta __PDF_ATTACH_FN1 0 meta __PDF_ATTACH_FN2 0 meta __PDF_ATTACH 0 endif ifplugin Mail::SpamAssassin::Plugin::FreeMail meta __FREEMAIL_DOC_PDF (__DOC_ATTACH || __PDF_ATTACH) && (FREEMAIL_FROM || FREEMAIL_REPLYTO) meta FREEMAIL_DOC_PDF __FREEMAIL_DOC_PDF describe FREEMAIL_DOC_PDF MS document or PDF attachment, from freemail meta FREEMAIL_DOC_PDF_BCC __FREEMAIL_DOC_PDF && __TO_UNDISCLOSED describe FREEMAIL_DOC_PDF_BCC MS document or PDF attachment, from freemail, all recipients hidden meta FREEMAIL_RVW_ATTCH (__PLS_REVIEW || __DLND_ATTACH) && __FREEMAIL_DOC_PDF describe FREEMAIL_RVW_ATTCH Please review attached document, from freemail endif meta EMPTY_RVW_ATTCH (__PLS_REVIEW || __DLND_ATTACH) && __EMPTY_BODY describe EMPTY_RVW_ATTCH Please review attached document, empty message body __END_FUTURE_EMAILS /\b(?:end|stop(?! receiving these (?:alerts|emails))|cease|discontinue|removed?|(?:do(?! not wish to receive [\w\s]{0,20}emails)|would|you(?:'d)?) (?:not (?:wish|want|like|desire)|(?:prefer|wish|want|like|desire) not) to|exclude yourself|fore?go)[- ](?:get |receiv(?:ing|e) |or |(?:a-z{1,30} ){0,4}from )?(?:these|our|(?:any )?(?:future|further)) (?:(?:e|ad)?-?m(?:ail(?:ing)?|es+[age]{3})|alert|PSA|marketing|notice)[- ]?(?:ad|update)?s?\b/i ifplugin Mail::SpamAssassin::Plugin::DKIM meta END_FUTURE_EMAILS __END_FUTURE_EMAILS && !__SUBJECT_ENCODED_B64 && !__HDRS_LCASE && !__HDRS_LCASE_KNOWN && !__TO___LOWER && !__DKIM_DEPENDABLE && !DKIM_SIGNED else meta END_FUTURE_EMAILS __END_FUTURE_EMAILS && !__SUBJECT_ENCODED_B64 && !__HDRS_LCASE && !__HDRS_LCASE_KNOWN && !__TO___LOWER endif describe END_FUTURE_EMAILS Spammy unsubscribe score END_FUTURE_EMAILS 2.500 # limit body AD_COMPLAINTS /\bcomplaints about this ad+\b/i describe AD_COMPLAINTS Complain about this spam # observed in bank phishing 09/2009 #rawbody MISQ_HTML /<\w{2,20}[^>=]{1,30}=[^"][^">]{1,30}[^=]"[\s>]/ #describe MISQ_HTML Unbalanced quotes in HTML tag #tflags MISQ_HTML nopublish # observed in bank phishing 09/2009 uri WIKI_IMG m,^https?://[^/]+wiki[mp]edia\.org/.+\.(?:png|gif|jpe?g),i describe WIKI_IMG Image from wikipedia # observed in spam 09/2009 header SUBJ_RE_CLNCLN Subject =~ /^\s*RE::/ describe SUBJ_RE_CLNCLN Subject RE:: # observed in spam 02/2011 header TO_SEM_SEM To =~ /;;/ describe TO_SEM_SEM To has ";;" tflags TO_SEM_SEM nopublish uri __MANY_SUBDOM m;^https?://(?:[^\./]{1,30}\.){6};i meta MANY_SUBDOM __MANY_SUBDOM && !__JM_REACTOR_DATE && !__UNSUB_LINK && !__VIA_ML && !NO_RELAYS && !__UPPERCASE_URI && !__MIME_QP describe MANY_SUBDOM Lots and lots of subdomain parts in a URI # by request of Benny Pedersen on the users list 10/9/2009 #meta RFC_ABUSE_POST (__DNS_FROM_RFC_ABUSE && __DNS_FROM_RFC_POST) #describe RFC_ABUSE_POST Both abuse and postmaster missing on sender domain #score RFC_ABUSE_POST 0.01 #tflags RFC_ABUSE_POST net body CALL_SKYPE /\bCall this phone number [\w\s]{0,30}with Skype\b/ # tags shouldn't appear in the midst of text rawbody __SPAN_BEG_TEXT /[a-z]{2}<(?i:span)\s/ tflags __SPAN_BEG_TEXT multiple maxhits=5 rawbody __SPAN_END_TEXT /[^;>]<\/(?i:span)>[a-z]{3}/ tflags __SPAN_END_TEXT multiple maxhits=5 meta __MANY_SPAN_IN_TEXT (__SPAN_BEG_TEXT > 4) && (__SPAN_END_TEXT > 4) meta MANY_SPAN_IN_TEXT __MANY_SPAN_IN_TEXT && !__VIA_ML describe MANY_SPAN_IN_TEXT Many tags embedded within text tflags MANY_SPAN_IN_TEXT publish #score MANY_SPAN_IN_TEXT 2.50 #uri __FEEDPROXY_URI m;http://feedproxy\.google\.com/;i #rawbody __FEEDPROXY m;http://feedproxy\.google\.com/;i #tflags __FEEDPROXY multiple maxhits=5 #meta MANY_GOOG_PROXY __FEEDPROXY > 4 #describe MANY_GOOG_PROXY Many Google feedproxy URIs rawbody TINY_FLOAT /\bstyle\s*=\s*"[^"]{0,40}?(?:(?:FONT-SIZE\s*:\s+\dpx|FLOAT\s*:\s+(?:right|left))(?:;\s+)?(?:(?!(?:FONT-SIZE|FLOAT))\w+:\s+\w+;?\s*)*){2}/i describe TINY_FLOAT Has small-font floating HTML - text obfuscation? #score TINY_FLOAT 2.00 # endless requests on the users list... header __TO_EQ_FROM_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n]{0,80}<)?\1[>,\s\n]/ism header __TO_EQ_FROM_2 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*From:\s+(?:[^\n]{0,80}<)?\1[>,\s\n]/ism meta __TO_EQ_FROM (__TO_EQ_FROM_1 || __TO_EQ_FROM_2) describe __TO_EQ_FROM To: same as From: #tflags __TO_EQ_FROM publish # Suggested by Hans-Werner Friedemann on users list 09/30/2010 header __SUBJ_HAS_FROM_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*Subject:\s+[^\n]{0,100}\1[>,\s\n]/ism meta FROM_IN_TO_AND_SUBJ (__TO_EQ_FROM && __SUBJ_HAS_FROM_1) describe FROM_IN_TO_AND_SUBJ From address is in To and Subject tflags FROM_IN_TO_AND_SUBJ publish header __SUBJ_HAS_TO_1 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s>,]+)>?\n(?:[^\n]{1,200}\n)*Subject:\s+[^\n]{0,100}\1[^a-z0-9]/ism header __SUBJ_HAS_TO_2 ALL =~ /\nReceived:[^\n]{0,200} for ;]+)>?;(?:[^\n]+\n)*Subject:\s+[^\n]{0,100}\1[^a-z0-9]/ism header __SUBJ_HAS_TO_3 ALL =~ /\nSubject:(?=[^\n]{0,200}@)[^\n]{0,200}([a-z][a-z0-9_.]{3,80}@(?:[a-z0-9_]{1,80}\.){1,4}[a-z]{2,30})(?:[^\n]+\n)*To:\s+[^\n]{0,100}\1[^a-z0-9.]/ism meta __TO_IN_SUBJ (__SUBJ_HAS_TO_1 || __SUBJ_HAS_TO_2 || __SUBJ_HAS_TO_3) meta TO_IN_SUBJ __TO_IN_SUBJ && !__VIA_ML && !MISSING_MIMEOLE && !__THREAD_INDEX_GOOD && !__FSL_RELAY_GOOGLE && !__LCL__ENV_AND_HDR_FROM_MATCH && !__HS_SUBJ_RE_FW describe TO_IN_SUBJ To address is in Subject tflags TO_IN_SUBJ publish score TO_IN_SUBJ 0.1 meta __TO_EQ_FM_HTML_ONLY __TO_EQ_FROM && MIME_HTML_ONLY meta TO_EQ_FM_HTML_ONLY __TO_EQ_FM_HTML_ONLY && !ALL_TRUSTED && !__RCD_RDNS_MAIL_MESSY && !__RCD_RDNS_SMTP_MESSY && !__NOT_SPOOFED && !__DKIM_EXISTS && !__ANY_IMAGE_ATTACH && !__FROM_LOWER && !__TAG_EXISTS_CENTER describe TO_EQ_FM_HTML_ONLY To == From and HTML only #tflags TO_EQ_FM_HTML_ONLY publish meta __TO_EQ_FM_DIRECT_MX __TO_EQ_FROM && __DOS_DIRECT_TO_MX meta TO_EQ_FM_DIRECT_MX __TO_EQ_FM_DIRECT_MX && !__THREAD_INDEX_GOOD && !__IS_EXCH describe TO_EQ_FM_DIRECT_MX To == From and direct-to-MX #tflags TO_EQ_FM_DIRECT_MX publish # Why __HUSH_HUSH hits ham on this in masscheck I don't know. Legit bank emails maybe? meta __TO_EQ_FM_HTML_DIRECT __TO_EQ_FM_DIRECT_MX && MIME_HTML_ONLY meta TO_EQ_FM_HTML_DIRECT __TO_EQ_FM_HTML_DIRECT && !__HUSH_HUSH describe TO_EQ_FM_HTML_DIRECT To == From and HTML only, direct-to-MX #tflags TO_EQ_FM_HTML_DIRECT publish ifplugin Mail::SpamAssassin::Plugin::SPF meta __TO_EQ_FM_SPF_FAIL __TO_EQ_FROM && SPF_FAIL tflags __TO_EQ_FM_SPF_FAIL net meta TO_EQ_FM_SPF_FAIL __TO_EQ_FM_SPF_FAIL && !__THREADED && !ALL_TRUSTED describe TO_EQ_FM_SPF_FAIL To == From and external SPF failed tflags TO_EQ_FM_SPF_FAIL net else meta __TO_EQ_FM_SPF_FAIL 0 endif # Paul Stead on SA list 11/2014 # ++ not liked by perl 5.8.x if can(Mail::SpamAssassin::Conf::perl_min_version_5010000) header __PDS_TO_EQ_FROM_NAME_1 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*From:\W+(\1)([^\n\w<]++<)?((?!\1)[^\n">]++)>?\n/ism header __PDS_TO_EQ_FROM_NAME_2 ALL =~ /\nFrom:\W+"([\w+.-]+\@[\w.-]+\.\w\w+)(?:[^\n\w<]{0,80}<)?((?!\1)[^\n">]++)>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n<]{0,80}<)?(\1)>?/ism meta PDS_TO_EQ_FROM_NAME (__PDS_TO_EQ_FROM_NAME_1 || __PDS_TO_EQ_FROM_NAME_2) describe PDS_TO_EQ_FROM_NAME From: name same as To: address header __PDS_FROM_2_EMAILS From =~ /^\W+([\w+.-]+\@[\w.-]+\.\w\w++)(?:[^\n\w<]{0,80})?<(?!\1)[^\n\s]*\@/i meta PDS_FROM_2_EMAILS __PDS_FROM_2_EMAILS && !__VIA_ML && !__VIA_RESIGNER && !__CLICK_HERE && !__BUGGED_IMG && !__RP_MATCHES_RCVD endif uri __PDS_LOC_WP_POMO m;/wp-includes/pomo/(?!(?:entry|po|mo|streams|translations)\.php).*;i header __FROM_ALL_NUMS From:addr =~ /^\d+@/ header __TO_ALL_NUMS To:addr =~ /^\d+@/ meta __FM_TO_ALL_NUMS __FROM_ALL_NUMS && __TO_ALL_NUMS header __TO_EQ_FROM_DOM_1 ALL =~ /\nFrom:\s+[^\n@]{0,80}@([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*To:\s+[^\n]+@\1[>,\s\n]/ism header __TO_EQ_FROM_DOM_2 ALL =~ /\nTo:\s+[^\n@]{0,80}@([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*From:\s+[^\n]+@\1[>,\s\n]/ism meta __TO_EQ_FROM_DOM (__TO_EQ_FROM_DOM_1 || __TO_EQ_FROM_DOM_2) describe __TO_EQ_FROM_DOM To: domain same as From: domain meta __TO_EQ_FM_DOM_HTML_ONLY __TO_EQ_FROM_DOM && MIME_HTML_ONLY meta TO_EQ_FM_DOM_HTML_ONLY __TO_EQ_FM_DOM_HTML_ONLY && !__NOT_SPOOFED && !__CTYPE_MULTIPART_ALT && !HTML_MIME_NO_HTML_TAG && !__IS_EXCH && !__MSGID_BEFORE_RECEIVED && !__FM_TO_ALL_NUMS && !__FROM_LOWER && !__HAS_IN_REPLY_TO && !__BUGGED_IMG && !__FROM_ENCODED_QP && !__MSGID_OK_HEX describe TO_EQ_FM_DOM_HTML_ONLY To domain == From domain and HTML only meta __TO_EQ_FM_DOM_HTML_IMG __TO_EQ_FROM_DOM && __HTML_LINK_IMAGE meta TO_EQ_FM_DOM_HTML_IMG __TO_EQ_FM_DOM_HTML_IMG && !__NOT_SPOOFED && !__CTYPE_MULTIPART_ALT && !__IS_EXCH && !__UNSUB_LINK && !__COMMENT_EXISTS && !__FM_TO_ALL_NUMS && !__DKIM_EXISTS && !__HAS_THREAD_INDEX && !__MSGID_JAVAMAIL && !__RP_MATCHES_RCVD describe TO_EQ_FM_DOM_HTML_IMG To domain == From domain and HTML image link ifplugin Mail::SpamAssassin::Plugin::SPF meta __TO_EQ_FM_DOM_SPF_FAIL __TO_EQ_FROM_DOM && SPF_FAIL tflags __TO_EQ_FM_DOM_SPF_FAIL net meta TO_EQ_FM_DOM_SPF_FAIL __TO_EQ_FM_DOM_SPF_FAIL && !__THREADED && !ALL_TRUSTED describe TO_EQ_FM_DOM_SPF_FAIL To domain == From domain and external SPF failed tflags TO_EQ_FM_DOM_SPF_FAIL net else meta __TO_EQ_FM_DOM_SPF_FAIL 0 endif # Evaluate ReturnPath and blacklist collisions meta __RP_SAFE_BRBL RCVD_IN_RP_SAFE && RCVD_IN_BRBL_LASTEXT meta __RP_CERTIFIED_BRBL RCVD_IN_RP_CERTIFIED && RCVD_IN_BRBL_LASTEXT tflags __RP_SAFE_BRBL net nopublish tflags __RP_CERTIFIED_BRBL net nopublish meta __RP_SAFE_ZEN RCVD_IN_RP_SAFE && __RCVD_IN_ZEN meta __RP_CERTIFIED_ZEN RCVD_IN_RP_CERTIFIED && __RCVD_IN_ZEN tflags __RP_SAFE_ZEN net nopublish tflags __RP_CERTIFIED_ZEN net nopublish meta __RP_SAFE_SORBS RCVD_IN_RP_SAFE && __RCVD_IN_SORBS meta __RP_CERTIFIED_SORBS RCVD_IN_RP_CERTIFIED && __RCVD_IN_SORBS tflags __RP_SAFE_SORBS net nopublish tflags __RP_CERTIFIED_SORBS net nopublish meta __RP_SAFE_XBL RCVD_IN_RP_SAFE && RCVD_IN_XBL meta __RP_CERTIFIED_XBL RCVD_IN_RP_CERTIFIED && RCVD_IN_XBL tflags __RP_SAFE_XBL net nopublish tflags __RP_CERTIFIED_XBL net nopublish meta __RP_SAFE_PSBL RCVD_IN_RP_SAFE && RCVD_IN_PSBL meta __RP_CERTIFIED_PSBL RCVD_IN_RP_CERTIFIED && RCVD_IN_PSBL tflags __RP_SAFE_PSBL net nopublish tflags __RP_CERTIFIED_PSBL net nopublish #meta __RP_SAFE_ANBREP_L3 RCVD_IN_RP_SAFE && RCVD_IN_ANBREP_L3 #meta __RP_CERTIFIED_ANBREP_L3 RCVD_IN_RP_CERTIFIED && RCVD_IN_ANBREP_L3 #tflags __RP_SAFE_ANBREP_L3 net nopublish #tflags __RP_CERTIFIED_ANBREP_L3 net nopublish # a URI in the From comment text, to bypass URIBL checks # simplistic URI format for now header __FROM_URI_1 From =~ /[^\@]www[.\s][^\s"<\@]+[.\s](?:com|net|info|biz|org|\w\w)\b.*["<]/i header __FROM_URI_2 From =~ m;http://(?:[^.\s]+\.){1,3}(?:com|net|info|biz|org|\w\w)\b;i meta FROM_URI __FROM_URI_1 || __FROM_URI_2 describe FROM_URI URI or www. in From # observed in spam feb 2010 # Apparently-To per RFC2821 SHOULD NOT be used header __APPARENTLY_TO Apparently-To =~ /<.*>/ tflags __APPARENTLY_TO multiple maxhits=21 nopublish meta HAS_APPARENTLY_TO __APPARENTLY_TO > 0 describe HAS_APPARENTLY_TO Has deprecated Apparently-To header #score HAS_APPARENTLY_TO 0.50 tflags HAS_APPARENTLY_TO nopublish meta MANY_APPARENTLY_TO __APPARENTLY_TO > 20 describe MANY_APPARENTLY_TO Has many Apparently-To headers #score MANY_APPARENTLY_TO 2.00 tflags MANY_APPARENTLY_TO nopublish # obfuscation of "opt out" ifplugin Mail::SpamAssassin::Plugin::ReplaceTags body FUZZY_OPTOUT /\b(?!opt.?out)

.?\b/i replace_rules FUZZY_OPTOUT describe FUZZY_OPTOUT Obfuscated opt-out text endif # stock spam disclaimer obfuscation # body GAPPY_TRADING /\b(?!trading)t[^a-z\s]?r[^a-z\s]?a[^a-z\s]?d[^a-z\s]?i[^a-z\s]?n[^a-z\s]?g/i # body GAPPY_SECURITIES /\b(?!securities)s[^a-z\s]?e[^a-z\s]?c[^a-z\s]?u[^a-z\s]?r[^a-z\s]?i[^a-z\s]?t[^a-z\s]?i[^a-z\s]?e[^a-z\s]?s/i # body GAPPY_RISK /\b(?!risky?)r[^a-z\s]?i[^a-z\s]?s[^a-z\s]?k(?:[^a-z\s]?y)?/i # body GAPPY_SELLING /\b(?!selling)s[^a-z\s]?e[^a-z\s]?l[^a-z\s]?l[^a-z\s]?i[^a-z\s]?n[^a-z\s]?g/i # body GAPPY_HUNDRED /\b(?!hundred)h[^a-z\s]?u[^a-z\s]?n[^a-z\s]?d[^a-z\s]?r[^a-z\s]?e[^a-z\s]?d/i # body GAPPY_THOUSAND /\b(?!thousand)t[^a-z\s]?h[^a-z\s]?o[^a-z\s]?u[^a-z\s]?s[^a-z\s]?a[^a-z\s]?n[^a-z\s]?d/i # body GAPPY_EXPENSES /\b(?!expenses)e[^a-z\s]?x[^a-z\s]?p[^a-z\s]?e[^a-z\s]?n[^a-z\s]?s[^a-z\s]?e[^a-z\s]?s/i # body GAPPY_DOLLARS /\b(?!dollars)d[^a-z\s]?o[^a-z\s]?l[^a-z\s]?l[^a-z\s]?a[^a-z\s]?r[^a-z\s]?s/i # # describe GAPPY_TRADING Possible obfuscated stock disclaimer # describe GAPPY_SECURITIES Possible obfuscated stock disclaimer # describe GAPPY_RISK Possible obfuscated stock disclaimer # describe GAPPY_SELLING Possible obfuscated stock disclaimer # describe GAPPY_HUNDRED Possible obfuscated stock disclaimer # describe GAPPY_THOUSAND Possible obfuscated stock disclaimer # describe GAPPY_EXPENSES Possible obfuscated stock disclaimer # describe GAPPY_DOLLARS Possible obfuscated stock disclaimer body GAPPY_GENITALIA /\bp(?!enis)(?!en is)[^a-z]?e[^a-z]?n[^a-z]?i[^a-z]?s(?:\b|_)/i describe GAPPY_GENITALIA G.a.p.p.y male body parts body GAPPY_PILLS /\bp(?!ills)[^a-z]?i[^a-z]?l[^a-z]?l[^a-z]?s(?:\b|_)/i describe GAPPY_PILLS G.a.p.p.y pills body __STYLE_TAG_IN_BODY /]{0,30})?>/i body __BODY_XHTML //i if can(Mail::SpamAssassin::Conf::perl_min_version_5010000) # possessive {0,4}+ requires perl 5.10 or better rawbody __STYLE_GIBBERISH_1 /]{0,40})?>(?:\s{0,100}(?!<\/style>)(?:(?:\/\*(?:\s|[^*<]|\*(?!\/)|<(?!\/style>)){0,200}\*\/)|\#[^{<]{1,50}\{[^}<]{4,100}\})){0,4}+(?:\s{0,100}(?!<\/style>|\/\*)[^\s:;,]){150}/im else # older perl, can't deal with style comments properly rawbody __STYLE_GIBBERISH_1 /]{0,40})?>(?:\s{0,100}(?!<\/style>|\/\*)[^\s:;,]){150}/im endif rawbody __STYLE_GIBBERISH_2 /\.style\w{0,20}\s{1,10}\{[^:;]{200}/im rawbody __STYLE_GIBBERISH_3 /]{0,40})?>\s{0,80}(?:[\w:]{1,30}\s{0,10}\{[^}]{1,50}\}\s{0,80}){1,5}(?:[\w,.']{1,30}\s{1,10}){40}/im meta __STYLE_GIBBERISH (__STYLE_GIBBERISH_1 || __STYLE_GIBBERISH_2 || __STYLE_GIBBERISH_3) meta STYLE_GIBBERISH __STYLE_GIBBERISH && (__BODY_XHTML || !__STYLE_TAG_IN_BODY) && !__RCD_RDNS_MX_MESSY && !__HAS_THREAD_INDEX && !__ANY_OUTLOOK_MUA && !__MIME_QP && !ALL_TRUSTED describe STYLE_GIBBERISH Nonsense in HTML