Skip to content

Added new rule for detecting rating solicitation scams#4492

Open
jacob-mazurkiewicz wants to merge 11 commits into
sublime-security:mainfrom
jacob-mazurkiewicz:Feauture/Scam-Employer-Review-Solicitation
Open

Added new rule for detecting rating solicitation scams#4492
jacob-mazurkiewicz wants to merge 11 commits into
sublime-security:mainfrom
jacob-mazurkiewicz:Feauture/Scam-Employer-Review-Solicitation

Conversation

@jacob-mazurkiewicz
Copy link
Copy Markdown

@jacob-mazurkiewicz jacob-mazurkiewicz commented May 15, 2026

Description

This new rule targets attempts for solicitation of ratings/reviews of employers. These false solicitations can contain malicious links or be attempts at phishing information or credentials from the receiver.

Associated samples

Example one:

Date: Thu, 15 May 2026 14:02:33 -0400
Subject: You've Been Selected - Rate Your Employer & Earn $500!
From: John Glennson <John@gl4ssdoor-reviews.com>
To: Jacob.Mazurkiewicz2@dcsg.com

Dear Valued Professional,

Congratulations! You have been specially selected to particpiate in our Annual Employer Review Program.

We are partnering with top companies to collect honest workplace feedback. As a token of our appreciation, you will receive a $500 gift card simply for completing a short review of your employer.

To claim your reward, please review your experience at your current workplace by clicking the link below:

https://gl4ssdoor-reviews.com/rate-employer?ref=29571

All you need to do is:
1. Rate your employer on a scale of 1-5
2. Share your review of your workplace experience
3. Verify your identity by entering your company email and password

Your feedback helps other job seekers make informed decisions. Leave a review today and your $500 gift card will be sent within 24 hours.

This offer expires in 48 hours so act now! Write a review before time runs out.

Important: To verify your eligibility and process your reward, we will need you to confirm your login credentials on the next page.

Thank you for helping us improve workplace transparency!

Best regards,
John Glennson
Glassdoor Ratings Department

Screenshot (insights)

Rule flagged example one
image

Rule flagged example two
image

@github-actions github-actions Bot added the review-needed Indicates that a PR is waiting for review label May 15, 2026
@jacob-mazurkiewicz jacob-mazurkiewicz marked this pull request as ready for review May 15, 2026 11:46
@jacob-mazurkiewicz jacob-mazurkiewicz requested a review from a team May 15, 2026 11:46
@jacob-mazurkiewicz jacob-mazurkiewicz requested a review from a team as a code owner May 15, 2026 11:46
@github-actions
Copy link
Copy Markdown
Contributor

Test Rules Sync - Action Required

This PR was not automatically synced to test-rules because the author is not a member of the sublime-security organization.

To enable syncing, an organization member can comment /update-test-rules on this PR.

Once triggered, the rules will be synced on the next scheduled run (every 10 minutes).

Copy link
Copy Markdown
Member

@IndiaAce IndiaAce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Jacob thanks for your contribution!

I think this is a clever idea to provide coverage for these scams. Early telemetry looks okay, however I have a few suggestions (left below). Also, I'm curious to hear your thoughts on reinforcing the "scam" nature of these two examples you provided. I see some arrant false positives on some document sharing messages that are requests to view documents/proposals and leave feedback. They are no doubt malicious, but outside of the scope of this rule. I'm curious to see what the nlu classifier gives as a .topic for both of your samples? Perhaps the "giveaway" angle is something worth pursuing?

Keeping your .intent use for both current and previous threads, but adding another "and" stanza with something like
and any(ml.nlu_classifier(body.current_thread.text).topics, .name == "Advertising and Promotions" )

I also see some patterns (with some samples I found as well) where each of these seem to provide "instructions" to the user, notice your two samples contain that set of 4 instructions. That might be an angle worth pursuing.

Let me know your thoughts!

Comment thread detection-rules/scam_employer_review_solicitation.yml Outdated
Comment thread detection-rules/scam_employer_review_solicitation.yml Outdated
Comment thread detection-rules/scam_employer_review_solicitation.yml Outdated
jacob-mazurkiewicz and others added 7 commits May 22, 2026 11:59
Co-authored-by: Luke Wescott <69780712+IndiaAce@users.noreply.github.com>
Co-authored-by: Luke Wescott <69780712+IndiaAce@users.noreply.github.com>
Co-authored-by: Luke Wescott <69780712+IndiaAce@users.noreply.github.com>
@jacob-mazurkiewicz
Copy link
Copy Markdown
Author

Hey Jacob thanks for your contribution!

I think this is a clever idea to provide coverage for these scams. Early telemetry looks okay, however I have a few suggestions (left below). Also, I'm curious to hear your thoughts on reinforcing the "scam" nature of these two examples you provided. I see some arrant false positives on some document sharing messages that are requests to view documents/proposals and leave feedback. They are no doubt malicious, but outside of the scope of this rule. I'm curious to see what the nlu classifier gives as a .topic for both of your samples? Perhaps the "giveaway" angle is something worth pursuing?

Keeping your .intent use for both current and previous threads, but adding another "and" stanza with something like and any(ml.nlu_classifier(body.current_thread.text).topics, .name == "Advertising and Promotions" )

I also see some patterns (with some samples I found as well) where each of these seem to provide "instructions" to the user, notice your two samples contain that set of 4 instructions. That might be an angle worth pursuing.

Let me know your thoughts!

Appreciate the feedback @IndiaAce! Good to know! Can I ask if there is a location for ground truth values that nlu_classifier can predict? Does this schema live in a different repository? I was having trouble finding possible values here (I just scanned through different rules to derive these ones)

I also checked for my samples what the predicted topics were.

The primary ones I got were:
"Professional and Career Development", "Reminders and Notifications", and "Financial Communications".
image

I am thinking of adding these topics to your "Advertising and Promotions" suggestion with a confidence != low condition.

I implemented your suggestions and hardened some of the rules to cut out false positives and overlap into other rules.
The first checks for an explicit instruction set either through bulleted or numbered steps or walkthrough guidance.
The second hardens the regex around leaving reviews for employers and adds a negation to exclude matches when referring to things like attachments or documents.

It looks like my sample is still flagged with these improvements as well.

Let me know what you think!

@IndiaAce
Copy link
Copy Markdown
Member

Hey Jacob, appreciate the iteration here! I still think the core detection idea is great, but I think we can scope this back a little bit? I ran some hunts with the proposed logic here and I had some success with it (also tested it against your sample)

type.inbound
// credential theft or scam intent
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("cred_theft", "job_scam") and .confidence != "low"
)
// employer/workplace review solicitation phrasing
and regex.icontains(body.current_thread.text,
                    '\brate\s+(?:your\s+)?(?:employer|workplace)\b',
                    '\breview\s+(?:your\s+)?(?:experience\s+(?:at|with)\s+(?:your|the)\s)',
                    '\b(?:employer|workplace)\s+(?:review|rating|feedback)\b',
                    '\bleave\s+(?:a\s+)?(?:review|rating).{0,40}(?:employer|workplace)',
                    '(?:glassdoor|comparably|great\s+place\s+to\s+work|kununu|jobcase).{0,40}(?:review|rate|rating|feedback)'
)
and (
  // credential harvesting
  regex.icontains(body.current_thread.text,
                  '(?:enter|provide|confirm|verify).{0,40}(?:password|credentials|login|email\s+and\s+password)',
                  'verify\s+your\s+(?:identity|eligibility|account)',
                  '(?:password|credential|login).{0,30}(?:enter|provide|confirm|verify|required)'
  )
  // or monetary incentive
  or regex.icontains(body.current_thread.text,
                     'gift.?card',
                     '(?:receive|earn|get|claim).{0,30}[\$€£]\d+',
                     '[\$€£]\d+.{0,30}(?:gift|reward|credit|incentive|voucher)',
                     'token\s+of\s+(?:our\s+)?(?:appreciation|thanks|gratitude)'
  )
)
// negating legitimate/trusted employer review/rating senders
and not (
  (
    sender.email.domain.root_domain in (
      'comparably.com',
      'greatplacetowork.com',
      'builtin.com',
      'lensa.com',
      'ziprecruiter.com',
      'kununu.com',
      'jobcase.com',
      'trustpilot.com'
    )
    or sender.email.domain.root_domain in $high_trust_sender_root_domains
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

NLU intent does quite a bit of the heavy lifting. If cred_theft or job_scam fires with confidence, we don't need all the extra layers. We just need a specific body regex to scope it to the employer review context, plus a "why it's malicious" gate (credential harvesting or monetary bait).

  1. NLU intent gates the rule to actually malicious content
  2. Employer review regex requiring explicit employer/workplace context.
  3. Cred harvesting or monetary bait
  4. Your same sender negation

Let me know what you think, nice work on this so far!

@jacob-mazurkiewicz
Copy link
Copy Markdown
Author

Hey Jacob, appreciate the iteration here! I still think the core detection idea is great, but I think we can scope this back a little bit? I ran some hunts with the proposed logic here and I had some success with it (also tested it against your sample)

type.inbound
// credential theft or scam intent
and any(ml.nlu_classifier(body.current_thread.text).intents,
        .name in ("cred_theft", "job_scam") and .confidence != "low"
)
// employer/workplace review solicitation phrasing
and regex.icontains(body.current_thread.text,
                    '\brate\s+(?:your\s+)?(?:employer|workplace)\b',
                    '\breview\s+(?:your\s+)?(?:experience\s+(?:at|with)\s+(?:your|the)\s)',
                    '\b(?:employer|workplace)\s+(?:review|rating|feedback)\b',
                    '\bleave\s+(?:a\s+)?(?:review|rating).{0,40}(?:employer|workplace)',
                    '(?:glassdoor|comparably|great\s+place\s+to\s+work|kununu|jobcase).{0,40}(?:review|rate|rating|feedback)'
)
and (
  // credential harvesting
  regex.icontains(body.current_thread.text,
                  '(?:enter|provide|confirm|verify).{0,40}(?:password|credentials|login|email\s+and\s+password)',
                  'verify\s+your\s+(?:identity|eligibility|account)',
                  '(?:password|credential|login).{0,30}(?:enter|provide|confirm|verify|required)'
  )
  // or monetary incentive
  or regex.icontains(body.current_thread.text,
                     'gift.?card',
                     '(?:receive|earn|get|claim).{0,30}[\$€£]\d+',
                     '[\$€£]\d+.{0,30}(?:gift|reward|credit|incentive|voucher)',
                     'token\s+of\s+(?:our\s+)?(?:appreciation|thanks|gratitude)'
  )
)
// negating legitimate/trusted employer review/rating senders
and not (
  (
    sender.email.domain.root_domain in (
      'comparably.com',
      'greatplacetowork.com',
      'builtin.com',
      'lensa.com',
      'ziprecruiter.com',
      'kununu.com',
      'jobcase.com',
      'trustpilot.com'
    )
    or sender.email.domain.root_domain in $high_trust_sender_root_domains
  )
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

NLU intent does quite a bit of the heavy lifting. If cred_theft or job_scam fires with confidence, we don't need all the extra layers. We just need a specific body regex to scope it to the employer review context, plus a "why it's malicious" gate (credential harvesting or monetary bait).

  1. NLU intent gates the rule to actually malicious content
  2. Employer review regex requiring explicit employer/workplace context.
  3. Cred harvesting or monetary bait
  4. Your same sender negation

Let me know what you think, nice work on this so far!

Thanks for the great feedback @IndiaAce!

I think these are fair points - especially if the nlu_classifier intents are a primary lever in catching some of these attacks. I'll be interested to hear how this process of "running hunts" works on your end! It seems to be a good way to evaluate the broadness/narrowness of rules.

I implemented your suggested logic - but left in a regex check for employer review related keywords in the subject of the email and added some additional words to the body-level regex checks that I think are indicative of review solicitation and monetary incentive language. This way we properly scope down to the attack type we're hoping to catch here.

I like your proposed structure of a hierarchical-like filtering system - this has been fun iterating on with you. Let me know if you have any other suggestions or comments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants