Welcome to MSDN Blogs Sign in | Join | Help

If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

One of the predefined security access masks is STANDARD_RIGHTS_REQUIRED. You see it used in defining the _ALL_ACCESS masks for various objects. Here are just a few examples:

#define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
                                   0xFFF)
#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)

The STANDARD_RIGHTS_REQUIRED mask is meant to be used when defining access masks for object types. I'm guessing it's called STANDARD_RIGHTS_REQUIRED because it's the set of access masks that all securable objects must support. Look at the documentation or just at the definition:

#define DELETE                           (0x00010000L)
#define READ_CONTROL                     (0x00020000L)
#define WRITE_DAC                        (0x00040000L)
#define WRITE_OWNER                      (0x00080000L)

#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)

Notice that STANDARD_RIGHTS_REQUIRED is just an abbreviation for the union of the four access bits DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER.

Now that you see what it's for, you can also see what it's not for: You're not expected to pass it as the mask of requested access bits when you attempt to open an object. In other words, the following is wrong:

// wrong!
HANDLE hProcess =
    OpenProcess(dwProcessId, FALSE,
                STANDARD_RIGHTS_REQUIRED | PROCESS_QUERY_INFORMATION);

The person writing this code probably thought, "Well, I just want to be able to query information, so I need to pass PROCESS_QUERY_INFORMATION. There's this other thing here called STANDARD_RIGHTS_REQUIRED; since it's required, I'll pass that too."

The "required"ness of STANDARD_RIGHTS_REQUIRED doesn't apply to you, the program opening the object. It applies to the person who is designing the object.

Your attempt to be a "good security citizen" and ask only for the access you need (namely, PROCESS_QUERY_INFORMATION) has backfired due to the addition of STANDARD_RIGHTS_REQUIRED. If you ask for STANDARD_RIGHTS_REQUIRED, you are asking for everything.

Why is that? Notice that STANDARD_RIGHTS_REQUIRED includes WRITE_DAC. If you have WRITE_DAC permission, that means that you have permission to change the security descriptor on the object, at which point you totally 0wnz0r it. You want PROCESS_VM_WRITE access but the security descriptor doesn't let you? No problem. Just set a new security descriptor that grants you PROCESS_ALL_ACCESS to the process object. Tada! You now have all the access in the world.

Moral of the story: Don't ask for STANDARD_RIGHTS_REQUIRED, because only somebody with full control will be able to get it. Ask for what you actually want.

Published Wednesday, February 27, 2008 7:00 AM by oldnewthing
Filed under:

Comments

# Think about it...

Wednesday, February 27, 2008 10:34 AM by Matt Green

While I understand that users of the API would think they need to pass that in because of the name, a little bit of critical thinking reveals otherwise. If it was really required to be passed in, omitting it would cause the function to return and set the invalid parameter error code.

Keeping a tiny little solution off to the side for these sorts of 'experiments' is invaluable.

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 11:08 AM by random poster

You know you've been reading http://www.crazyontap.com for too long when A) you read the thread title as "...you may as well ask for the moron"; and B) you substitute in the obligatory 18 in your head.

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 11:22 AM by Medinoc

One of the culprits is the wording of the documentation. This extract comes from the DuplicateHandle() page:

In addition to STANDARD_RIGHTS_REQUIRED, the following access rights can be specified in the dwDesiredAccess parameter for the different object types:

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 12:22 PM by M

"One of the culprits is the wording of the documentation."

Exactly. I used to always take that to mean, "STANDARD_RIGHTS_REQUIRED must be combined with whatever other access rights you specify."

Good to know I wasn't the only one. :)

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 1:05 PM by Niels

#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)

I like how the constant pretty much spells out "FOOL" :)

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 1:16 PM by Yuhong Bao

>I like how the constant pretty much spells out "FOOL" :)

Funny isn't it? The L, BTW, stands for "long".

STANDARD_RIGHTS_REQUIRED, BTW, illustrates the disadvantages of designing from the author's prescriptive of the word "required".

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 1:16 PM by Yuhong Bao

>I like how the constant pretty much spells out "FOOL" :)

Funny isn't it? The L, BTW, stands for "long".

STANDARD_RIGHTS_REQUIRED, BTW, illustrates the disadvantages of designing from the author's prescriptive of the word "required".

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 3:06 PM by anonymous

I'm waiting for the day when they'll replace STANDARD_RIGHTS_REQUIRED with MAXIXUM_ALLOWED for some of the XXX_ALL_ACCESS constants, which would  instantly fix all LUA problems with the CreateXXX() routines.

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 7:50 PM by SERVICE_ALL_ACCESS

Hmmmmm, whoops... this was a very timely post!

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Wednesday, February 27, 2008 8:38 PM by Igor Levicki

That is easily solved with the following define:

#define GIVE_ME_ALL_POSSIBLE_ACCESS_INSTANTLY_OR_I_WILL_REBOOT_YOU_AND_THIS_TIME_I_MEAN_IT 0xFFFFFFFFL

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Friday, February 29, 2008 8:52 PM by dcook

Well, STANDARD_RIGHTS_REQUIRED isn't really MAXIMUM_ALLOWED. Basically, it is the set of all permissions that an object must understand. Some objects understand other permissions in addition to the ones specified in STANDARD_RIGHTS_REQUIRED. For example, a file could have a permission bit for setting attributes, which doesn't make sense for registry keys, and the registry could have a permission bit for enumerating values, which doesn't make sense for a file. The mapping between the standard rights and the object-specific rights always gives me a headache.

As far as asking for the moon, it's always good to cite prior implementations. http://www.putty.nl/wishlist/moon-on-stick.html

# re: If you ask for STANDARD_RIGHTS_REQUIRED, you may as well ask for the moon

Sunday, March 02, 2008 10:43 AM by CPM

That putty link is a giggle!

# Changing Printer settings using the Windows API | Lessan Vaezi

New Comments to this post are disabled
 
Page view tracker