US Post Office Web Tools gives away your password

   Print.Print
Email.Email weblog link
Blog this.Blog this
brian d foy

brian d foy
Feb. 25, 2005 03:12 AM
Permalink

Atom feed for this author. RSS 1.0 feed for this author. RSS 2.0 feed for this author.

URL: http://www.usps.com/webtools/technical.htm...

I applied for a User-ID and password so I could use the US Post Office's web services. They have some promising looking tools: zip code lookup, city/state lookup, address verification, and some other things.

A couple of hours after I applied for an account, I got my welcome email. I was on to the next task though, so I filed it. Tonight I wanted to take it for a spin.

I wrote a little program to give it a go. I didn't follow their technical details because I don't want to put a long XML string in the query string of the XML. This is an idempotent request, but I'll put that stuff in the message body anyway and use a POST request.

Here's the code. Notice I have my ID and password in the environment. The USPS says on just about every other page that I can't give out those credentials. I can't share them and I can't tell anyone else what they are. Fair enough.

Look at the request scheme though! It's plain ol' HTTP. That's plaintext floating across the air, or copper, or whatever. I tried sticking https in there, but it never makes a connection. Every time I test this little application, I'm exposing my credentials. You don't have to hack ChoicePoint to get that.

use HTTP::Request;
use LWP::UserAgent;

my $content =<<"HERE";
API=Verify&XML=<AddressValidateRequest
	USERID="$ENV{USPS_ID}"
	PASSWORD="$ENV{USPS_PASS}">
<Address ID="0">
<Address1>5250 N. Kenmore Suite 157</Address1>
<City>Chicago</City>
<State>IL</State>
<Zip5>60640</Zip5>
</Address>
</AddressValidateRequest>
HERE

my $ua = LWP::UserAgent->new();

my $request = HTTP::Request->new( POST =>
'http://testing.shippingapis.com/ShippingAPITest.dll' );
$request->content( $content );

print $request->as_string;

my $response = $ua->request( $request );

print $response->as_string;

Okay, it's their system and a password to their system. Obviously they know what they are doing. They are the government after all.

Not so fast. Check out this response: All I really have is a User-ID and password. I can't actually use the service, even on the testing service. It turns out that I have to request that separately. Ughh. Not only that, they are using IIS. Oh boy, so this service will down a lot, won't it? I'll have to wait to see about that because I need someone to authorize me to use the web service I signed up for two weeks ago.

HTTP/1.1 200 OK
Connection: close
Date: Fri, 25 Feb 2005 11:04:46 GMT
Server: Microsoft-IIS/5.0
Client-Date: Fri, 25 Feb 2005 11:04:40 GMT
Client-Peer: 56.0.134.43:80
Client-Response-Num: 1

<Error>
	<Number>80040b1a</Number>
	<Description>API Authorization failure. 
User 931THEPE4647 is not authorized to use API Verify.</Description>
	<Source>UspsCom::DoAuth</Source>
</Error>

brian d foy is a Perl trainer for Stonehenge Consulting Services and is the publisher of The Perl Review.