Detection rules › Sublime MQL

Credential phishing: Suspicious e-sign agreement document notification

Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects phishing attempts disguised as e-signature requests, characterized by common document sharing phrases, unusual HTML padding, and suspicious link text.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering

Event coverage

Rule body MQL

type.inbound
and any([subject.subject, sender.display_name],
        regex.icontains(strings.replace_confusables(.),
                        "D[0o]cuLink",
                        "Agreement",
                        "Access.&.Appr[0o]ved",
                        "Agreement.{0,5}Review",
                        "Attend.and.Review",
                        "action.re?quired",
                        "AuthentiSign",
                        "Completed.File",
                        "D[0o]chsared",
                        "D[0o]cshared",
                        "D[0o]csPoint",
                        "D[0o]cument.Shared",
                        "D[0o]cuCentre",
                        "D[0o]cuCenter",
                        "D[0o]cCenter",
                        "D[0o]csOnline",
                        "D[0o]cSend",
                        "D[0o]cu?Send",
                        "d[0o]csign",
                        "D[0o]cu-eSin",
                        "D[0o]cu-management",
                        "\\beSign",
                        "e\\.sign",
                        "esign.[0o]nline",
                        "[SsZz][lL][GgSs][Nn].*D[0o]c",
                        "e-d[0o]c",
                        "e-signature",
                        "e-Verify Doc",
                        "eSignature",
                        "eSign&Return",
                        "eSign[0o]nline",
                        "Fileshare",
                        "Review.and.C[0o]mplete",
                        "Review.&.Sign",
                        "Sign[0o]nline",
                        "Signature.Request",
                        "Shared.C[0o]mpleted",
                        "Sign.and.Seal",
                        "viaSign",
                        "D[0o]cuSign",
                        "D[0o]csID",
                        "Complete.{0,10}D[0o]cuSign",
                        "Enroll & Sign",
                        "Review and Sign",
                        "Sign(?:Report|Now)",
                        "SignD[0o]c",
                        "D[0o]cxxx",
                        "d[0o]cufile",
                        'E\x{00AD}-\x{00AD}S\x{00AD}i\x{00AD}g\x{00AD}n\x{00AD}&Return',
                        "d[0o]cument.signature",
                        "Electr[0o]nic.?Signature",
                        "Complete: ",
                        "Please (?:Review|Sign)",
                        "^REVIEW$",
                        "requests your signature",
                        "signature on.*contract",
                        "Independent Contract",
                        "Contract.*signature",
                        "add your signature",
                        "signature needed",
                        "attn_task",
                        "DocReq\\b"
        )
        or (
          regex.icontains(strings.replace_confusables(.), "action.re?quired")
          and not (
            sender.email.domain.root_domain == "sharepointonline.com"
            and headers.auth_summary.dmarc.pass
            and strings.icontains(subject.subject, "asked to edit")
          )
        )
)
and (
  // unusual repeated patterns in HTML
  regex.icontains(body.html.raw, '((<br\s*/?>\s*){20,}|\n{20,})')
  or regex.icontains(body.html.raw, '(<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}')
  or regex.icontains(body.html.raw,
                     '(<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\s*){30,}'
  )
  or regex.icontains(body.html.raw, '(<p>&nbsp;</p>\s*){7,}')
  or regex.icontains(body.html.raw, '(<p[^>]*>\s*&nbsp;<br>\s*</p>\s*){5,}')
  or regex.icontains(body.html.raw, '(<p[^>]*>&nbsp;</p>\s*){7,}')
  or strings.count(body.html.raw, "&nbsp;\u{200C}&nbsp;\u{200C}&nbsp") > 50
  or regex.count(body.html.raw,
                 '<span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]\s*<\/span><span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]+\s*<\/span>'
  ) > 50
  // lookalike docusign
  or regex.icontains(body.html.raw, '>Docus[1l]gn<')
  or strings.icontains(body.current_thread.text, 'completed by all parties')
  or (
    regex.icontains(body.html.inner_text, 'Document')
    and length(body.html.inner_text) < 500
  )
  // common greetings via email.local_part
  or any(recipients.to,
         // use count to ensure the email address is not part of a disclaimer
         strings.icount(body.current_thread.text, .email.local_part) > 
         // sum allows us to add more logic as needed
         sum([
               strings.icount(body.current_thread.text,
                              strings.concat('was sent to ', .email.email)
               ),
               strings.icount(body.current_thread.text,
                              strings.concat('intended for ', .email.email)
               )
             ]
         )
  )
  // common greetings via mailbox display name
  or strings.icount(body.current_thread.text, mailbox.display_name) > 
  // sum allows us to add more logic as needed
  sum([
        strings.icount(body.current_thread.text,
                       strings.concat('was sent to ', mailbox.display_name)
        ),
        strings.icount(body.current_thread.text,
                       strings.concat('intended for ', mailbox.display_name)
        )
      ]
  )
  // Abnormally high count of mailto links in raw html
  or regex.count(body.html.raw,
                 'mailto:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}'
  ) > 50

  // High count of empty elements (padding)
  or regex.count(body.html.raw,
                 '<(?:p|div|span|td)[^>]*>\s*(?:&nbsp;|\s)*\s*</(?:p|div|span|td)>'
  ) > 30

  // HR impersonation
  or strings.ilike(sender.display_name, "HR", "H?R", "*Human Resources*")

  // Sender display name contains a phone number
  or regex.icontains(sender.display_name,
                     '\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}'
  )
)
and (
  any(body.links,

      // suspicious content within link display_text
      regex.icontains(strings.replace_confusables(.display_text),
                      "activate",
                      "re-auth",
                      "verify",
                      "acknowledg",
                      "(keep|change).{0,20}(active|password|access)",
                      '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
                      'use.same.pass',
                      'validate.{0,15}account',
                      'recover.{0,15}messages',
                      '(retry|update).{0,10}payment',
                      'check activity',
                      '(listen|play).{0,10}(vm|voice)',
                      'clarify.{0,20}(deposit|wallet|funds)',
                      'enter.{0,15}teams',
                      'Review and sign',
                      'REVIEW.*DOCUMENT',
                      'Open Document',
                      'Sign Now',
                      'complete tasks?'
      )
      // check that the display_text is all lowercase
      or (
        regex.contains(.display_text,
                       "\\bVIEW",
                       "DOWNLOAD",
                       "CHECK",
                       "KEEP.(SAME|MY)",
                       "VERIFY",
                       "ACCESS\\b",
                       "SIGN\\b",
                       "ENABLE\\b",
                       "RETAIN",
                       "PLAY",
                       "LISTEN",
        )
        and regex.match(.display_text, "^[^a-z]*[A-Z][^a-z]*$")
      )

      // the display text is _exactly_
      or .display_text in~ ("Open")

      // URL fragment containing recipient's address
      or .href_url.fragment in map(recipients.to, .email.email)
  )
  // one hyperlinked image that's not a tracking pixel
  or (
    length(html.xpath(body.html,
                      "//a//img[(number(@width) > 5 or not(@width)) and (number(@height) > 5 or not(@height))]"
           ).nodes
    ) == 1
    and length(body.current_thread.text) < 500
  )
  or (
    length(attachments) > 0
    and any(attachments,
            (
              regex.icontains(beta.ocr(.).text,
                              "activate",
                              "re-auth",
                              "verify",
                              "acknowledg",
                              "(keep|change).{0,20}(active|password|access)",
                              '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
                              'use.same.pass',
                              'validate.{0,15}account',
                              'recover.{0,15}messages',
                              '(retry|update).{0,10}payment',
                              'check activity',
                              '(listen|play).{0,10}(vm|voice)',
                              'clarify.{0,20}(deposit|wallet|funds)',
                              'enter.{0,15}teams',
                              'Review and sign'
              )
            )
            or (
              any(file.explode(.),
                  regex.icontains(.scan.ocr.raw,
                                  "activate",
                                  "re-auth",
                                  "verify",
                                  "acknowledg",
                                  "(keep|change).{0,20}(active|password|access)",
                                  '((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)',
                                  'use.same.pass',
                                  'validate.{0,15}account',
                                  'recover.{0,15}messages',
                                  '(retry|update).{0,10}payment',
                                  'check activity',
                                  '(listen|play).{0,10}(vm|voice)',
                                  'clarify.{0,20}(deposit|wallet|funds)',
                                  'enter.{0,15}teams',
                                  'Review and sign'
                  )
              )
            )
    )
  )
)
// the message is unsolicited and no false positives
and (
  not profile.by_sender_email().solicited
  or profile.by_sender_email().prevalence == "new"
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and not profile.by_sender_email().any_messages_benign
  )
  or (
    profile.by_sender_email().any_messages_malicious_or_spam
    and profile.by_sender_email().any_messages_benign
    and (
      not headers.auth_summary.dmarc.pass or not headers.auth_summary.spf.pass
    )
  )
)

// negate replies/fowards containing legitimate docs
and not (length(headers.references) > 0 or headers.in_reply_to is not null)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and (
      any(distinct(headers.hops, .authentication_results.dmarc is not null),
          strings.ilike(.authentication_results.dmarc, "*fail")
      )
    )
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Detects phishing attempts disguised as e-signature requests, characterized by common document sharing phrases, unusual HTML padding, and suspicious link text.

  1. inbound message
  2. any of [subject.subject, sender.display_name] where any holds:
    • strings.replace_confusables(.) matches any of 62 patterns
      • D[0o]cuLink
      • Agreement
      • Access.&.Appr[0o]ved
      • Agreement.{0,5}Review
      • Attend.and.Review
      • action.re?quired
      • AuthentiSign
      • Completed.File
      • D[0o]chsared
      • D[0o]cshared
      • D[0o]csPoint
      • D[0o]cument.Shared
      • D[0o]cuCentre
      • D[0o]cuCenter
      • D[0o]cCenter
      • D[0o]csOnline
      • D[0o]cSend
      • D[0o]cu?Send
      • d[0o]csign
      • D[0o]cu-eSin
      • D[0o]cu-management
      • \\beSign
      • e\\.sign
      • esign.[0o]nline
      • [SsZz][lL][GgSs][Nn].*D[0o]c
      • e-d[0o]c
      • e-signature
      • e-Verify Doc
      • eSignature
      • eSign&Return
      • eSign[0o]nline
      • Fileshare
      • Review.and.C[0o]mplete
      • Review.&.Sign
      • Sign[0o]nline
      • Signature.Request
      • Shared.C[0o]mpleted
      • Sign.and.Seal
      • viaSign
      • D[0o]cuSign
      • D[0o]csID
      • Complete.{0,10}D[0o]cuSign
      • Enroll & Sign
      • Review and Sign
      • Sign(?:Report|Now)
      • SignD[0o]c
      • D[0o]cxxx
      • d[0o]cufile
      • E\x{00AD}-\x{00AD}S\x{00AD}i\x{00AD}g\x{00AD}n\x{00AD}&Return
      • d[0o]cument.signature
      • Electr[0o]nic.?Signature
      • Complete:
      • Please (?:Review|Sign)
      • ^REVIEW$
      • requests your signature
      • signature on.*contract
      • Independent Contract
      • Contract.*signature
      • add your signature
      • signature needed
      • attn_task
      • DocReq\\b
    • all of:
      • strings.replace_confusables(.) matches 'action.re?quired'
      • not:
        • all of:
          • sender.email.domain.root_domain is 'sharepointonline.com'
          • headers.auth_summary.dmarc.pass
          • subject.subject contains 'asked to edit'
  3. any of:
    • body.html.raw matches '((<br\\s*/?>\\s*){20,}|\\n{20,})'
    • body.html.raw matches '(<p[^>]*>\\s*<br\\s*/?>\\s*</p>\\s*){30,}'
    • body.html.raw matches '(<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\\s*){30,}'
    • body.html.raw matches '(<p>&nbsp;</p>\\s*){7,}'
    • body.html.raw matches '(<p[^>]*>\\s*&nbsp;<br>\\s*</p>\\s*){5,}'
    • body.html.raw matches '(<p[^>]*>&nbsp;</p>\\s*){7,}'
    • strings.count(body.html.raw, '&nbsp;\\u{200C}&nbsp;\\u{200C}&nbsp') > 50
    • regex.count(body.html.raw, '<span\\s*class\\s*=\\s*"[^\\"]+"\\s*>\\s*[a-z]\\s*<\\/span><span\\s*class\\s*=\\s*"[^\\"]+"\\s*>\\s*[a-z]+\\s*<\\/span>') > 50
    • body.html.raw matches '>Docus[1l]gn<'
    • body.current_thread.text contains 'completed by all parties'
    • all of:
      • body.html.inner_text matches 'Document'
      • length(body.html.inner_text) < 500
    • any of recipients.to where:
      • strings.icount(body.current_thread.text) > sum([strings.icount(body.current_thread.text, strings.concat('was sent to ', .email.email)), strings.icount(body.current_thread.text, strings.concat('intended for ', .email.email))])
    • strings.icount(body.current_thread.text) > sum([strings.icount(body.current_thread.text, strings.concat('was sent to ', mailbox.display_name)), strings.icount(body.current_thread.text, strings.concat('intended for ', mailbox.display_name))])
    • regex.count(body.html.raw, 'mailto:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}') > 50
    • regex.count(body.html.raw, '<(?:p|div|span|td)[^>]*>\\s*(?:&nbsp;|\\s)*\\s*</(?:p|div|span|td)>') > 30
    • sender.display_name matches any of 3 patterns
      • HR
      • H?R
      • *Human Resources*
    • sender.display_name matches '\\+?([ilo0-9]{1}.)?\\(?[ilo0-9]{3}?\\)?.[ilo0-9]{3}.?[ilo0-9]{4}'
  4. any of:
    • any of body.links where any holds:
      • strings.replace_confusables(.display_text) matches any of 19 patterns
        • activate
        • re-auth
        • verify
        • acknowledg
        • (keep|change).{0,20}(active|password|access)
        • ((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)
        • use.same.pass
        • validate.{0,15}account
        • recover.{0,15}messages
        • (retry|update).{0,10}payment
        • check activity
        • (listen|play).{0,10}(vm|voice)
        • clarify.{0,20}(deposit|wallet|funds)
        • enter.{0,15}teams
        • Review and sign
        • REVIEW.*DOCUMENT
        • Open Document
        • Sign Now
        • complete tasks?
      • all of:
        • .display_text matches any of 11 patterns
          • \\bVIEW
          • DOWNLOAD
          • CHECK
          • KEEP.(SAME|MY)
          • VERIFY
          • ACCESS\\b
          • SIGN\\b
          • ENABLE\\b
          • RETAIN
          • PLAY
          • LISTEN
        • .display_text matches '^[^a-z]*[A-Z][^a-z]*$'
      • .display_text in ('Open')
      • .href_url.fragment in map(recipients.to, .email.email)
    • all of:
      • length(html.xpath(body.html, '//a//img[(number(@width) > 5 or not(@width)) and (number(@height) > 5 or not(@height))]').nodes) is 1
      • length(body.current_thread.text) < 500
    • all of:
      • length(attachments) > 0
      • any of attachments where any holds:
        • beta.ocr(.).text matches any of 15 patterns
          • activate
          • re-auth
          • verify
          • acknowledg
          • (keep|change).{0,20}(active|password|access)
          • ((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)
          • use.same.pass
          • validate.{0,15}account
          • recover.{0,15}messages
          • (retry|update).{0,10}payment
          • check activity
          • (listen|play).{0,10}(vm|voice)
          • clarify.{0,20}(deposit|wallet|funds)
          • enter.{0,15}teams
          • Review and sign
        • any of file.explode(.) where:
          • .scan.ocr.raw matches any of 15 patterns
            • activate
            • re-auth
            • verify
            • acknowledg
            • (keep|change).{0,20}(active|password|access)
            • ((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)
            • use.same.pass
            • validate.{0,15}account
            • recover.{0,15}messages
            • (retry|update).{0,10}payment
            • check activity
            • (listen|play).{0,10}(vm|voice)
            • clarify.{0,20}(deposit|wallet|funds)
            • enter.{0,15}teams
            • Review and sign
  5. any of:
    • not:
      • profile.by_sender_email().solicited
    • profile.by_sender_email().prevalence is 'new'
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • not:
        • profile.by_sender_email().any_messages_benign
    • all of:
      • profile.by_sender_email().any_messages_malicious_or_spam
      • profile.by_sender_email().any_messages_benign
      • any of:
        • not:
          • headers.auth_summary.dmarc.pass
        • not:
          • headers.auth_summary.spf.pass
  6. none of:
    • length(headers.references) > 0
    • headers.in_reply_to is set
  7. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • any of distinct(headers.hops) where:
        • .authentication_results.dmarc matches '*fail'
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: body.current_thread.text, body.html, body.html.inner_text, body.html.raw, body.links, body.links[].display_text, body.links[].href_url.fragment, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].authentication_results.dmarc, headers.in_reply_to, headers.references, mailbox.display_name, recipients.to, recipients.to[].email.email, recipients.to[].email.local_part, sender.display_name, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: beta.ocr, file.explode, html.xpath, profile.by_sender_email, regex.contains, regex.count, regex.icontains, regex.match, strings.concat, strings.count, strings.icontains, strings.icount, strings.ilike, strings.replace_confusables. Reference lists: $high_trust_sender_root_domains.

Indicators matched (113)

FieldMatchValue
regex.icontainsregexD[0o]cuLink
regex.icontainsregexAgreement
regex.icontainsregexAccess.&.Appr[0o]ved
regex.icontainsregexAgreement.{0,5}Review
regex.icontainsregexAttend.and.Review
regex.icontainsregexaction.re?quired
regex.icontainsregexAuthentiSign
regex.icontainsregexCompleted.File
regex.icontainsregexD[0o]chsared
regex.icontainsregexD[0o]cshared
regex.icontainsregexD[0o]csPoint
regex.icontainsregexD[0o]cument.Shared
101 more
regex.icontainsregexD[0o]cuCentre
regex.icontainsregexD[0o]cuCenter
regex.icontainsregexD[0o]cCenter
regex.icontainsregexD[0o]csOnline
regex.icontainsregexD[0o]cSend
regex.icontainsregexD[0o]cu?Send
regex.icontainsregexd[0o]csign
regex.icontainsregexD[0o]cu-eSin
regex.icontainsregexD[0o]cu-management
regex.icontainsregex\\beSign
regex.icontainsregexe\\.sign
regex.icontainsregexesign.[0o]nline
regex.icontainsregex[SsZz][lL][GgSs][Nn].*D[0o]c
regex.icontainsregexe-d[0o]c
regex.icontainsregexe-signature
regex.icontainsregexe-Verify Doc
regex.icontainsregexeSignature
regex.icontainsregexeSign&Return
regex.icontainsregexeSign[0o]nline
regex.icontainsregexFileshare
regex.icontainsregexReview.and.C[0o]mplete
regex.icontainsregexReview.&.Sign
regex.icontainsregexSign[0o]nline
regex.icontainsregexSignature.Request
regex.icontainsregexShared.C[0o]mpleted
regex.icontainsregexSign.and.Seal
regex.icontainsregexviaSign
regex.icontainsregexD[0o]cuSign
regex.icontainsregexD[0o]csID
regex.icontainsregexComplete.{0,10}D[0o]cuSign
regex.icontainsregexEnroll & Sign
regex.icontainsregexReview and Sign
regex.icontainsregexSign(?:Report|Now)
regex.icontainsregexSignD[0o]c
regex.icontainsregexD[0o]cxxx
regex.icontainsregexd[0o]cufile
regex.icontainsregexE\x{00AD}-\x{00AD}S\x{00AD}i\x{00AD}g\x{00AD}n\x{00AD}&Return
regex.icontainsregexd[0o]cument.signature
regex.icontainsregexElectr[0o]nic.?Signature
regex.icontainsregexComplete:
regex.icontainsregexPlease (?:Review|Sign)
regex.icontainsregex^REVIEW$
regex.icontainsregexrequests your signature
regex.icontainsregexsignature on.*contract
regex.icontainsregexIndependent Contract
regex.icontainsregexContract.*signature
regex.icontainsregexadd your signature
regex.icontainsregexsignature needed
regex.icontainsregexattn_task
regex.icontainsregexDocReq\\b
sender.email.domain.root_domainequalssharepointonline.com
strings.icontainssubstringasked to edit
regex.icontainsregex((<br\s*/?>\s*){20,}|\n{20,})
regex.icontainsregex(<p[^>]*>\s*<br\s*/?>\s*</p>\s*){30,}
regex.icontainsregex(<p class=".*?"><span style=".*?"><o:p>&nbsp;</o:p></span></p>\s*){30,}
regex.icontainsregex(<p>&nbsp;</p>\s*){7,}
regex.icontainsregex(<p[^>]*>\s*&nbsp;<br>\s*</p>\s*){5,}
regex.icontainsregex(<p[^>]*>&nbsp;</p>\s*){7,}
regex.countregex<span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]\s*<\/span><span\s*class\s*=\s*"[^\"]+"\s*>\s*[a-z]+\s*<\/span>
regex.icontainsregex>Docus[1l]gn<
strings.icontainssubstringcompleted by all parties
regex.icontainsregexDocument
regex.countregexmailto:[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}
regex.countregex<(?:p|div|span|td)[^>]*>\s*(?:&nbsp;|\s)*\s*</(?:p|div|span|td)>
strings.ilikesubstringHR
strings.ilikesubstringH?R
strings.ilikesubstring*Human Resources*
regex.icontainsregex\+?([ilo0-9]{1}.)?\(?[ilo0-9]{3}?\)?.[ilo0-9]{3}.?[ilo0-9]{4}
regex.icontainsregexactivate
regex.icontainsregexre-auth
regex.icontainsregexverify
regex.icontainsregexacknowledg
regex.icontainsregex(keep|change).{0,20}(active|password|access)
regex.icontainsregex((verify|view|click|download|goto|keep|Vιew|release).{0,15}(attachment|current|download|fax|file|document|message|same)s?)
regex.icontainsregexuse.same.pass
regex.icontainsregexvalidate.{0,15}account
regex.icontainsregexrecover.{0,15}messages
regex.icontainsregex(retry|update).{0,10}payment
regex.icontainsregexcheck activity
regex.icontainsregex(listen|play).{0,10}(vm|voice)
regex.icontainsregexclarify.{0,20}(deposit|wallet|funds)
regex.icontainsregexenter.{0,15}teams
regex.icontainsregexReview and sign
regex.icontainsregexREVIEW.*DOCUMENT
regex.icontainsregexOpen Document
regex.icontainsregexSign Now
regex.icontainsregexcomplete tasks?
regex.containsregex\\bVIEW
regex.containsregexDOWNLOAD
regex.containsregexCHECK
regex.containsregexKEEP.(SAME|MY)
regex.containsregexVERIFY
regex.containsregexACCESS\\b
regex.containsregexSIGN\\b
regex.containsregexENABLE\\b
regex.containsregexRETAIN
regex.containsregexPLAY
regex.containsregexLISTEN
regex.matchregex^[^a-z]*[A-Z][^a-z]*$
body.links[].display_textmemberOpen
strings.ilikesubstring*fail