Dot Net Auto Update
I felt like .net was lacking a simple secure automatic update library so I've implemented something and put it up here. Before anyone considers using the library I was keen for the update process to get a bit a peer review.
Here are the steps:
- The client software is populated with a public key and URI to poll.
- Client polls a URI for a manifest file.
- Manifest is downloaded and signature (in a separate ".signature") is used to check that the manifest is valid.
- A list of pending updates is parsed out of the manifest (to show to the user).
- The installer file is downloaded and again is verified with a corresponding ".signature" file. (the downloaded file will be protected with ACLs)
- The installer is run.
Mitigated threats:
- The manifest signature should prevent any malicious downloads ("carpet bombing")
- The installer signature should prevent any MITM attacks from sending malicious installers
- Protecting the downloaded installer with ACLs should prevent any local escalation attacks.
Unmitigated threats:
- A MITM attack where the attacker always reports "no updates available". (Could keep a client at a vulnerable version)
References:
- Secure Software Updates: Disappointments and New Challenges
- Black Ops 2008: It’s The End Of The Cache As We Know It
- Evilgrade Will Destroy Us All
Just as an addition, add a MD5 CheckSum to the downloaded file as well, otherwise, looking good :)- Fair comment below.Added:
The only additional thing I can see here is delving into things like obfuscating the code, or archiving the setup file and locking the archive, then once downloaded, unlocking it. That type of thing. However I think what you have currently done should be 100%.
The only time more is needed is when the application is very security complex. Right now you prevent DLL tampering and proof of origin, which for an auto updater, should be plenty.
Dan Kaminsky has a good set of guidelines for an updater:
To succeed, your update package must be:
From your description in this question, it appears that you have the first 3.
Don't mean to be troll in here, but you are trying to solve an already solved problem. Using SSL would be a much better choice. That would solve all problems listed in your question.
I understand that this system can be useful for people who can't afford an SSL certificate but anyone who can get one, should get one to solve this problem.
Don't forget, "Complexity is the enemy of security".
There is some very nice comment and solution in this post. But I am strongly agree with dr. evil. You should use SSL connection for update and the certificate must be saved (built on) in the client. So, you can make sure the client is not going to accept fake certificate. I think it will effectively immune the client from the MiTM attack.
NOTE: If client can accept unauthorized certificate then MiTM attack can be successful, so do not give this option to the client.
Edit: I think SSL certificate can be self signed in this case.
So I'm not clear on something; the downloader verifies that the manifest is the one it expects, via a signature, does it do the same for the actual patches it installs?
Well, you can try to prevent MITM by having the "no version update" response also include a timestamp (& be signed). Then if a month goes by (or whatever your policy is) with no version change and no timestamp update, then you refuse to run the software or pop-up a warning dialog informing the user there might be a MITM attack.
Doesn't solve the problem of what to do if your server goes down - presumably you treat it the same as a no timestamp change.