Sunday, August 17, 2008

Business Requirements for Security Controls

Before I start, this is not going to be an exposition on the topic requirements or controls, it's just a look at an interesting and well thought out business case and use of a control.

I was confused by a change in my mortgage the other day so went to my county website to look up what I pay in property taxes. I regularly use King County's I-Map to research such things.

The site had made a change and added a Captcha. Captchas are those screwy pictures of words that are hard to read. A computer can't make sense of them, so it proves that a human actually entered that data. This is used for two main reasons: to stop automated data mining of non-authenticated pages and to stop automated brute force attempts against a page that includes user name and password field. Forcing these things to become manual processes can be very valuable.

A quick aside on how that might be done. Take this URL,
http://www5.kingcounty.gov/KCGISReports/property_report.aspx?PIN=9208900079
if you were to follow it, you'd see on the page that they URL input variable, PIN=9208900079 happens to match the parcel number of the lot. Knowing this, you can write a simple script to query and log each parcel number in the county. This is all public record, so there isn't much of a reason to try and stop this, with the exception of the resource consumption.

Back on track, first the technical part... I clicked on the link to my parcels tax information and was presented with a Captcha where there hadn't been one before.
https://payments.metrokc.gov/metrokc.ecommerce.propertytaxweb/RealProperty.aspx?Parcel=9208900079
I entered the words, received my tax information, and my mortgage confusion went away.

The confusion was immediately replaced by curiosity. Security controls have a way of doing that to me. I noticed that they resulting page address included an input variable.
https://payments.metrokc.gov/metrokc.ecommerce.propertytaxweb/RealProperty.aspx?Parcel=q1iPffuHa3Qx3uPtyG%2fb3A%3d%3d
Parcel=. It seemed odd to me that the variable was used to request the page. I would have expected my session state to be maintained server side or at least in a cookie, where it's not seen.

Looking at the variable data, I immediately noticed the mixed case letters, numbers, and the trailing %3d%3d. The %3d%3d pointed me to URLEncoded data representing ==, which tells me that the whole value is a base64 encoded string. I've seen a lot of silly stuff lately, so I decoded the string. I'd have suspected it no matter what, but == is a dead giveaway.

I decoded it and I got, hex ab 58 8f 7d fb 87 6b 74 31 de e3 ed c8 6f db dc
which is gibberish as ASCII. I took a minute to reverse the nibbles and byte order and a few othe things. There was nothing interesting there.

I decided to see if there was a discernible pattern, so I looked up the next parcel number 9208900080. That came back q1iPffuHa3ScKwwlW92daw%3d%3d, which is ab 58 8f 7d fb 87 6b 74 9c 2b 0c 25 5b dd 9d 6b in hex.

Here I noticed that the first and second value were similar.
ab 58 8f 7d fb 87 6b 74 31 de e3 ed c8 6f db dc
ab 58 8f 7d fb 87 6b 74 9c 2b 0c 25 5b dd 9d 6b

The strings are 128 bits and the first 64 bits are the same, but the last 64 vary considerably, even tough they are only one base ten digit apart. I'm no cryptographer, but after a bit more looking, I've decided that they are using a block cipher that uses 64 bit blocks. As only one byte at the end of the data is going to change, 9208900079 to 9208900080, the first block would not change and thus remain the same, using the same key. If the system encrypting the parcel number and decrypting the number are the only ones in possession of the key, this is a way to securely pass the data between them, via the web browser. It however is subject to replay. I may not know the key, but I don't need it to enter the cipher text again.

I decided to check my assumption that this URL was all I needed to link to the record, so I used cURL to get the URL. This means no session state and no cookies are involved. Sure enough, I got the tax record back.

I decided to email the county, to see if this was intentional. It seemed to me that this was an oversight of some sort.

The county was prompt in responding that this was actually part of the requirement. They wanted to limit data mining of the tax information, but wanted the tax payers to be able to save a link to the page for their records.

My assumption that this was a fumbled hand off between the Captcha and session handling in the back end system was wrong.

This is a great example of a well thought out use of a security control. It meets the requirement of stopping automated data collection while making the system more friendly for the end-users.

Kudos to the King County web team!