Shortcut properties are in the shortcut, so if they can read the shortcut, they can read the properties


A customer wanted to know if “there was a way to hide the properties of a shortcut.”

We asked for an explanation of the problem they were trying to solve, so we could understand what their question meant. The customer liaison explained:

The customer is insisting on this, even though I think it’s really the wrong approach. They want to put a password into the parameters of a shortcut, but they don’t want their employees to see the password when they right-click the shortcut and select Properties. We’re trying to convince them of better ways of doing this, but right now they want to see if they can solve it by marking the field as “hidden” somehow.

If the password is anywhere in the shortcut file, the employees can dig it out. After all, the shell needs to dig it out, and since the shell runs with the user’s privileges, in order for the shell to see it, the user must be able to see it. In other words, you can’t hide anything in a shortcut because the user can just open the shortcut in Notepad and see all your “hidden” data. Or they can go to Task Manager and ask to see the command line. Or they can connect a debugger to Explorer and set a breakpoint on the Create­Process function.

It’s like saying, “I want my employees to be able to bake cakes, but I don’t want them to have access to an oven. To block access to the oven, I put a combination lock on the oven controls. On the other hand, I want to write a cake recipe that lets the employees bake cakes in the oven. Therefore, the recipe says Step 5: Go to the oven and press 1234. But now the employee can just read the recipe and find out the combination to the oven! Is there a way I can write a cake recipe that lets them bake a cake without revealing the oven combination?”

The recipe executes with the privileges of the employee. If you want the employee to be able to bake a cake by following the recipe, then they need to be able to perform the steps in the recipe, and that means being able to go to the oven and press 1234.

The oven analogy does provide some ideas on how you can solve the problem. For example, if you simply don’t want employees to be able to email the oven combination to their friends with the subject line Here’s the combination to the oven!, then change the way access to the oven is managed. Instead of putting a combination lock on the oven, put an employee ID card scanner on the oven that enables the oven controls if the employee has oven privileges.

For the original problem, this means changing your database so that instead of using a single password to control access and trusting each client to use it wisely, it uses the security identity of the client to control access. (I’m assuming that the password on the command line is a database password.)

On the other hand, if your goal is to prevent employees from using the oven to do anything other than bake at 350°F for one hour, you can change the employee ID card scanner so that it checks the employee for cake-baking privileges, and if so, sets the oven to bake for 350°F for one hour and locks the controls (except perhaps for a cancel button). If you have multiple recipes—say, cakes and cookies—the ID card scanner checks which recipes the employees are allowed to use and lets them choose which preset they want to activate.

For the original problem, this means changing your database so that the user identity selects which operations are permitted on the database. Some users have permission to see only records for active clients, whereas others have permission to see all records, and still others have modify permission.

If your goal is to prevent employees from doing anything other than baking cakes according to this specific recipe, then you need to move even more actions “behind the counter”, because you have no way of knowing that “that pan full of batter” was created according to your walnut cake recipe, or whether it’s some unauthorized recipe with extra cinnamon. If you don’t trust your employees to follow recipes, then you need to take the recipe out of their hands. The instructions are now Step 1: Order a walnut cake from the cafeteria.

For the original problem, this means changing your database so that instead of letting the employee access records directly, the employee submits the action to the database (“change client 23 address to 123 Main Street”), and the database verifies that the employee has “change a client address” permission, and if so, performs the record update.

Of course, if you want to ignore all the security guidance and “just hide the password in the shortcut file, why won’t you answer my question?”, you can just put the password somewhere other than the shortcut file. You could, say, have the shortcut run a batch file, and the batch file has the password.

Comments (33)
  1. That guy says:

    This sounds very complicated. I'll just give them admin privileges. Right after looking at this attachment the nice Russian lady sent me. Yes.

  2. President Skroob says:

    That's amazing! I've got the same combination on my luggage!

  3. pete.d says:

    The analysis is all well and good, no disagreement there. But there actually is a half-way, not-completely-awful option for the customer: have the program use a single encrypted/signed parameter (encoded as base64) that incorporates the password and any other options for the execution of the program. Then the data in the shortcut can be used by the user only to run the program in exactly the way intended.

    Of course, the user can still hack the program itself to retrieve the private key/decryption algorithm and decode the shortcut. But that's going to be true in any scenario where the password is both stored and used under the user's credentials (e.g. in a separate file).

    One possible fix to that problem would be to implement security-critical components as a service instead of in the executable the user runs. The encrypted parameter block is passed to the service which the user has no access to at all, not even to view the binaries. Then the service performs whatever action is needed on the user's behalf.

    None of this is meant to suggest that these ideas are better than simply putting the sensitive resource itself behind an identity-protected layer and requiring user credentials. IMHO that's the best solution. But there are acceptable alternatives for scenarios where that's not possible/practical for some reason.

  4. Only MS has the exclusive right to create shortcuts whose target says: notused (e.g. Metro style app shortcuts) or a greyed out target field (e.g. advertised shortcuts).

    [Hardly exclusive. The target is grayed out for any namespace extension. Try it with a shortcut to a control panel application, say. -Raymond]
  5. Diego says:

    Of course, if this were Unix, the "shortcut" (script) could just use setuid to get the password from a file the logged on user doesn't have access to.

    [And then do what with it? Run the database program directly? But then the database program would run as the setuid user. On the other hand, if you transfer the password back to the original user, then the original user can intercept it. -Raymond]
  6. "The target is grayed out for any namespace extension." But at least it shows the target there instead of saying "notused" and the shortcut is launchable from anywhere, not just explorer.exe shell:::{4234d49b-0245-4df3-b780-3893943456e1}.

    [I don't know what you're talking about. I don't see 'notused'. -Raymond]
  7. Maurits says:

    The obvious solution is to put a decoy password in the shortcut but embed the real password using LsaStorePrivateData.  Logging in with the decoy password trips an alarm.

  8. jader3rd says:

    Let me get this straight, the customer is jumping through all of these hoops so they can avoid using proper permissions/security groups on the database?

  9. Graham says:

    The use of the password to access a database is an assumption by Raymond. All that's known for certain is that the password is passed a a command line parameter to a program.

    [And as long as that program runs with the security context of the user, the user can steal that password. That's sort of my point. -Raymond]
  10. James Schend says:

    @Raymond: obviously any Windows feature xpclient doesn't understand is some kind of evil conspiracy against the common developer. It can't simply be a Windows feature xpclient doesn't understand.

  11. Joshua says:

    [And then do what with it? Run the database program directly? But then the database program would run as the setuid user. -Raymond]

    That's exactly what a lot of UNIX developers would do. It turns out that X message passing is slightly more secure than Windows message passing (you can still fake it out pretty good but things like EM_GETSEL for overwriting memory in the target process don't exist).

  12. I suspect xpclient is looking at a Windows Installer COM shortcut, whereby the text shown in the "Target" field comes from some MSI property (I forget which) and so can say pretty much anything it wants as the actual shortcut is resolved via the Windows Installer service.

    And no, nothing exclusive to Microsoft about those either.

  13. JohnCKirk says:

    I don't think that you always want to grant access based on the user ID: it may make sense to do it based on the tool that the person is using.

    Taking a real life example, there was a company with two applications. App 1 was the stock control system. App 2 (mine) had read-only access to the stock control system to look up product codes, but it stored all its information in its own database. Both apps used SQL authentication, i.e. one username/password per application. Shortly after App 2 was installed, they found a problem in their stock control database (missing/incorrect data) and they immediately blamed me for it. I was able to clear myself, because a) my app didn't make any changes, and b) even if I'd got drunk and written the wrong commands, my app didn't have permission to make any changes. However, if both apps had used the end user's credentials then I wouldn't have had that safety net/excuse.

    The best workaround I've come up with is pete.d's method, which is similar to the way that websites usually work: the database can have a single set of credentials (used by the ASP.NET code), then each person who logs into the website can have their own separate credentials (stored elsewhere). However, it seems a bit unwieldy. Is there a "best practice" approach to this?

  14. @jader3rd: I have seen many highly intelligent folk jump through all kind of hoops to avoid doing what specialists know is the correct/better way of doing things. It seems like they get their mind set on one solution then put blinders on and won’t really consider any other path to a solution. It doesn’t seem to matter what kind of problem it is either. If there is hardware to fix a problem, they will say “hardware is expensive, fix it in the software” then spend more $$ on a software solution than the hardware would have cost, then complain that it doesn’ work as well as they would like. Or, as in this case, there is a perfectly good way to do things in software, but it isn’t the way they think it should be done so they aren’t satisfied. OK, rant over. :)

  15. ErikF says:

    This doesn't seem any different from the standard Unix guidance not to put any potentially compromising information in the arguments passed to a program because command lines can be seen by any user (using "top", for example). There comes a point where you have to roll with the system, not fight it, and security is one of those points for me.

  16. WndSks says:

    @AndyCadley: The implementation of MSI shortcuts are exclusive to MS since it has its own datablock in the .lnk with some encoded text (EXP_DARWIN_LINK) You can not invent your own custom data block (And even you could, Windows would not know that it should gray out things)

  17. Marcel says:

    Actually my first thought was that they were trying to start a RunAs-variant that accepts a password on the command line to do some admin job for the user or start a program the users need that cannot cope with non-admin privileges. Sometimes I would have found this handy myself…

  18. Kemp says:

    @James Schend

    He's just inflating his post count the only way he knows how. There's not much point reading his messages generally and even less point replying. If he *actually* cared about the issues he complains about then he wouldn't be airing the issues in the comments section of a blog belonging to someone who has no control over the features in question.

  19. Cheong says:

    Just use the file name as password. Putting the password right in front of the user. The user shouldn't have guessed it. [/sarcasm]

  20. Nope I am looking at a shortcut to any Metro style app that says notused in the target, hides the actual target: http://i.imgur.com/O5Qws.png and can't be launched from anywhere except the "Applications" namespace extension in Windows 8. Or even for MSI advertised shortcuts, you need a tool like this: http://www.winhelponline.com/…/determine-the-target-path-of-windows-installer-shortcuts to see the target, which is masked and greyed out.

    [If you study the LNK file carefully you'll understand what's going on. (And you are welcome to put "notused" in your shortcuts too.) Nothing evil, just different. You seem to think that everything you don't understand must be evil. -Raymond]
  21. Cheong says:

    @Marcel: I sometimes port little application without UI as service, so I can change the account it's running on (such as to poll data to local Access database), and place a little shortcut on desktop to tell user to run it when they need it. (The application is written as part of DR plan, so normally it won't be run as the cold standby database server won't be running)

    In that case, Raymond's tips on how to allow non-admin user start a service is helpful and inspiring.

  22. Layered cake says:

    Man, I'd be willing to pay a buck 'o five for an oven that could bake a range of cakes with just the swipe of a card. And it'd be the *right* way to do things too! (The boss' grandmother can keep her recipes secret)

  23. Medinoc says:

    Diego's comment misses out that SETUID can't apply here, but it is indeed reminiscent of it.

    When working on that problem, I have noticed that it's possible on Windows to have an executable file that can be executed but not read (like say, a program with a password in resources). However that doesn't prevent a determined user from debugging the program once it's running.

    As for the SETUID problem itself, the root of it seems to be that on Windows you can't log a user on without that user's credentials, unlike Unix where the superuser can do that.

  24. Neil says:

    @Medinoc It's possible for privileged processes to impersonate, so that they can access local resources in another user's security context, without knowing their password. (Vista makes this really easy via Task Manager.) I have some vague recollection that things worked differently on a domain controller though.

  25. speedfan says:

    Did I even say the word "evil"? My point is it masks information from the user which should be shown.

    [You implied evil by your outrage. -Raymond]
  26. voo says:

    @xpclient Maybe next time you don't understand something, first think, then search and then maybe annoy us all with some conspiracy theories? Obviously that would at least halve your post count, but winning a bumper sticker for your 10.000th misguided complaint isn't the goal here or is it?

  27. speedfan says:

    @James Schend, Kemp and voo, three clueless morons and counting who haven't the faintest idea of what's the discussion is about between Raymond and me. There's no question of "not understanding" and "evil conspiracy". The point is MS hides the target of certain shortcuts and provides no way for end users to resolve them.

  28. someone says:

    I'm with xp.client on his previous post. Its cheap to bash him without a clue about the subject of discussion. As it turned out, he was right with the "notused" thing and others was wrong by their purely theoretical assumptions about this topic.

  29. Joshua says:

    @Medinoc: It turns out it is possible to log on without a password if you don't want network resources.

  30. Maurits says:

    continues to be confused by "xpclient" and "xp.client".  Are you two the same person?

  31. Sven2 says:

    So, what exactly is wrong with the batch file attempt? You can give rights to execute and deny rights to read the batch file, can't you?

  32. Gabe says:

    Sven2: It's impossible to execute a batch file that you can't read because it's executed by first reading the file.

  33. @Maurits, yes sorry about that. Depends on which Live ID I sign in first to check my email. :)

Comments are closed.