US Post Office Web Tools gives away your password
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>