EZ-Pass Data Integrity and security fail

On October 29th 2011, I entered an EZ-Pass lane of the Brooklyn Battery Tunnel toll plaza and, to make a long story short, learned my EZ-Pass was broken. On November 19th 2011, I went to the Newark, NJ EZ-Pass Customer Service Center to rectify the matter. I was given another external EZ-Pass tag, and told it would cost me $33 dollars. I was not asked for payment, and assumed it would come  out of my account. I went out, mounted the new EZ-Pass tag to my front licence plate (with the old screws, because the new screws were one way security screws) and went on my merry way (through several tollbooths). That’s when the real fun began.

My old EZ-Pass would not be detected by a toll lane at all. It had developed a crack, and I assume the circuitry malfunctioned. The new one on the other hand caused the toll booths to say  “toll unpaid call EZ-Pass.” I assumed at the time it would take a while for the tag to be associated with my account. This assumption was supported by the fact that he woman at the service center wrote the serial number of my tag on a paper form. This form incidently stated it was for accounting of the internal tags only. I assumed that the process of associating tags with accounts was not instantaneous.

Then November 24th came around, and I needed to travel to participate in not one, but two feasts of slaughtered turkeys for an American Holiday called Thanksgiving. My tag failed to work. Obviously something was amiss, and I took action on Black Friday. I logged into my account and only saw the old tag number. So I went to my car, got my new tag number off my tag, and called EZ-Pass. While I was waiting to talk to someone I made a horrible discovery.

So let’s backup here a little, because this is my second horrible EZ-Pass discovery. Before I got my new EZ-Pass tag, I only interacted with EZ-Pass via the EZ-Pass NJ website. To log into the site, you need either your account number or your tag number, and a pin. The pin is an all numeric password. I will come out and make the confession that at the time I made it, its was the same as my ATM pin. That is no longer my ATM pin, because this was years ago.

So I shared passwords across accounts, but that’s not a discovery. I always knew this. The discovery was this. When I was at the customer service center, I was asked for my pin to verify my account. I gave it to the woman, and she did not type it into her computer. She looked at her screen to make sure what I said matched what was displayed. So pins are stored unencrypted. Mind you, an EZ-Pass account contains a lot of personally identifiable information (PII). In addition to credit card numbers and your address, it contains license plate numbers, and places you’ve been. With this discovery, it seems that a lot of low paid clerks, living in the same state as the tag holder can access this information with just a persons name. Remind me never to anger an EZ-Pass employee.

Ok so that’s terrible, but hardly worth writing a blog post about. I mean I’ve seen plenty of data security sins of that caliber, none of which have inspired a written tirade. However, something sent me over the top here.

So what sent me over the top you might ask? Well when I first logged in I used my old tag number, because that’s the number I know and use to log in to my account. However, while waiting on hold, I said to myself, “let me use the new tag number and my pin to log in.” I did this and I saw not my account,  but the account of a complete stranger. I explain the situation to the person on the phone and the outcome is I have to mail in both tags (at my own cost), and a new tag will be sent to me (at which point I will be charged $33). There is no record of my original visit to the EZ-Pass center. I have a feeling if they look hard enough in the other person’s account, they will find it. I’d like to know what transpired while the guy put me on hold.

I will likely have a lot of headaches to sort out once this is all said and done. I regret not writing down the name of the person whose account my second tag was assigned to, or the name of the clerk in Newark or phone operator I dealt with.  If there are any further developments, I’ll report them here.

Editing elements with periods in the name in PowerShell

Recently, a coworker asked me about a problem he was having with a PowerShell script that edited an app.config file. It was a simple enough fix for an experienced PowerShell programmer, but worth sharing the solution for those not as experienced.

For this article, I’ll use a very small example web.config that demonstrates the problem.

<?xml version="1.0" encoding="utf-8" ?>
    <add key="verbose" value="true"/>
    <compilation debug="true" />

The script my coworker was using worked something like this:

$scriptPath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptPath

$configFile = (Get-Content "$($dir)web.config")
'Before: ' + $configFile.configuration.appSettings.OuterXml
$configFile.configuration.appSettings.add.value = 'false'
'After:  ' + $configFile.configuration.appSettings.OuterXml

Which of course prints out the following output:

Before: <appSettings><add key="verbose" value="true" /></appSettings>
After:  <appSettings><add key="verbose" value="false" /></appSettings>

The actual script saved the configuration file and didn’t print anything to the screen, but that’s irrelevant to the problem. The problem was he needed to edit the element inside the element. He tried this first:

$configFile = (Get-Content "$($dir)web.config")
'Before: ' + $configFile.configuration.system.web.OuterXml
$configFile.configuration.system.web.compilation.debug = 'false'
'After:  ' + $configFile.configuration.system.web.OuterXml

Which got him the following:

Property 'debug' cannot be found on this object; make sure it exists and is settable.
At C:UserszippyDocumentsdeletemeposh.configeditConfig.ps1:3 char:50
+ $configFile.configuration.system.web.compilation. <<<< debug = 'false'
    + CategoryInfo          : InvalidOperation: (debug:String) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

The problem was the dot in system.web. PowerShell uses a period to separate an object from its members. However, all is not lost, because there is an alternate notation.

'Before: ' + $configFile.configuration['system.web'].OuterXml
$configFile.configuration['system.web'].compilation.debug = 'false'
'After:  ' + $configFile.configuration['system.web'].OuterXml

As you can see, we can reach into an xml element with indexer notation. Please note that you will get an error if you put a period before the opening square bracket, but a period is required after the closing square bracket. If you would like some more in depth knowledge of how indexers work, see this MSDN page. While that article is written from a C# perspective, the concepts can be applies to PowerShell as well.