Detection rules › Sublime MQL
DLP - PCI: Visa Credit Card Number
Detects outbound emails containing Visa credit card numbers in the message body or text-parseable attachments. Visa card numbers begin with 4 and are 13 or 16 digits long, optionally separated by spaces or dashes (e.g. 4111 1111 1111 1111 or 4111-1111-1111-1111). Deploy this rule with the "Block Delivery" action to prevent PCI data exfiltration, or in passive mode to monitor and audit outbound mail containing card numbers. Regex engine: RE2 (Golang). No PCRE lookbehind — word boundaries (\b) are used instead. Attachment content is extracted via file.explode() / .scan.strings.strings.
Event coverage
| Message attribute |
|---|
| attachments (collection) |
| body.current_thread |
| type |
Rule body MQL
type.outbound
and (
// Body: Visa 16-digit (4XXX XXXX XXXX XXXX or 4XXX-XXXX-XXXX-XXXX)
regex.contains(body.current_thread.text,
'\b4\d{3}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b'
)
// Body: Visa 13-digit legacy (4XXX XXXX XXXXX)
or regex.contains(body.current_thread.text,
'\b4\d{3}[\s-]?\d{4}[\s-]?\d{5}\b'
)
// Attachments: scan extracted strings from PDFs, Office docs, CSVs, etc.
or any(attachments,
.file_extension in~ ('pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'eml', 'msg')
and any(file.explode(.),
any(.scan.strings.strings,
regex.contains(., '\b4\d{3}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b')
or regex.contains(., '\b4\d{3}[\s-]?\d{4}[\s-]?\d{5}\b')
)
)
)
)
Detection logic
Scope: outbound message.
Detects outbound emails containing Visa credit card numbers in the message body or text-parseable attachments. Visa card numbers begin with 4 and are 13 or 16 digits long, optionally separated by spaces or dashes (e.g. 4111 1111 1111 1111 or 4111-1111-1111-1111). Deploy this rule with the "Block Delivery" action to prevent PCI data exfiltration, or in passive mode to monitor and audit outbound mail containing card numbers. Regex engine: RE2 (Golang). No PCRE lookbehind — word boundaries (\b) are used instead. Attachment content is extracted via file.explode() / .scan.strings.strings.
- outbound message
any of:
- body.current_thread.text matches '\\b4\\d{3}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b'
- body.current_thread.text matches '\\b4\\d{3}[\\s-]?\\d{4}[\\s-]?\\d{5}\\b'
any of
attachmentswhere all hold:- .file_extension in ('pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'eml', 'msg')
any of
file.explode(.)where:any of
.scan.strings.stringswhere any holds:- . matches '\\b4\\d{3}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b'
- . matches '\\b4\\d{3}[\\s-]?\\d{4}[\\s-]?\\d{5}\\b'
Inspects: attachments[].file_extension, body.current_thread.text, type.outbound. Sensors: file.explode, regex.contains.
Indicators matched (11)
| Field | Match | Value |
|---|---|---|
regex.contains | regex | \b4\d{3}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b |
regex.contains | regex | \b4\d{3}[\s-]?\d{4}[\s-]?\d{5}\b |
attachments[].file_extension | member | pdf |
attachments[].file_extension | member | doc |
attachments[].file_extension | member | docx |
attachments[].file_extension | member | xls |
attachments[].file_extension | member | xlsx |
attachments[].file_extension | member | txt |
attachments[].file_extension | member | csv |
attachments[].file_extension | member | eml |
attachments[].file_extension | member | msg |