1+ name : " PR# 4380 - 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+ // Single thread with unsubscribe link or $org_domains link
70+ or (
71+ length(body.links) <= 3
72+ and (
73+ // unsubscribe mailto link
74+ regex.icontains(body.html.raw, "mailto:*[++unsubscribe@]")
75+ // or link to found in org_domains
76+ or any(body.links, .href_url.domain.root_domain in~ $org_domains)
77+ )
78+ and length(body.previous_threads) == 0
79+ // short message between 20 and 500 chars
80+ and 20 < length(body.current_thread.text) < 500
81+ // service offering keywords
82+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
83+ "(?:screenshot|error list|plan|quote|rank|professional|price|mistake)"
84+ )
85+ // generic greeting
86+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
87+ '(?:h(?:i|ello|ey)|morning)\b'
88+ )
89+ // problem or urgency keywords
90+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
91+ '(?:error|report|issues|website|repair|redesign|upgrade|Google\s+.{0,15}find it)'
92+ )
93+ // website or page mention
94+ and regex.icontains(strings.replace_confusables(body.current_thread.text),
95+ "(?:site|website|page)"
96+ )
97+ )
98+ // Multiple thread messages
99+ or (
100+ length(body.links) == 0
101+ // small thread with less than 5 messages
102+ and length(body.previous_threads) < 5
103+ // check previous messages for spam characteristics
104+ and any(body.previous_threads,
105+ // short previous messages less than 400 chars
106+ length(.text) < 400
107+ and (
108+ // generic greeting
109+ regex.icontains(strings.replace_confusables(.text),
110+ '(?:h(?:i|ello|ey)|morning)\b'
111+ )
112+ // service offering keywords
113+ and regex.icontains(strings.replace_confusables(.text),
114+ '(?:\berror(?:\s+list)?\b|screenshot|report|plan)'
115+ )
116+ // previous threads written in English
117+ and ml.nlu_classifier(.text).language == "english"
118+ )
119+ )
120+ )
121+ )
122+ tags :
123+ - " Attack surface reduction"
124+ - pr_author_cybher0808
125+ - created_from_open_prs
126+ - rule_status_renamed
127+ attack_types :
128+ - " Spam"
129+ detection_methods :
130+ - " Content analysis"
131+ - " Sender analysis"
132+ - " Natural Language Understanding"
133+ id : " 5c1bac1a-407f-5ac9-81ed-800b666a7447"
134+ references :
135+ - https://github.com/sublime-security/sublime-rules/pull/4380
0 commit comments