0

I am building a wrapper to process payments. We want to log requests, but don't want to store sensitive credit card data. A query string will be passed similar to what is below

amount=100.00&expMonth=01&expYear=14&cardnumber=4111111111111111

I want to mask the first 12 digits of the credit card number with X values. However, the cardnumber key will not always be in the same spot.

My first leaning is to create a NameValueCollection and check for the key and do a string.format("XXXX-XXXX-XXXX-{0}", substring of the value

var qs = HttpUtility.ParseQueryString(request);
foreach (string key in qs)
{
    if (key == "creditcard")
    {

    }
}

Can someone point me in the right direction?

I need to save the string in the same format with just the credit card number masked.

Jon Harding
  • 4,928
  • 13
  • 51
  • 96
  • 1
    Side note: consider not putting sensitive information in Url that may be copy-pasted by a user... Generally such requests are done via post and putting information in fields (along with some sort of replay/CSRF protection) – Alexei Levenkov Dec 27 '13 at 21:50
  • It actually isn't coming in through a query string. It will be coming in through the body of the request. It's just passed in querystring format – Jon Harding Dec 27 '13 at 21:50
  • Why don't you use regular ASP.Net (WebForms/MVC) mechanism than? Anyway - check out http://stackoverflow.com/questions/829080/how-to-build-a-query-string-for-a-url-in-c which shows how to build it back. – Alexei Levenkov Dec 27 '13 at 21:52
  • What database/ORM are you using? – Alon Gubkin Dec 27 '13 at 22:01

2 Answers2

0

Seems like a sensible approach, but maybe using Get method on the NameValueCollection would be easier. Like so:

String maskedCardNumber = null;
var qs = HttpUtility.ParseQueryString(request);
var cardNumber = qs.Get("cardnumber");
if (cardNumber != null)
{
    var substring = cardNumber.Substring(cardNumber.Length - Math.Min(4, cardNumber.Length));
    maskedCardNumber = String.Format("XXXX-XXXX-XXXX-{0}", substring);
}
Choc13
  • 796
  • 7
  • 23
  • Good solution, but now I need to put it all back together again. The string needs to be saved in it's original format with the masked credit card – Jon Harding Dec 27 '13 at 22:01
0

This works great, there may be a more elegant solution though.

var maskedRequest = "";
var qs = HttpUtility.ParseQueryString(request);
foreach (string item in qs.AllKeys)
{
   if (item != "cardnumber")
   {
       maskedRequest = maskedRequest + item + "=" + qs.Get(item) + "&";
   }
   else
   {
       maskedRequest = maskedRequest + item + "=" + string.Format("XXXX-XXXX-XXXX-{0}", qs.Get(item).Substring(12, 4)) + "&";
    }
}

maskedRequest = maskedRequest.Remove(maskedRequest.Length - 1)
Jon Harding
  • 4,928
  • 13
  • 51
  • 96