An iPhone application that we’re developing for a client handles credit card information on the device. Therefore we need to have the app tested and certified against the Payment Application Data Security Standard (PA-DSS).
Unfortunately the consultant we had lined up for the testing self-destructed.
Do you know anyone in this business with experience testing iPhone apps? Are you a PCI consultant looking for a gig? Please let me know in the comments below. Thanks!
In a previous post I listed a line of code that looked like this:
NSString *credentials = [NSString stringWithFormat:@”%c%s%@%c%c%s%@”, ‘u’, “ser:”, @”pas”, ’s’, ‘w’, “ord”, @”@”];
Reader Matt asked me to expand on this in his comment. (Hint: Don’t be afraid to suggest topics for this blog.)
The reason for the curious looking line above is to avoid the whole string to be easily visible in the binary application file. Had I just done this:
NSString *credentials = @"user:password";
it is trivial to search the binary file and find this information in clear text in the file. But by breaking up the string into mixed parts of characters, C strings and Objective-C strings, the content is dispersed in the binary file making it more difficult to find.
Other ways you can obscure strings is to manipulate the string before it’s used. An easy example is to add 1 to each byte in the string so that “HAL” becomes “IBM”. Of course you can make that function as complex as you want.
Keep in mind that security by obscurity is simply hiding information, which is very different from employing encryption using a mathematically proven algorithm. While it may take a long time to find a needle in a haystack, it just requires luck or patience. Whereas cracking a good safe is really difficult. When you think about security for your application you need to decide when a haystack is good enough for the information you’re trying to protect. And when that is the case, feel free to use a variation of the techniques described here.
To download a small amount of data from a URL it’s very convenient to use:
NSData *downloadData = [NSData dataWithContentsOfURL:url];
To get data from a URL that requires authentication there several classes that specifically deal with this, e.g. NSURLAuthenticationChallengeSender and NSURLCredential, which require that you use NSURLConnection instead.
NSURLConnection has several other advantages such as asynchronous downloading, but if you just want a one-liner, you can still use NSData dataWithContentsOfURL with basic authentication using the following method.
Normally the URL that you pass to dataWithContentsOfURL looks something like https://www.mysite.com/getmydata
You can add a username and password directly in the URL like this https://username:firstname.lastname@example.org/getmydata and this type of URL works just fine with NSData dataWithContentsOfURL.
- When you include the username and password in the URL, they may be stored in the web server’s log file.
- If you don’t use SSL, the username and password are sent in clear text.
- Don’t store the URL including the username and password in a property file or plist. These files can easily be viewed by someone looking inside your app bundle.
- Don’t store the credentials like this: NSString *credentials = @”user:password@”; This string is very easy to find in the executable file. If your security requirements are low then you can apply some mild obfuscation: NSString *credentials = [NSString stringWithFormat:@”%c%s%@%c%c%s%@”, ‘u’, “ser:”, @”pas”, ‘s’, ‘w’, “ord”, @”@”]; If you have real security requirements, use real encryption.