Articles
maskCC UDF
Strips all credit card variations from a string. Useful when sending/storing user-submitted data in order to remain compliant with VISA Payment Card Industry Data Security Standard (PCI DSS) requirements
April 19, 2025
The maskCC user-defined function (UDF) takes a text string as input, searches for patterns that resemble credit card numbers, attempts to validate these potential numbers using ColdFusion's built-in credit card validation, and then masks the validated numbers by replacing all but the last four digits with asterisks. This is a common technique for protecting sensitive information while still allowing for partial display for identification purposes. This function is recommended whenever dumping, logging or send emails that may contain PCI DSS restricted data.
Source Code
<cfscript>
// NOTE: Requires jreEscape UDF (or reEscape BIF can be used if using ACF)
string function maskCC(string textFragment="") output=false hint="Mask CC numbers in any text string" {
local.response = tostring(arguments.textFragment);
local.matches = rematch("\b(?:\d[ -_]*?){13,16}\b", local.response);
if (arraylen(local.matches)){
for (local.match in local.matches) {
local.cc = local.match.replaceAll("\D", "");
if (isvalid("creditcard", local.cc)){
local.response = local.response.replaceAll(jreescape(local.match), "\*\*\*\*\*\*\*\*\*\*\*\*" & jreescape(right(local.cc,4)));
}
}
}
return local.response;
}
</cfscript>
Demo
<cfscript>
// https://test-gateway.mastercard.com/api/documentation/integrationGuidelines/supportedFeatures/testAndGoLive.html?locale=en_US
tests = [
"Masking 5123 4500 0000 0008 strings": "Mastercard: Test card from mastercard.com"
,"Masking 2223-0000-0000-0007 strings": "Mastercard: Test card from mastercard.com"
,"Masking 5111_1111_1111_1118 strings": "Mastercard: Test card from mastercard.com"
,"Masking 2223-0000 0000_0023 strings": "Mastercard: Test card from mastercard.com"
,"Masking 4508750015741019 strings": "Visa: Test card from mastercard.com"
,"Masking 4012-0000-3333-0026 strings": "Visa: Test card from mastercard.com"
,"Masking 30123400000000 strings": "Diners Club: Test card from mastercard.com"
,"Masking 3625 9600 0000 12 strings": "Diners Club: Test card from mastercard.com"
,"Masking 3528000000000007 strings": "JCB: Test card from mastercard.com"
,"Masking 3528111100000001 strings": "JCB: Test card from mastercard.com"
,"Masking 6011003179988686 strings": "Discover: Test card from mastercard.com"
,"Masking 6011963280099774 strings": "Discover: Test card from mastercard.com"
,"Masking 5000000000000000005 strings": "Maestro: Test card from mastercard.com"
,"Masking 5666555544443333 strings": "Maestro: Test card from mastercard.com"
,"Masking 135492354874528 strings": "UATP: Test card from mastercard.com"
,"Masking 135420001569134 strings": "UATP: Test card from mastercard.com"
,"Masking 6201089999995464 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6201089999991455 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6201089999994020 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6201089999999300 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6201089999994749 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6214239999999611 strings": "UnionPay: Test card from mastercard.com"
,"Masking 6214239999999546 strings": "UnionPay: Test card from mastercard.com"
,"Masking 2205459999997832 strings": "PayPak: Test card from mastercard.com; invalid LUHN"
,"Masking 2205439999999541 strings": "PayPak: Test card from mastercard.com; invalid LUHN"
,"Masking 4111 1111 111 strings": "Visa: Invalid - too short"
,"Masking 5123-4567-8901-2345-6789 strings": "Mastercard: Invalid - too long"
];
results = [:];
for (test in tests){
results[test] = "#maskCC(test)# (#tests[test]#)";
}
writedump(var=results, label="maskCC results");
// Dumping data to the screen or an email? Sanitize it!
savecontent variable="dumpHtml" {
writedump(var=tests, label="sanitizing cfdump html");
}
writeoutput(maskCC(dumpHtml));
</cfscript>