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)"
 16      )
 17      // report and follow up keywords
 18      or (
 19        strings.icontains(strings.replace_confusables(subject.subject), "report")
 20        and regex.icontains(strings.replace_confusables(body.current_thread.text),
 21                            "(?:free|send you|can i send|may i send|let me know|interested|get back to me|reply back|just reply)"
 22        )
 23      )
 24      // short subject
 25      or length(subject.base) < 5
 26    )
 27    // or a reply or forward in a thread that mentions website or screenshots
 28    or (
 29      (length(subject.base) < 5 or subject.is_reply or subject.is_forward)
 30      and any(body.previous_threads,
 31              regex.icontains(strings.replace_confusables(.text),
 32                              "(?:screenshot|website)"
 33              )
 34      )
 35    )
 36  )
 37  // body structure and content patterns
 38  and (
 39    // Single thread with no links
 40    (
 41      length(body.links) == 0
 42      and length(body.previous_threads) == 0
 43      // short message between 20 and 500 chars
 44      and 20 < length(body.current_thread.text) < 500
 45      // service offering keywords
 46      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 47                          "(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
 48      )
 49      // generic greeting
 50      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 51                          'h(?:i|ello|ey)\b'
 52      )
 53      // problem or urgency keywords
 54      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 55                          '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
 56      )
 57      // website or page mention
 58      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 59                          "(?:site|website|page)"
 60      )
 61    )
 62    // Single thread with only unsubscribe link
 63    or (
 64      length(body.links) == 1
 65      and (
 66        // unsubscribe mailto link
 67        regex.icontains(body.html.raw, "mailto:*[++unsubscribe@]")
 68        // or link to found in org_domains
 69        or any(body.links, .href_url.domain.root_domain in~ $org_domains)
 70      )
 71      and length(body.previous_threads) == 0
 72      // short message between 20 and 500 chars
 73      and 20 < length(body.current_thread.text) < 500
 74      // service offering keywords
 75      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 76                          "(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
 77      )
 78      // generic greeting
 79      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 80                          '(?:h(?:i|ello|ey)|morning)\b'
 81      )
 82      // problem or urgency keywords
 83      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 84                          '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
 85      )
 86      // website or page mention
 87      and regex.icontains(strings.replace_confusables(body.current_thread.text),
 88                          "(?:site|website|page)"
 89      )
 90    )
 91    // Multiple thread messages
 92    or (
 93      length(body.links) == 0
 94      // small thread with less than 5 messages
 95      and length(body.previous_threads) < 5
 96      // check previous messages for spam characteristics
 97      and any(body.previous_threads,
 98              // short previous messages less than 400 chars
 99              length(.text) < 400
100              and (
101                // generic greeting
102                regex.icontains(strings.replace_confusables(.text),
103                                '(?:h(?:i|ello|ey)|morning)\b'
104                )
105                // service offering keywords
106                and regex.icontains(strings.replace_confusables(.text),
107                                    '(?:\berror(?:\s+list)?\b|screenshot|report|plan)'
108                )
109                // previous threads written in English
110                and ml.nlu_classifier(.text).language == "english"
111              )
112      )
113    )
114  )  
115
116tags:
117  - "Attack surface reduction"
118attack_types:
119  - "Spam"
120detection_methods:
121  - "Content analysis"
122  - "Sender analysis"
123  - "Natural Language Understanding"
124id: "122ea794-f619-5f29-acb2-83261d8f81fc"

Related rules

to-top