Question

Consider the following requirements

  1. Windows software which communicates with a web application using basic authentication
  2. The software is an MSI package
  3. The software requires a token to be placed in order to authenticate itself to the web application
  4. The token is unique to every user, but the user is expected to install the software with the same token on several machines

The question is:

What is the best strategy to distribute the software from the web application with appropriate token in it ? (The user should not be asked to enter the token.)

The proposed solution is::

When the user clicks the download software button from the web application instead of giving then the software, we generate a VBScript file which contains the token and download location of the software package (MSI), and deliver it as a download. After that, when the user invokes the script, the following things will happen.

  • The software will be downloaded and the token is passed to the installer and a custom action inside the installer will get the token and configure the application accordingly

Will the Windows world accept the above solution? Do they feel it unnatural? Is there a better solution to the problem at hand?

Was it helpful?

Solution

The standard solution which you have surely seen from other software vendors is to

  • let the user download and install the software, maybe with or without the registration, but let the software itself lead the user through the registration process afterwards.

Through that process, after the user is authentificated, the token is downloaded in form of a license file. If you want to let the user install the software on a second machine without a new authentification, allow the license file to be copied to the other machine. You wrote "user should not be asked to enter the token" - but actually, where is the difference for the user if he has to copy a VBS file to a second machine, or if he has to copy a license file?

Note that this does not prevent your user to give away the software together with the license file to another person, but since your own approach does not prevent that either, I guess you are not after a solution for that problem.

A different approach is not to use VBS, but generate a personalized downloader in form of an exe file (it is not too hard to provide a C or C++ source code which is personalized by modifiying just one small code file and then compiled on-the-fly by your web server). At least this prohibits modifications by the average user with a simple text editor like Notepad, which would be possible for a VBS downloader. And you do not have to teach your users how to run a VB script.

And if you really want to provide personalized installer packages, there is a third option. It is possible to generate or regenerate your MSI packages on-the-fly, so you can replace the personal token file inside an MSI package for each individual download. This SO post contains some information about this, and here is shown how a single file can be replaced inside a compressed MSI. That may be the smoothest solution for your case.

OTHER TIPS

Downloadable scripts to be run - VBScript or Javascript - always sounds very fishy to me, especially since there are too many black sheep out there abusing such things to install malware. You don't want to train anyone using your program to trust, download, and use such scripts.

Unfortunately I can't think of any secure fire & forget solution to this that won't include possible security vulnerabilities (like someone unintentionally passing the token to a co-worker as part of the installer package).

Theoretically you could install a browser plugin to act as an authentication/communication bridge between the web application and the native program (similar to what EA does with their Battlelog plugin for the newer Battlefield games), but even that isn't something perfect.

As such I'd still strongly advice you to go the (a tiny bit) more intrusive way and asking the user for login details once the program is installed. Keep in mind that you might want some way to revoke tokens as well (even if it's just due to a stolen machine).

You could, although I'm not certain I actually recommend it, embed the user's token in the filename of the installer, and put code in the installer to retrieve it.

To prove I didn't make it up, Sophos anti-virus does this. Rather predictably, number one on their list of Most common Installation issues is "Renaming the installer file name". But I assume the benefit is that since they don't modify the contents of the installer at all, the server that distributes it doesn't need access to the private keys that sign it.

Anyway the general principle is that for serious software you probably want to distribute a signed executable generated in the most secure location you have, together with an unsigned token that's generated on the fly by some public-facing web server. If you don't want to make the user download two files, copy-paste the token, or anything of that kind, then the filename is about the only bits you have left to communicate with.

Putting the token into unsigned code intended to run with full user privileges on the user's machine, even just a script, rather defeats the purpose of signing the installer. If you want to go that route, then you almost might as well distribute an unsigned installer with the user's token patched into it. To a tiny proportion of geeky users, a very simple VBScript doesn't need to be signed since it can be verified by eye not to be malicious. But there aren't many of them, so "almost" is "very nearly indeed".

There are two aspects involved in this question.

  1. Packaging of your application
  2. Distribution of user tokens

For the point 1, I recommend the ClickOnce deployment model. I have made assumption you have built a Microsoft .NET framework application. Even if otherwise, you could implement something similar to ClickOnce deployment in your technology platform. I intend to highlight more on the deployment model rather than the particular technology.

For the point 2, it could be addressed in two different ways -

  1. Consider building a small application (something similar to your current VBScript code). However this application would be an executable like .exe. This application will be packaged along with the program which you intend to distribute. Let us call it as Product Activator. Its sole purpose would be to connect to a token-generating service and get one token for the current user. Assuming you have UI fields to collect user id from the user. This product activator could be part of your larger portfolio of applications which you distribute through the web.
  2. As part of the application there could be a one time startup module / code which does the same activity as the product activator described above.

Let me focus on the token generating service. This element is present in both the options of the solution. The service is the piece of code which you have today to generate tokens for users. You should consider hosting it as a web service with limited discovery and access to avoid exposing your logic of generating the token.

In both the approaches, the user is not prompted for a token. However, user id might be an user input expected from the user. In both the approaches, like @Mario pointed out, the risk of educating the user to run an VBScript script is avoided. On top of it, the process of installing the application is now a task of registering the binaries of your application on the client machine. The logic of registering the user is a different perspective and is not open for the user to tweak around with as it would be if the user opened the VBScript file.

Licensed under: CC-BY-SA with attribution
scroll top