Spam: Website errors solicitation

This rule detects messages claiming to have identified errors on a website. The messages typically offer to send pricing or information upon request.

Sublime rule (View on GitHub)

  1name: "Spam: Website errors solicitation"
  2description: "This rule detects messages claiming to have identified errors on a website. The messages typically offer to send pricing or information upon request."
  3type: "rule"
  4severity: "low"
  5source: |
  6  type.inbound
  7  and not profile.by_sender().solicited
  8  // no attachments
  9  and length(attachments) == 0
 10  // subject must contain SEO or web dev spam keywords or be short
 11  and (
 12    (
 13      // SEO or web development service keywords
 14      regex.icontains(strings.replace_confusables(subject.subject),
 15                      '(?:proposal|cost|estimate|error|bug|audit|screenshot|strategy|rankings|issues|fix|website|design|review|price)'
 16      )
 17      or regex.icontains(subject.base,
 18                         '[^\x{2600}-\x{27BF}\x{1F300}-\x{1F9FF}][\x{2600}-\x{27BF}\x{1F300}-\x{1F9FF}]\x{FE0F}?$'
 19      )
 20      // report and follow up keywords
 21      or (
 22        strings.icontains(strings.replace_confusables(subject.subject), "report")
 23        and regex.icontains(strings.replace_confusables(body.current_thread.text),
 24                            "(?:free|send you|can i send|may i send|let me know|interested|get back to me|reply back|just reply)"
 25        )
 26      )
 27      // short subject
 28      or length(subject.base) < 5
 29    )
 30    // or a reply or forward in a thread that mentions website or screenshots
 31    or (
 32      (length(subject.base) < 5 or subject.is_reply or subject.is_forward)
 33      and any(body.previous_threads,
 34              regex.icontains(strings.replace_confusables(.text),
 35                              "(?:screenshot|website)"
 36              )
 37      )
 38    )
 39  )
 40  // body structure and content patterns
 41  and (
 42    // Single thread with no links
 43    (
 44      length(body.links) == 0
 45      and length(body.previous_threads) == 0
 46      // short message between 20 and 500 chars
 47      and 20 < length(body.current_thread.text) < 500
 48      // service offering keywords
 49      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 50                          "(?:screenshot|error list|plan|quote|rank|professional|price|mistake|visibility|improvement|review|emailed.{0,10}more details)"
 51      )
 52      // generic greeting
 53      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 54                          'h(?:i|ello|ey)\b'
 55      )
 56      // problem or urgency keywords
 57      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 58                          '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it|glitch)'
 59      )
 60      // website or page mention
 61      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 62                          "(?:site|website|page)"
 63      )
 64    )
 65    // Single thread with unsubscribe link or $org_domains link
 66    or (
 67      length(body.links) <= 3
 68      and (
 69        // unsubscribe mailto link
 70        regex.icontains(body.html.raw, "mailto:*[++unsubscribe@]")
 71        // or link to found in org_domains
 72        or any(body.links, .href_url.domain.root_domain in~ $org_domains)
 73      )
 74      and length(body.previous_threads) == 0
 75      // short message between 20 and 500 chars
 76      and 20 < length(body.current_thread.text) < 500
 77      // service offering keywords
 78      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 79                          "(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
 80      )
 81      // generic greeting
 82      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 83                          '(?:h(?:i|ello|ey)|morning)\b'
 84      )
 85      // problem or urgency keywords
 86      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 87                          '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
 88      )
 89      // website or page mention
 90      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 91                          "(?:site|website|page)"
 92      )
 93    )
 94    // Multiple thread messages
 95    or (
 96      length(body.links) == 0
 97      // small thread with less than 5 messages
 98      and length(body.previous_threads) < 5
 99      // check previous messages for spam characteristics
100      and any(body.previous_threads,
101              // short previous messages less than 400 chars
102              length(.text) < 400
103              and (
104                // generic greeting
105                regex.icontains(strings.replace_confusables(.text),
106                                '(?:h(?:i|ello|ey)|morning)\b'
107                )
108                // service offering keywords
109                and regex.icontains(strings.replace_confusables(.text),
110                                    '(?:\berror(?:\s+list)?\b|screenshot|report|plan)'
111                )
112                // previous threads written in English
113                and ml.nlu_classifier(.text).language == "english"
114              )
115      )
116    )
117  )  
118
119tags:
120  - "Attack surface reduction"
121attack_types:
122  - "Spam"
123detection_methods:
124  - "Content analysis"
125  - "Sender analysis"
126  - "Natural Language Understanding"
127id: "122ea794-f619-5f29-acb2-83261d8f81fc"

Related rules

to-top