From f1e97107f087b07ef9f346280026043051408e6a Mon Sep 17 00:00:00 2001 From: Joel Dickson Date: Fri, 23 Feb 2024 09:30:14 +0700 Subject: [PATCH 1/2] This was masking session IDs, updating to check if the number is actually a credit card using luhn --- .../CreditCardMaskingOperator.cs | 78 ++++++++++++++----- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs b/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs index 3d087fc..e1f0e5a 100644 --- a/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs +++ b/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs @@ -1,27 +1,67 @@ -using System.Text.RegularExpressions; - +using System; +using System.Text.RegularExpressions; namespace Serilog.Enrichers.Sensitive { - public class CreditCardMaskingOperator : RegexMaskingOperator - { - private const string CreditCardPartialReplacePattern = - @"(?\d{4}(?[ -]?))(?\d{4}\k*\d{2})(?\d{2}\k*\d{4})"; +public class CreditCardMaskingOperator : RegexMaskingOperator +{ + private const string CreditCardPartialReplacePattern = + @"(?\d{4}(?[ -]?))(?\d{4}\k*\d{2})(?\d{2}\k*\d{4})"; + + private const string CreditCardFullReplacePattern = + @"(?\d{4}(?[ -]?)\d{4}\k*\d{4}\k*\d{4})"; - private const string CreditCardFullReplacePattern = - @"(?\d{4}(?[ -]?)\d{4}\k*\d{4}\k*\d{4})"; + private readonly string _replacementPattern; - private readonly string _replacementPattern; + public CreditCardMaskingOperator(bool fullMask) + : base(fullMask ? CreditCardFullReplacePattern : CreditCardPartialReplacePattern, RegexOptions.IgnoreCase | RegexOptions.Compiled) + { + _replacementPattern = fullMask ? "{0}" : "${{leading4}}{0}${{trailing6}}"; + } - public CreditCardMaskingOperator() : this(true) - { - } + protected override string PreprocessMask(string mask) + { + return string.Format(_replacementPattern, mask); + } - public CreditCardMaskingOperator(bool fullMask) - : base(fullMask ? CreditCardFullReplacePattern : CreditCardPartialReplacePattern, RegexOptions.IgnoreCase | RegexOptions.Compiled) - { - _replacementPattern = fullMask ? "{0}" : "${{leading4}}{0}${{trailing6}}"; - } + public override string Mask(string input) + { + var matches = Regex.Matches(input, _regexPattern, _regexOptions); + foreach (Match match in matches) + { + if (IsValidCreditCardNumber(match.Value)) + { + // Perform masking + input = Regex.Replace(input, match.Value, m => PreprocessMask("XXXX-XXXX-XXXX-XXXX")); + } + } + return input; + } + + private bool IsValidCreditCardNumber(string cardNumber) +{ + // Remove non-numeric characters + var cleanCardNumber = Regex.Replace(cardNumber, "[^0-9]", ""); - protected override string PreprocessMask(string mask) => string.Format(_replacementPattern, mask); - } + int sum = 0; + bool alternate = false; + for (int i = cleanCardNumber.Length - 1; i >= 0; i--) + { + var digit = int.Parse(cleanCardNumber[i].ToString()); + + if (alternate) + { + digit *= 2; + if (digit > 9) + { + digit = (digit % 10) + 1; + } + } + sum += digit; + alternate = !alternate; + } + // If the sum modulo 10 is 0, the number is valid according to the Luhn formula + return sum % 10 == 0; +} + +} } From 539c7c98aad8c6e114f8bcd417727e6ccfd24868 Mon Sep 17 00:00:00 2001 From: Joel Dickson Date: Fri, 23 Feb 2024 10:10:00 +0700 Subject: [PATCH 2/2] Update CreditCardMaskingOperator.cs --- .../CreditCardMaskingOperator.cs | 98 ++++++++++--------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs b/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs index e1f0e5a..8ca9bf1 100644 --- a/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs +++ b/src/Serilog.Enrichers.Sensitive/CreditCardMaskingOperator.cs @@ -1,67 +1,71 @@ using System; using System.Text.RegularExpressions; + namespace Serilog.Enrichers.Sensitive { -public class CreditCardMaskingOperator : RegexMaskingOperator -{ - private const string CreditCardPartialReplacePattern = - @"(?\d{4}(?[ -]?))(?\d{4}\k*\d{2})(?\d{2}\k*\d{4})"; + public class CreditCardMaskingOperator : IMaskingOperator + { + private const string CreditCardPartialReplacePattern = + @"(?\d{4}(?[ -]?))(?\d{4}\k*\d{2})(?\d{2}\k*\d{4})"; - private const string CreditCardFullReplacePattern = - @"(?\d{4}(?[ -]?)\d{4}\k*\d{4}\k*\d{4})"; + private const string CreditCardFullReplacePattern = + @"(?\d{4}(?[ -]?)\d{4}\k*\d{4}\k*\d{4})"; - private readonly string _replacementPattern; + private readonly string _replacementPattern; - public CreditCardMaskingOperator(bool fullMask) - : base(fullMask ? CreditCardFullReplacePattern : CreditCardPartialReplacePattern, RegexOptions.IgnoreCase | RegexOptions.Compiled) - { - _replacementPattern = fullMask ? "{0}" : "${{leading4}}{0}${{trailing6}}"; - } + public CreditCardMaskingOperator() : this(true) + { + } - protected override string PreprocessMask(string mask) - { - return string.Format(_replacementPattern, mask); - } + public CreditCardMaskingOperator(bool fullMask) + { + _replacementPattern = fullMask ? "{0}" : "${{leading4}}{0}${{trailing6}}"; + } - public override string Mask(string input) - { - var matches = Regex.Matches(input, _regexPattern, _regexOptions); - foreach (Match match in matches) + protected string PreprocessMask(string mask) { - if (IsValidCreditCardNumber(match.Value)) + return string.Format(_replacementPattern, mask); + } + + public MaskingResult Mask(string input, string mask) + { + var matches = Regex.Matches(input, _replacementPattern); + foreach (Match match in matches) { - // Perform masking - input = Regex.Replace(input, match.Value, m => PreprocessMask("XXXX-XXXX-XXXX-XXXX")); + if (IsValidCreditCardNumber(match.Value)) + { + // Perform masking + input = Regex.Replace(input, match.Value, m => PreprocessMask("XXXX-XXXX-XXXX-XXXX")); + return new MaskingResult { Match = true, Result = input }; + } } + return MaskingResult.NoMatch; } - return input; - } - - private bool IsValidCreditCardNumber(string cardNumber) -{ - // Remove non-numeric characters - var cleanCardNumber = Regex.Replace(cardNumber, "[^0-9]", ""); - - int sum = 0; - bool alternate = false; - for (int i = cleanCardNumber.Length - 1; i >= 0; i--) - { - var digit = int.Parse(cleanCardNumber[i].ToString()); - if (alternate) + private bool IsValidCreditCardNumber(string cardNumber) { - digit *= 2; - if (digit > 9) + // Remove non-numeric characters + var cleanCardNumber = Regex.Replace(cardNumber, "[^0-9]", ""); + + int sum = 0; + bool alternate = false; + for (int i = cleanCardNumber.Length - 1; i >= 0; i--) { - digit = (digit % 10) + 1; + var digit = int.Parse(cleanCardNumber[i].ToString()); + + if (alternate) + { + digit *= 2; + if (digit > 9) + { + digit = (digit % 10) + 1; + } + } + sum += digit; + alternate = !alternate; } + // If the sum modulo 10 is 0, the number is valid according to the Luhn formula + return sum % 10 == 0; } - sum += digit; - alternate = !alternate; } - // If the sum modulo 10 is 0, the number is valid according to the Luhn formula - return sum % 10 == 0; -} - -} }