Null and Empty Discretionary Access Controls
This is a past investigation I shared on another blog years ago. Security descriptors seem like a simple concept; yet they can be quite confusing. IT professionals learn about security descriptors differently from developers. For a developers, its fairly straightforward-- they're only interested in the permission they need to perform an action. Developers need not worry about effective permissions. However, IT professionals need to be concerned about effective permissions because they need to ensure that the effective permissions result in the proper access for the all the right users.
Below, I discuss a rather esoteric scenario with access control that may not be widely known or understood. Mainly because the ACL editor goes through great effort to prevent this scenario from occurring. However, access control is accomplished by an API, so while the ACL editor tries to prevent the scenario, other applications can easily create it... If you think this is interesting, wait until I can figure out how to write about canonical access control entry ordering to where it doesn't have as many installments as Star Wars.
Background
Windows uses the concept of a security descriptor to allow or deny security principals (user or groups) access to specific resources. A security descriptor is a data structure that contains:
- The memory location of a security identifier of a security principal that owns the objects.
- The memory location of a security identifier of a group owner (for interoperability with POSIX subsystems).
- The memory location of a discretionary access control list (DACL).
- The memory location of a system access control list (SACL).
An access control list (ACL) is a list of memory locations to access control entries (ACEs). An ACE contains information such as
- an action
- is the action allowed or denied
- and the security principal to which the allowed or denied action applies.
ACEs are mostly commonly referred to as permissions. Windows uses discretionary access control lists to prevent or allow actions against resources for a specific user and/or group. Windows uses system access control lists to audit actions performed against an object by a specific user or group.
What is an empty DACL
The DACL controls that type of access for a given action to a resource and who can perform that action. Windows allocates memory when creating a DACL. The security descriptor stores the memory location of the DACL. Windows uses the DACL memory location to identify where it should store the location of ACEs associated with the DACL. Therefore, the DACL exists but is empty and remains empty until an ACE is created and assigned to the DACL. This is an empty DACL.
What is a null DACL
A null DACL is often confused with an empty DACL; however, they're different. As mentioned earlier, the security descriptor contains the memory location of the DACL when a DACL is created. However, it is possible to create a security descriptor without the memory location of the DACL. The security descriptor is valid; however, the memory location of the DACL does not exist; it is null. This means that Windows did not create a DACL. This also means that it is not possible to add an access control entry to the DACL until the DACL is created and a valid memory location is provided in the security descriptor.
How Windows handles null and empty DACLs
Windows’ security defines two specific actions with regard to handling a null or empty DACL. These actions occur when Windows performs an access check. An access check occurs when a user attempts access to a resource and on the computer hosting the resource.
With a null DACL, Windows checks the access token created on the resource computer with the security descriptor protecting the resource. Windows grants full access to any requesting user, bypassing any further security checks. The resulting effects of a null DACL is similar to granting the Everyone group Full Control permissions.
An empty DACL provides the opposite effect of a null DACL. An empty DACL is similar to denying Full Control permissions to the Everyone group; effectively preventing anyone from accessing the resource. It’s important to understand that Windows only accommodates null or empty DACLs during the access check; not when the null or empty DACL is saved to the security descriptor.