Attacking Access Controls

Common Vulnerabilities

Access controls can be divided into two broad categories: vertical and horizontal. Vertical access controls allow different types of users to access different parts of the application’s functionality. In the simplest case, this typically involves a division between ordinary users and administrators. In more complex cases, vertical access controls may involve fine-grained user roles granting access to specific functions, with each user being allocated to a single role, or a combination of different roles.

Horizontal access controls allow users to access a certain subset of a wider range of resources of the same type. For example, a web mail application may allow you to read your email but no one else’s; an online bank may let you transfer money out of your account only; and a workflow application may allow you to update tasks assigned to you but only read tasks assigned to other people.

In many cases, vertical and horizontal access controls are intertwined. For example, an enterprise resource planning application may allow each accounts payable clerk to pay invoices for a specific organizational unit and no other. The accounts payable manager, on the other hand, may be allowed to pay invoices for any unit. Similarly, clerks may be able to pay invoices for small amounts, while larger invoices must be paid by the manager. The finance director may be able to view invoice payments and receipts for every organizational unit in the company but may not be permitted to pay any invoices at all.

Access controls are broken if any user is able to access functionality or resources for which he is not authorized. There are two main types of attack against access controls, corresponding to the two categories of control:

■ Vertical privilege escalation occurs when a user can perform functions that their assigned role does not permit them to. For example, if an ordinary user can perform administrative functions or a clerk is able to pay invoices of any size, then access controls are broken.

■ Horizontal privilege escalation occurs when a user can view or modify resources to which he is not entitled. For example, if you can use a web mail application to read other people’s email, or if a payment clerk can process invoices for an organizational unit other than his own, then access controls are broken.

It is common to find cases where a vulnerability in the application’s horizontal separation of privileges can lead immediately to a vertical escalation attack. For example, if a user finds a way to set a different user’s password, then the user can attack an administrative account and take control of the application.

Completely Unprotected Functionality

In many cases of broken access controls, sensitive functionality and resources can be accessed by anyone who knows the relevant URL. For example, there are many applications in which anyone who visits a specific URL is able to make full use of its administrative functions:
“https://wahh-app.com/admin/”

In this situation, the application typically enforces access control only to the following extent: users who have logged in as administrators see a link to this URL on their user interface, while other users do not. This cosmetic difference is the only mechanism in place to “protect” the sensitive functionality from unauthorized use.

Sometimes, the URL that grants access to powerful functions may be less easy to guess, and may even be quite cryptic, for example:
“https://wahh-app.com/menus/secure/ff457/DoAdminMenu2.jsp”

Here, access to administrative functions is protected by the assumption that an attacker will not know or discover this URL. The application is harder for a complete outsider to compromise, because they are less likely to guess the URL by which they can do so.

In some applications where sensitive functionality is hidden behind URLs that are not trivial to guess, an attacker may often be able to identify these via close inspection of client-side code. Many applications use JavaScript to build the user interface dynamically within the client. This typically works by setting various flags regarding the user’s status, and then adding individual elements to the UI on the basis of these. For example:

var isAdmin = false;

if (isAdmin)
{
adminMenu.addItem(“/menus/secure/ff457/addNewPortalUser2.jsp”,
“create a new user”);
}

Here, an attacker can simply review the JavaScript to identify URLs for administrative functionality and attempt to access these. In other cases, HTML comments may contain references to or clues about URLs that are not linked from on-screen content.

Identifier-Based Functions

When a function of an application is used to gain access to a specific resource, it is very common to see an identifier for the requested resource being passed to the server in a request parameter, either within the URL query string or the body of a POST request. For example, an application may use the following URL to display a specific document belonging to a particular user:
“https://wahh-app.com/ViewDocument.php?docid=1280149120”

When the user who owns the document is logged in, a link to this URL is displayed on the user’s My Documents page. Other users do not see the link. However, if access controls are broken, then any user who requests the relevant URL may be able to view the document in exactly the same way as the authorized user.

Multistage Functions

Many kinds of functions within an application are implemented across several stages, involving multiple requests being sent from the client to the server. For example, a function to add a new user may involve choosing this option from a user maintenance menu, selecting the department and user role from drop down lists, and then entering the new username, initial password, and other information.

It is common to encounter applications in which efforts have been made to protect this kind of sensitive functionality from unauthorized access but where the access controls employed are broken because of flawed assumptions about the ways in which the functionality will be used.

In the previous example, when a user attempts to load the user maintenance menu, and chooses the option to add a new user, the application may verify that the user has the required privileges, and block access if the user does not. However, if an attacker proceeds directly to the stage of specifying the user’s department and other details, there may be no effective access control. The developers unconsciously assumed that any user who reaches the later stages of the process must have the relevant privileges because this was verified at the earlier stages. The result is that any user of the application can add a new administrative user account, and thereby take full control of the application, gaining access to many other functions whose access control is intrinsically robust.

The authors have encountered this type of vulnerability even in the most security-critical web applications, those deployed by online banks. Making a funds transfer in a banking application typically involves multiple stages, partly to prevent users from accidentally making mistakes when requesting a transfer. This multistage process involves capturing different items of data from the user at each stage. This data is strictly checked when first submitted and then is usually passed to each subsequent stage, using hidden fields in an HTML form. However, if the application does not revalidate all of this data atthe final stage, then an attacker can potentially bypass the server’s checks. For example, the application might verify that the source account selected for the transfer belongs to the current user and then ask for details about the destination account and the amount of the transfer. If a user intercepts the final POST request of this process and modifies the source account number, she can execute a horizontal privilege escalation and transfer funds out of an account belonging to a different user.

Static Files

In the majority of cases, users gain access to protected functionality and resources by issuing requests to dynamic pages that execute on the server. It is the responsibility of each such page to perform suitable access control checks,
and confirm that the user has the relevant privileges to perform the action that they are attempting.

However, in some cases, requests for protected resources are made directly to the static resources themselves, which are located within the web root of the server. For example, an online publisher may allow users to browse its book catalog and purchase ebooks for download. Once payment has been made, the user is directed to a download URL like the following:
“https://wahh-books.com/download/0636628104.pdf”

Because this is a completely static resource, it does not execute on the server, and its contents are simply returned directly by the web server. Hence, the resource itself cannot implement any logic to verify that the requesting user has the required privileges. When static resources are accessed in this way, it is highly likely that there are no effective access controls protecting them and that anyone who knows the URL naming scheme can exploit this to access any resources they desire. In the present case, the document name looks suspiciously like an ISBN, which would enable an attacker to quickly download every ebook produced by the publisher!

Certain types of functionality are particularly prone to this kind of problem, including financial web sites providing access to static documents about companies such as annual reports, software vendors who provide downloadable binaries, and administrative functionality that provides access to static log files and other sensitive data collected within the application.

Insecure Access Control Methods

Some applications employ a fundamentally insecure access control model in which access control decisions are made on the basis of request parameters submitted by the client. In some versions of this model, the application determines a user’s role or access level at the time of login and from this point onwards transmits this information via the client in a hidden form field, cookie, or preset query string parameter (see Chapter 5). When each subsequent request is processed, the application reads this request parameter and decides what access to grant the user accordingly. For example, an administrator using the application may see URLs like the following:
“https://wahh-app.com/login/home.jsp?admin=true”

while the URLs seen by ordinary users contain a different parameter, or none at all. Any user who is aware of the parameter assigned to administrators can simply set it in his own requests and thereby gain access to administrative functions.

This type of access control may sometimes be difficult to detect without actually using the application as a high-privileged user and identifying what requests are made. The techniques described in previous article for discovering hidden request parameters may be successful in discovering the mechanism when working only as an ordinary user.

In other unsafe access control models, the application uses the HTTP Referer header as the basis for making access control decisions. For example, an application may strictly control access to the main administrative menu, based on a user’s privileges. But when a user makes a request for an individual administrative function, the application may simply check whether this request was referred from the administrative menu page and assume that, if so, then the user must have accessed that page and so have the required privileges. This model is fundamentally broken, of course, because the Referer header is completely within the control of the user and can be set to any value at all.


NEXT is..Attacking Access Controls.,..,.,.,,.,.,..,.