1+ name : " PR# 4379 - Spam: Website errors solicitation"
2+ description : " This rule detects messages claiming to have identified errors on a website. The messages typically offer to send pricing or information upon request."
3+ type : " rule"
4+ severity : " low"
5+ source : |
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+ "(?:available|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+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
65+ '(mail\.|mx|\.u)?\.?@?(aol|yahoo|hotmail|google|gmail|googlemail)\.com'
66+ )
67+ )
68+ or any(body.links, regex.icontains(.display_text, '\.?@?(hotmail)\.com'))
69+ )
70+
71+ // Single thread with unsubscribe link or $org_domains link
72+ or (
73+ length(body.links) <= 3
74+ and (
75+ // unsubscribe mailto link
76+ regex.icontains(body.html.raw, "mailto:*[++unsubscribe@]")
77+ // or link to found in org_domains
78+ or any(body.links, .href_url.domain.root_domain in~ $org_domains)
79+ )
80+ and length(body.previous_threads) == 0
81+ // short message between 20 and 500 chars
82+ and 20 < length(body.current_thread.text) < 500
83+ // service offering keywords
84+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
85+ "(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
86+ )
87+ // generic greeting
88+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
89+ '(?:h(?:i|ello|ey)|morning)\b'
90+ )
91+ // problem or urgency keywords
92+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
93+ '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
94+ )
95+ // website or page mention
96+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
97+ "(?:site|website|page)"
98+ )
99+ )
100+ // Multiple thread messages
101+ or (
102+ length(body.links) == 0
103+ // small thread with less than 5 messages
104+ and length(body.previous_threads) < 5
105+ // check previous messages for spam characteristics
106+ and any(body.previous_threads,
107+ // short previous messages less than 400 chars
108+ length(.text) < 400
109+ and (
110+ // generic greeting
111+ regex.icontains(strings.replace_confusables(.text),
112+ '(?:h(?:i|ello|ey)|morning)\b'
113+ )
114+ // service offering keywords
115+ and regex.icontains(strings.replace_confusables(.text),
116+ '(?:\berror(?:\s+list)?\b|screenshot|report|plan)'
117+ )
118+ // previous threads written in English
119+ and ml.nlu_classifier(.text).language == "english"
120+ )
121+ )
122+ )
123+ tags :
124+ - " Attack surface reduction"
125+ - pr_author_cybher0808
126+ - created_from_open_prs
127+ - rule_status_modified
128+ attack_types :
129+ - " Spam"
130+ detection_methods :
131+ - " Content analysis"
132+ - " Sender analysis"
133+ - " Natural Language Understanding"
134+ id : " 033af5ca-2d78-546d-806b-7aad14e8860d"
135+ references :
136+ - https://github.com/sublime-security/sublime-rules/pull/4379
0 commit comments