# Composites setup
# Please don't modify this file as your changes might be overwritten with
# the next update.
#
# You can modify 'local.d/composites.conf' to add and merge
# parameters defined inside this section
#
# You can modify 'override.d/composites.conf' to strictly override all
# parameters defined inside this section
#
# See https://rspamd.com/doc/faq.html#what-are-the-locald-and-overrided-directories
# for details
#
# See https://rspamd.com/doc/tutorials/writing_rules.html and
# https://rspamd.com/doc/configuration/composites.html for details

composites {

  FORGED_RECIPIENTS_MAILLIST {
    expression = "FORGED_RECIPIENTS & -MAILLIST";
  }
  FORGED_SENDER_MAILLIST {
    expression = "FORGED_SENDER & -MAILLIST";
  }
  FORGED_SENDER_FORWARDING {
    expression = "FORGED_SENDER & g:forwarding";
    description = "Forged sender, but message is forwarded";
    policy = "remove_weight";
  }
  SPF_FAIL_FORWARDING {
    expression = "g:forwarding & (R_SPF_SOFTFAIL | R_SPF_FAIL)";
    policy = "remove_weight";
  }
  DMARC_POLICY_ALLOW_WITH_FAILURES {
    expression = "DMARC_POLICY_ALLOW & (R_SPF_SOFTFAIL | R_SPF_FAIL | R_DKIM_REJECT)";
    policy = "remove_weight";
  }
  FORGED_RECIPIENTS_FORWARDING {
    expression = "FORGED_RECIPIENTS & g:forwarding";
    policy = "remove_weight";
  }
  FORGED_SENDER_VERP_SRS {
    expression = "FORGED_SENDER & (ENVFROM_PRVS | ENVFROM_VERP)";
  }
  FORGED_MUA_MAILLIST {
    expression = "g:mua & -MAILLIST";
  }
  RBL_SPAMHAUS_XBL_ANY {
    expression = "RBL_SPAMHAUS_XBL & RECEIVED_SPAMHAUS_XBL";
    description = "From and Received address are listed in Spamhaus XBL";
  }
  AUTH_NA {
    expression = "R_DKIM_NA & R_SPF_NA & DMARC_NA & ARC_NA";
    score = 1.0;
    policy = "remove_weight";
    description = "Authenticating message via SPF/DKIM/DMARC/ARC not possible";
  }
  DKIM_MIXED {
    expression = "-R_DKIM_ALLOW & (R_DKIM_DNSFAIL | R_DKIM_PERMFAIL | R_DKIM_REJECT)"
    policy = "remove_weight";
  }
  MAIL_RU_MAILER_BASE64 {
    expression = "MAIL_RU_MAILER & (FROM_EXCESS_BASE64 | MIME_BASE64_TEXT | REPLYTO_EXCESS_BASE64 | SUBJ_EXCESS_BASE64 | TO_EXCESS_BASE64)";
  }
  YANDEX_RU_MAILER_CTYPE_MIXED_BOGUS {
    expression = "YANDEX_RU_MAILER & -HAS_ATTACHMENT & CTYPE_MIXED_BOGUS";
  }
  MAILER_1C_8_BASE64 {
    expression = "MAILER_1C_8 & (FROM_EXCESS_BASE64 | MIME_BASE64_TEXT | SUBJ_EXCESS_BASE64 | TO_EXCESS_BASE64)";
    description = "Message was sent by '1C:Enterprise 8' and uses base64 encoded data";
  }
  HACKED_WP_PHISHING {
    expression = "(HAS_X_POS | HAS_PHPMAILER_SIG) & HAS_WP_URI & (PHISHING | DBL_PHISH | PHISHED_OPENPHISH | PHISHED_PHISHTANK)";
    description = "Phish message sent by hacked Wordpress instance";
    policy = "leave";
  }
  COMPROMISED_ACCT_BULK {
    expression = "(HAS_XOIP | RCVD_FROM_SMTP_AUTH) & DCC_BULK";
    description = "Likely to be from a compromised account";
    score = 3.0;
    policy = "leave";
  }
  UNDISC_RCPTS_BULK {
    expression = "DCC_BULK & (MISSING_TO | R_UNDISC_RCPT)";
    description = "Missing or undisclosed recipients with a bulk signature";
    score = 3.0;
    policy = "leave";
  }
  RCVD_UNAUTH_PBL {
    expression = "RECEIVED_PBL & !RCVD_VIA_SMTP_AUTH";
    description = "Relayed through ZEN PBL IP without sufficient authentication (possible indicating an open relay)";
    score = 2.0;
    policy = "leave";
  }
  RCVD_DKIM_ARC_DNSWL_MED {
    expression = "(R_DKIM_ALLOW | ARC_ALLOW) & RCVD_IN_DNSWL_MED";
    description = "Sufficiently DKIM/ARC signed and received from IP with medium trust at DNSWL";
    score = -0.5;
    policy = "leave";
  }
  RCVD_DKIM_ARC_DNSWL_HI {
    expression = "(R_DKIM_ALLOW | ARC_ALLOW) & RCVD_IN_DNSWL_HI";
    description = "Sufficiently DKIM/ARC signed and received from IP with high trust at DNSWL";
    score = -1.0;
    policy = "leave";
  }
  AUTOGEN_PHP_SPAMMY {
    expression = "(HAS_X_POS | HAS_PHPMAILER_SIG | HAS_X_PHP_SCRIPT) & (SUBJECT_ENDS_QUESTION | SUBJECT_ENDS_EXCLAIM | MANY_INVISIBLE_PARTS)";
    description = "Message was generated by PHP script and contains some spam indicators";
    score = 1.0;
    policy = "leave";
  }
  PHISH_EMOTION {
    expression = "(PHISHING | DBL_PHISH | PHISHED_OPENPHISH | PHISHED_PHISHTANK) & (SUBJECT_ENDS_QUESTION | SUBJECT_ENDS_EXCLAIM)";
    description = "Phish message with subject trying to address users emotion";
    score = 1.0;
    policy = "leave";
  }
  HAS_ANON_DOMAIN {
    expression = "HAS_GUC_PROXY_URI | URIBL_RED | DBL_ABUSE_REDIR | HAS_ONION_URI";
    description = "Contains one or more domains trying to disguise owner/destination";
    score = 0.1;
    policy = "leave";
  }
  BAD_REP_POLICIES {
    description = "Contains valid policies but are also marked by fuzzy/bayes/surbl/rbl";
    expression = "(~g-:policies) & (-g+:fuzzy | -g+:bayes | -g+:surbl | -g+:rbl)";
    score = 0.1;
  }

  VIOLATED_DIRECT_SPF {
    description = "Has no Received (or no trusted received relays) and SPF policy fails or soft fails";
    expression = "(R_SPF_FAIL | R_SPF_SOFTFAIL) & (RCVD_COUNT_ZERO | RCVD_NO_TLS_LAST)";
    policy = "leave";
    score = 3.5;
  }

  IP_SCORE_FREEMAIL {
    description = "Negate IP_SCORE when message comes from FreeMail";
    expression = "FREEMAIL_FROM & SENDER_REP_SPAM";
    score = 0.0;
    policy = "remove_weight";
  }
  BROKEN_HEADERS_MAILLIST {
    description = "Negate BROKEN_HEADERS when message comes via some mailing list";
    expression = "BROKEN_HEADERS & -MAILLIST";
    score = 0.0;
    policy = "remove_weight";
  }
  LEAKED_PASSWORD_SCAM {
    description = "Contains BTC wallet address and scam patterns";
    expression = "BITCOIN_ADDR & (LEAKED_PASSWORD_SCAM_RE | R_MIXED_CHARSET | R_EMPTY_IMAGE)";
    policy = "leave";
    score = 7.0;
    group = "scams";
  }

  .include(try=true; priority=1; duplicate=merge) "$LOCAL_CONFDIR/local.d/composites.conf"
  .include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/composites.conf"
}
