Adding URLs to an application securely

An Anonymous Reader writes:

Dear Peter,

I am writing a desktop application that contains links to external websites inside the "Help" menu, as is common with many applications such as Internet Explorer and Microsoft Office. I want to make this list dynamic so that I can update it with cool new content over time. I want to do this by downloading a small XML file from my web server containing the text of the menu item and the URL to go to. How can I make sure that hackers don't insert a menu item to

www.evil.com

and exploit my customers?

Yours,

Anonymous Reader

 

Dear Anonymous,

I'm glad you asked that question. There are three main ways you can help prevent hackers from inserting menu items to www.evil.com in your situation. They are:

1) Download your XML file over an SSL connection. As long as you are connecting to https://www.example.com/ and verifying that the connection is secure, an attacker won't be able to tamper with the XML file in-transit to the user's computer. This doesn't help if an attacker compromises your web server though, as they could still insert malicious content to be "securely downloaded" to the client.

2) Sign the contents of your XML file and verify the signature on the user's computer. As long as the signature verifies correctly, you can be sure that no-one has tampered with the file either in transit or by compromising your web server (assuming you keep the private key physically separated from your web server). Note that it isn't sufficient to simply check that the file has a valid signature; you also need to check that it is signed by the correct publisher (ie, you!) and chains to the correct root. Otherwise the bad guys could just sign it with their own key-pair. You should also use an increasing version number in your digital signature's description so that you can detect attempts to "re-play" old, signed files.

3) Change the design to have less attack surface (risk). You don't actually need to send URLs to the client in the first place -- you only need to be able to uniquely identify the menu item that the user clicked on. A "safer" way to do this is to store all the URLs in a database on your server and assign each one a unique ID. This ID is sent to the desktop application along with the menu item text inside the XML file. When the user clicks on the menu item you simply construct a URL such as https://www.example.com/menu-redirector.aspx?id=ID_GOES_HERE and the server determines which URL to go to and does a redirect. This means the server is always in control of which URLs the client can be navigated to, and it can easily filter out invalid content. Even if an attacker compromises the XML file on the server (or in transit) the worst they can do is redirect your users to an un-intended (but still "good") site. Note that you should not build a redirect page that takes an arbitrary URL, as this can be abused in cross-domain attacks. Always build your redirect pages to take an opaque identifier that then maps back to a URL you control and know to be trustworthy.

And as a bonus tip, make sure you store the XML file in the user's profile, not inside the application folder under Program Files. This ensures that non-Administrative users can use the download-and-update feature.