Manipulating the zone identifier to specify where a file was download from


When you download a file via Internet Explorer, the file is tagged with a little bit of information known as a zone identifier which remembers where the file was downloaded from. This is what tells Explorer to put up the "Yo, did you really want to run this program?" prompt and which is taken into account by applications so that they can do things like disable scripting and macros when they open the document, just in case the file is malicious.

Today's Little Program is really three Little Programs: One to read the zone identifier, one to set the zone identifier, and one to clear it.

#define STRICT
#include <windows.h>
#include <atlbase.h>
#include <urlmon.h>
#include <stdlib.h>

int __cdecl wmain(int argc, wchar_t **argv)
{
 if (argc < 2) return 0;

 CCoInitialize init;

 CComPtr<IZoneIdentifier> spzi;
 spzi.CoCreateInstance(CLSID_PersistentZoneIdentifier);

 DWORD dwZone;
 if (SUCCEEDED(CComQIPtr<IPersistFile>(spzi)
                   ->Load(argv[1], STGM_READ)) &&
     SUCCEEDED(spzi->GetId(&dwZone))) {
  printf("Zone identifier is %d\n", dwZone);
 } else {
  printf("Couldn't get zone identifier (perhaps there isn't one)\n");
 }

 return 0;
}

The first program takes a file name on the command line (fully-qualified path, please) and prints the zone identifier associated with it. The numeric values for the most commonly-encountered zone identifiers are

Identifier Value
URLZONE_LOCAL_MACHINE 0
URLZONE_INTRANET 1
URLZONE_TRUSTED 2
URLZONE_INTERNET 3
URLZONE_UNTRUSTED 4

Note also that if you want your application to be sensitive to the file zone (so that you can disable features for untrusted documents), you should use the IInternet­Security­Manager::Map­Url­To­Zone function rather than using only the file zone identifier, because the effective zone of a file is a combination of the file's declared zone as well as its physical location. (For example, a file in the Temporary Internet Files directory or on an untrusted server should not be given full trust regardless of what it claims. Additional reading.)

Here's a program that uses IInternet­Security­Manager::Map­Url­To­Zone to determine the effective security zone:

#define STRICT
#include <windows.h>
#include <atlbase.h>
#include <urlmon.h>
#include <stdlib.h>

int __cdecl wmain(int argc, wchar_t **argv)
{
 if (argc < 2) return 0;

 CCoInitialize init;

 CComPtr<IInternetSecurityManager> spism;
 spzi.CoCreateInstance(CLSID_InternetSecurityManager);

 DWORD dwZone;
 if (SUCCEEDED(spism->MapUrlToZone(
                   argv[1],
                   &dwZone,
                   MUTZ_ISFILE | MUTZ_DONT_UNESCAPE))) {
  printf("Zone is %d\n", dwZone);
 } else {
  printf("Couldn't get zone\n");
 }

 return 0;
}

The MUTZ_IS­FILE flag saves you the hassle of having to prepend file: in front of the path, but you still have to pass a full path because the first parameter is a URL, not a path.

Okay, that was a bit of a digression there. Let's write another Little Program which changes the zone identifier.

#define STRICT
#include <windows.h>
#include <atlbase.h>
#include <urlmon.h>
#include <stdlib.h>

int __cdecl wmain(int argc, wchar_t **argv)
{
 if (argc < 3) return 0;

 CCoInitialize init;

 CComPtr<IZoneIdentifier> spzi;
 spzi.CoCreateInstance(CLSID_PersistentZoneIdentifier);
 spzi->SetId(_wtol(argv[2]));
 CComQIPtr<IPersistFile>(spzi)->Save(argv[1], TRUE);

 return 0;
}

This program takes two parameters: A fully-qualified path and a zone (in integer form). It applies the zone to the file, overwriting the existing zone if any.

Finally, here's a Little Program to remove the zone information from the file entirely. This is the equivalent of clicking the Unblock button in the file property sheet.

#define STRICT
#include <windows.h>
#include <atlbase.h>
#include <urlmon.h>
#include <stdlib.h>

int __cdecl wmain(int argc, wchar_t **argv)
{
 if (argc < 2) return 0;

 CCoInitialize init;

 CComPtr<IZoneIdentifier> spzi;
 spzi.CoCreateInstance(CLSID_PersistentZoneIdentifier);
 spzi->Remove();
 CComQIPtr<IPersistFile>(spzi)->Save(argv[1], TRUE);

 return 0;
}
Comments (38)
  1. Tess says:

    Zone identifier is a useless "feature" that only wears down the mouse and exacerbates the user.

    Forgot to remove it once from a driver install file. Installed the driver. On every boot when the background program started that vexing "security warning" dialog showed up. The zone information had infected the files it unpacked and installed. Had to remove the driver, remove the zone information and install it again. Took 2 reboots extra.

    Microsoft is helping to kill mother nature.

    The feature wants to be helpful but any sane person would install a firewall and anti-virus program which makes that feature redundant and creates a bad user experience. Redundant security. UAC and windows vista anyone?

    That feature treats the user as an internet virgin. "You do know this stranger is potentially infected and bad for you?"

    Microsoft loves to treat their users as a children. Lie, cheat and even abuse us. Microsoft say: "It is for your own good. We know best. Now shut up and buy this new overpriced and crappy product!"

    Surprising that windows doesn't popup a message each time you use the web camera "This image/video can be stolen and uploaded online for everyone to see"

    Hmm. With image recognition tech: "Warning: This image contains nudity. Are you sure you want to save it?" or more realistic view on image recognition (it is always faulty, buggy): "Error: This image contains child-porn. Police have been notified!"

    Talking about wearing down the mouse. When will microsoft make click-fest metro optional for desktop users?

    I'm feeling violated and raped here, again. Isn't one apple enough?

  2. Brian_EE says:

    @Tess: Risking "feeding the troll", perhaps you'd be more at home with some Linux distro.

  3. Brian Friesen says:

    These prompts to before running downloaded files are so annoying that I decided to do something about it.  I discovered the underlying mechanism uses NTFS alternate streams to store the zone information.  So I wrote a program that traverses every file on the hard drive and deletes this alternate stream info thus unblocking all files in one action.  I was unaware of this IZoneIdentifier interface.  I'll have to modify my program to use this interface instead of going for the raw alternate stream.

  4. David Crowell says:

    Brian,

    Interesting.  I wonder what the underlying mechanism is on FAT32 volumes.

  5. Brian says:

    I think this "feature" only works on NTFS.  I know if you copy the file to FAT or burn to a CD, then copy back to NTFS the zone info is lost.  I haven't tried FAT32, but I suspect the zone info is lost there as well.

  6. Dan Bugglin says:

    @Tess That is not a Windows feature and I have never had that happen to me on any version of Windows.  I suspect a third-party installer or some other third-party shenanigans.

    In Windows 8/8.1, ScreenSmart or whatever it's called (SmartScreen?) will bypass the prompt for known good software, so it will not appear.  I've only had it pop up a few times myself since I installed the 8.1 preview back when it was released.  So it appears to work well in my experience.

  7. Miff says:

    IIRC, there was a Group Policy setting to disable this.

  8. DJUrsus says:

    I've got a file that doesn't respond to clicking to Unblock button.  The button does get grayed out, and I can then click OK to save the changes, but when I re-open the file properties, it's back, and running the program still causes the warning dialog to appear.  Does anyone have experience with this?

  9. Joshua says:

    Here we go again. Microsoft documented the API for a file format tag but not the format of the alternate data stream.

    This is bad behavior that MS will not stop.

  10. Jack says:

    Wow @Tess ("Microsoft is helping to kill mother nature", "Metro sucks, boo hoo") – troll alert! BTW, here's a handy tip for future rants: people/users get exasperated, situations get exacerbated.

    There is indeed a group policy for this and if you don't like the feature it takes all of a minute to Bing the steps and implement. Oh, and Chrome has now copied IE9+/Win8+'s zone id based SmartScreen App Reputation system.

    @Brian: So you effectively rewrote SysInternals' Streams utility?

  11. Jack says:

    Win8 also has a Control Panel option to turn off SmartScreen: http://i.imgur.com/yVRZawm.png

  12. morlamweb says:

    @Jack: my thoughts exactly.  If they're really annoyed by this feature, then why don't you search for the switch to turn it off rather than build an app to mess with the alternate data streams?  I'm reminded of Raymond's recent post about enumerating all GUIDs.  There's probably a simpler way to solve the "problem".  First, the Zone.Identifier is usually set only on files that you download from the web, not generally on system files, so searching through the whole filesystem seems like a waste of time.

    I view this dialog as a reminder to run the program through an anti-virus scanner before actually running the program.  I'm usually quite diligent in scanning for viruses and checking file hashes before running programs, but sometimes I forget.  This dialog is like a helpful last-minute reminder to run my security scans before letting a program loose on my system.

  13. ErikF says:

    @Tess: This has been identified as a serious problem for regular users. It's not just IE that does this BTW; Safari in OSX does this too, and for exactly the same reason: to prevent users from picking up drive-by viruses/malware!

    Congratulations if you are perfect and never get unintended downloads. I'm not, and the people who this feature was designed to protect aren't either.

  14. John says:

    The problem with features like this is that 99.9% of the time the behavior is unwanted.  Imagine if you had a bodyguard that asked you "Are you sure?" every time you did something.  Got out of bed, stepped into the shower, put on some clothes, went into the garage, got into the car, etc.  I don't think you would employ him very long.

  15. John says:

    Are you people in the habit of executing unknown files of unknown origin?  If so, I would argue PEBKAC.  If not, then this feature doesn't really help you.

  16. Brian says:

    Oh no… now you're going to get another "vulnerability report."

    LEETCORP REPORT

    Copyright LeetCorp, Inc, 2013.  All rights reserved.  LeetCorp must be cited in any reference to this vulnerability.

    Vulnerability:  If a user downloads my file, and then I run ZoneClearer.exe against the file, they will not get a Zone Identifier prompt when they double click the file.  This is a clear flaw in the Zone Identification mechanism.

    Marked as CLOSED by rchen:  Airtight Hatchway

  17. Nick says:

    While I agree that the Explorer prompt is less than helpful for most "power" users, the zone identifier is useful in some circumstances:

    1) A "normal" user who very rarely downloads executables, and the unexpected warning may prevent them from running CuteKitties.jpg.exe.  It might not help everyone, but if even 5% of Windows users are ever helped by the dialog then that's a still a very large number of people.

    2) As Raymond mentions, a program might treat files it opens differently if they're marked as coming from an untrusted zone.  Word, for example, disables editing (and probably some other things).  I think this is probably the primary motivation for the feature — a scaffold for other applications to make use of — and Explorer's dialog is really just an example of an implementation.

  18. rwilke says:

    CComPtr<IInternetSecurityManager> spism;

    spzi.CoCreateInstance(CLSID_InternetSecurityManager);

    Shouldn't that be:

    spism.CoCreateInstance(…

  19. Brian Friesen says:

    @Jack:  I did and I didn't rewrite SysInternals' Streams utility.  SysInternals Streams is a command line tool and removes all alternate file streams.  My utility is GUI, allows you to control which folder(s) to search in, and only remove zone identifier stream info – all other streams are left intact.  I wish I still had my personal website up, I would post the code for all to see and download.

  20. @Joshua says:

    Why should they be required to document the stream itself? I don't think you know what you're talking about.

  21. John says:

    Always showing file extensions by default would be more helpful against unintended execution than a dialog that most users will click through without reading.

  22. God says:

    99.9% of the time, you don't NEED to be wearing kevlar armour. You only need it when someone takes a shot at you. You can't just say 'sorry Mr Gunman, hang on a tick while I put on my kevlar armour'.

    Put another way: if there was a 1 in 1,000 chance I would be shot at, would I be wanting to be wearing kevlar armour? The answer is: hell, yes.

  23. Jesus says:

    @God

    Gosh, Dad… Since when do you need kevlar armour?

  24. ender says:

    > 2) As Raymond mentions, a program might treat files it opens differently if they're marked as coming from an untrusted zone.  Word, for example, disables editing (and probably some other things).

    A certain well-known PDF reader disables printing on untrusted files. I have no idea why.

  25. Ooh says:

    @ender: Never heard of printer viruses? Could be that the PDF contains sequences of malicious code that don't make sense to the viewer application, but use security vulnerabilities in the printer firmware to infect your network. When the content would simply be sent to the printer and the printer has a security flaw you'd be pwned (I'd say currently every single printer is vulnerable, because security hasn't been much of a concern with those devices till a few years ago).

  26. Fleet Command says:

    Since a lot of computer programs write zone identifier data without regards to one unified policy, I believe security-conscious people need a garbage collector to remove them en masse. Even if there is a policy in Windows to ignore them, the policy must enabled in all computers that use the file. What's the need? What's safe is safe anywhere until changed.

    As side note, I'd love Tess to take Brian EE's advice and grab a Linux distro… only to discover that Linux comes with sudo, a more heavy-handed version of UAC that can't exactly be disabled. (Mind you, I love both UAC and sudo.)

  27. Fleet Command says:

    @Ooh: There is no such thing in real life. You might see it in a bad sci-fi though.

  28. SD says:

    "…that Linux comes with sudo, a more heavy-handed version of UAC that can't exactly be disabled."

    The kind of people who hate UAC would probably just log in as root all the time.  

  29. ultramage says:

    @Fleet Command: Printer manufacturers like to do firmware updates by having users 'print' special document files with a firmware payload. They're most likely no crypto, just security by obscurity. Search 'printer malware' or 'print me if you dare' for examples of this being subverted by researchers.

  30. Marc K says:

    @The MAZZTer: I've had something similar happen to me, though I don't remember if it was a driver.  I downloaded the file, then unzipped it and the unzip utility copied the zone identifier to all the files.  When I was done, I was getting those popups from unexpected places while just trying to use the system.

    @morlamweb: What need is there to manually scan the file?  By the time it is executed, the typical user has inadvertently scanned it three times.  Once when it was written to disk during the download.  A second time when Explorer looked at it to list the directory.  Then a third time when it was actually executed.

    @Nick: No silly dialog will keep the normal user from trying to open up what he thinks is a cute kitties picture.  

  31. Ben says:

    @ender "A certain well-known PDF reader disables printing on untrusted files. I have no idea why."

    Because it by default runs the viewer as a (low-integrity?) sandboxed process which doesn't have permission to do anything much, including access the printer. If you choose "enable all features" it reopens the document as an unsandboxed process, and is then able to print.

  32. God says:

    That's between me and your mother, son. Now go play…

  33. Fleet Command says:

    @SD: True; but that's not the point. It does not happen before an "OMG! This OS too!?" attack. Whether they run as root, or return to Windows and disable UAC is irrelevant.

  34. morlamweb says:

    @Marc K: anti-virus or anti-malware programs (assuming that they're installed, are up-to-date, and the on-access scanner is enabled) will scan files as you describe.  But they don't, as a rule, verify checksums.  I make it a habit to verify the checksums on downloaded files (if I have a checksum to verify against), especially for larger files.  As for running it through a malware scanner: I guess it's a security blanket thing.  Seeing the "no problems found" message after a file scan brings a measure of comfort that silence doesn't.

  35. Medinoc says:

    The big problem with zones and web pages is that users (even programmers like me) have trouble wrapping their heads at the concept that a web page containing scripts is given more rights when it's on the computer than when it's on the web.

    What compounds the problem is that for long (I don't know if it's sill the case), the only choice when opening a web page with scripts was to either don't execute scripts at all, or execute the scripts in URLZONE_LOCAL_MACHINE. Why not provide an option to execute the script in URLZONE_INTERNET? And make this "just do as if it were still on the interwebs" option the default one, because it follows the principle of least astonishment for the average user that assumes "a web page is a web page".

    [You can tag your HTML with "The Mark of the Web" to get it to execute in the Internet zone even when local. Unfortunately it's too late to change the default behavior for compatibility reasons. -Raymond]
  36. Medinoc says:

    Oh, thanks for the info, I didn't know of that. I wonder how many browsers add it when saving pages (I just tested with Firefox, which doesn't). If it were systematically inserted by all browsers for page downloads, it would certainly close a big security hole.

  37. jrv says:

    I've been using a program called ZoneStripper (jameskovacs.com/…/zonestripper-updated) for years. I assume it works on the same information, but it may be implementation-dependent where I think yours is not. Even though I frequently remove the zone (most often for sample code), I prefer having it put on by default when I have a way of taking it off.

Comments are closed.