Archive for May, 2008

Mail.app rules [and no AppleScript]: Blocking spam by SpamAssassin’s X-Spam-Bar header

Sunday, May 11th, 2008

As I was writing my previous post about using Apple Mail’s rules and AppleScript to block spammy email messages, I realized there was a much easier way to do it, without using AppleScript. When I was going through the headers added by SpamAssassin, I noticed that the X-Spam-Bar header’s length represented the spaminess score. So instead of using AppleScript to parse the X-Spam-Score header as a number, I could just use rule conditions to weed out particularly spammy emails.

The following rule definition does almost exactly the same thing as the AppleScript in the previous post:

If [all] of the following conditions are met:
    [Subject] [Begins with] [***SPAM***]
    [X-Spam-Bar] [Begins with] [+++++++++]
Perform the following actions:
    [Delete Message]
    [Mark as Read]
    [Stop evaluating rules]

Two things might be of note here:

  • The ***SPAM*** tag in the message’s subject is added by our SpamAssassin setup automatically. We don’t actually need it to make this rule work, but I figure it probably cuts down on some processing time.
  • The X-Spam-Bar header is not initially a choice in the rule adding/editing dialog. You have to add it to the list by choosing the [Edit Header List] option from the bottom of the [Subject] select menu.

This rule takes advantage of the X-Spam-Bar header, which, if the spam score is 9.0 or greater, will contain at least 9 ‘+’ symbols, and will thus be deleted.

The one thing it doesn’t do is mark the message as spam, which helps teach Mail’s spam analysis engine. If anyone knows how to do that with Mail’s rules, please leave me a comment and let me know!

Mail.app rules and AppleScript: Blocking spam by SpamAssassin’s X-Spam-Score header

Sunday, May 11th, 2008

At work, our mail server uses SpamAssassin to block undesired messages. We’ve got the spam threshold currently set at 6, meaning that any message with a “spaminess” score of 6.0 or more is determined to officially be spam. But since we don’t want to miss a customer’s email coming from a recently blacklisted domain, we don’t have SpamAssassin automatically delete the spammy messages, rather it just tags their subjects and delivers them to their recipients.

SpamAssassin also adds a few headers into each email it passes on. An example of each header is included after it’s description.

  • X-Spam-Status: A line indicating whether the message is spam or not, and it’s spaminess score. [Yes, score=19.2]
  • X-Spam-Score: The message’s spaminess score, multiplied by 10. [192]
  • X-Spam-Bar: A series of ‘+’ symbols, each one representing 1 spaminess point. [+++++++++++++++++++]
  • X-Spam-Report: The full spaminess detection process report of the message. [Example too long to include.]
  • X-Spam-Flag: A simple yes/no saying whether the message is spam. [YES]

Since all the spam got through, I wanted to at least delete the emails which were definitely spam. Since a spam threshold of 6 was doing almost a perfect job of keeping the real emails clean and marking the spam emails as such, I decided that a spaminess score of 9 or more would indicate that an email was definitely spam, and could without consequence be deleted.

Everybody at work uses Apple’s Mail program for their emailing, so I wrote an AppleScript to be triggered from a rule that will delete any email with an X-Spam-Score header value of 90 or more. The AppleScript is shown here:

on perform_mail_action(theData)
  tell application "Mail"
    try
      set theMessages to |SelectedMessages| of theData
      set theRule to |Rule| of theData

      repeat with theMessage in theMessages
        set theHeader to the header "X-Spam-Score" of theMessage
        set theSpamScore to the content of theHeader as integer
        if theSpamScore ≥ 90 then

          -- Make sure the message is marked as junk
          if the junk mail status of theMessage is false then
            set junk mail status of theMessage to true
          end if

          -- Don't let the message show up as unread
          set the read status of theMessage to true

          -- Delete the message
          delete theMessage

          -- No need to check this message against anything else
          if stop evaluating rules of theRule is false then
            set stop evaluating rules of theRule to true
          end if
        end if
      end repeat
    end try
  end tell
end perform_mail_action

And to attach this script to a rule in Mail, we used this
definition:

If [any] of the following conditions are net:
    [Subject] [Begins with] [***SPAM***]
Perform the following actions:
    [Run AppleScript] [/path/to/my/script.scpt]
    [Stop evaluating rules]

One thing which might be of note is that SpamAssassin automatically prepends the ***SPAM*** string to the subject line of every email it believes is spam.