Part of my job involves reviewing how products and solutions use ACLs to protect resources such as files and registry entries. In some cases, the ACLs are poor and leave the protected resource open to attack. This month, I show you some best practices for determining secure ACLs for your resources.
What's an ACL?
An ACL is an access-control method that some OSs, including Windows 2000, employ to determine to what degree an account (e.g., user, computer) can access a resource. ACLs are made up of system ACLs (SACLs) and discretionary ACLs (DACLs). SACLs determine audit policy for secured resources. DACLs determine access rights to secured resources. All securable objects in Windows have owners; DACLs are called discretionary because the object owner decides who has access to the object. (See the sidebar "Setting DACLs the Easy Way," page 15, for information about predefined DACLs.)
Win2K resources that you can use DACLs to secure and SACLs to audit include files, registry keys, shared memory, named pipes, mutexes (i.e., mutual exclusions), and printers. Shared memory and named pipes are ways for applications to communicate with one another. Mutexes let multiple processes access shared data in a synchronous manner. For example, if two processes use shared memory to communicate, you can use a mutex to make sure that only one application writes to the in-memory data at a time.
DACLs and ACEs
Each DACL can include access control entries (ACEs). An ACE includes two major components: an account that the account's SID represents and a description of what that SID can do to this resource. A SID represents a user, a group, or a computer.
An empty DACL (i.e., a DACL with no ACEs) is a DACL for which no such access-control mechanism exists on the resource and to which no one has access. A NULL DACL isn't a DACL at all; I recommend that you never use a NULL DACL because attackers can set any access policy they choose on the object and possibly prevent your users from accessing the resource.
ACEs can be allow ACEs or deny ACEs. The OS orders ACEs so that it evaluates deny ACEs before allow ACEs. For example, in the ACE Everyone (Full Control), Everyone is the account (the SID for the Everyone account is S-1-1-0), and Full Control is the degree to which the account can access the resource in question. Any account can do anything to the resource. However, in the ACE Everyone (Deny Full Control), every account (including you, even if you're the administrator) is denied access to the resource. The OS evaluates Everyone (Deny Full Control) before Everyone (Full Control). If an attacker can set such a deny ACE on a resource, serious Denial of Service (DoS) threats exist. Fortunately, in such an event, you can take ownership of the object and change its DACL, but the damage might already have been done.
I've performed security reviews both inside and outside Microsoft, and I've found this rule invaluable: Account for every ACE in a DACL. If you can't determine why an ACE exists in a DACL, remove the ACE.
Determining Appropriate DACLs: Scenario 1
The process for defining access-control mechanisms is simple. Here are the points I follow:
- Determine the resources you use.
- Determine the business-defined access requirements.
- Determine the appropriate access-control technology.
- Convert the access requirements to the technology.
First, you need to determine what resources you want to protect. When you know the resources, you'll have a better chance of determining the DACLs you need to apply to protect the resource.
Next, you need to determine the access requirements. Recently, I had a meeting with a group that used Everyone (Full Control) on some crucial files that they owned. The rationale was that local users on the computer needed to access the files. After talking with team members a little more, the consensus was "All users at the computer must be able to read the data files." Note the italicized words. I use the italics to extract key words from the scenario to build business requirements. From the access business requirements, you can derive technical solutions—in this case, access requirements to derive DACLs.
I define access-control rules as "someone can perform something on some resource." In the previous example, "All users at the computer must be able to read the data files" translates into the ACE Interactive Users (Read) on the data files.
Interactive Users is semantically the same as All users at the computer, except in the case of Win2K Server Terminal Services and NT Server 4.0, Terminal Server Edition (WTS) users. If you decide that Terminal Services or WTS users also need access, you can add the ACE Remote Interactive User (Read). The Remote Interactive User group contains users who use Terminal Services or WTS to log on to the computer.
Determining Appropriate DACLs: Scenario 2
Let's look at a different example from a banking application. In this case, the scenario is updating a client's bank records. "The teller searches for, reads, then updates the client's account information with the new balance; an audit entry is written to the audit log. Administrators and auditors can read the audit log." (After talking with the users, you determine that in this case, search is the same as read.) From this statement, you can derive this access policy for the client account data:
- Tellers (Read, Update)
You derive this access policy for the audit log:
- Auditors (Read)
- Administrators (Read)
- Tellers (Write)
In this example, Tellers, Auditors, and Administrators can be groups.
The scenario-based approach to access-control policy that I've described is implementation independent. For example, you might choose to have a trigger or rule on a Microsoft SQL Server table determine the implementation of a policy. The trigger could fire when a user who isn't in the Auditors group attempts to insert, update, or delete data in an audit log table. Because the user isn't in the Auditors group, the transaction is rolled back (i.e., the transaction doesn't occur). The code in Web-exclusive Listing 1 sets such a SQL Server trigger.
Simply put, determining the correct access-control policy for a resource is a straightforward task. Write out what the business requirements are when the users concerned access the resource. Pick out the verbs and nouns from the sentences. The nouns determine the users and resources; the verbs determine the access policy.
Your Last Line of Defense
You must always set the appropriate DACLs on all resources you create. Everyone (Full Control) is simply too dangerous, and you should avoid it. Also, I recommend that you not rely on default SACLs: Don't assume that the default SACL is good enough for your application.
Remember that when you're under attack, in most cases ACLs are your last line of defense. (Encryption is another last line of defense.) If all your security technologies have failed to protect your assets, the ACLs must protect the resources.
Note: Use the Force application termination setting with care if you let users access mission-critical applications from your kiosk machines. Killing an application without properly saving its state might result in data loss.