Session Puzzling Attacks (a.k.a. “Session Variable Overloading”)

In this article we’re going to take a look at so-called “Session Puzzling Attacks”. The reference to session “puzzling” comes from the meaning of puzzle as in to mislead or confound – in this case, a way of confusing session handling mechanisms such that they can be manipulated or tricked into making incorrect security decisions relating to a client. The alternative name of “session variable overloading” provides a little bit more context about how this vulnerability is typically introduced into a web application – through developers “overloading” the usage of variables used within session objects such that multiple mechanisms rely on a single underlying variable and yet interpret it differently within different application contexts.

This description doesn’t really explain much in and of itself however, so in this article we’re going to step through a full explanation of typical session handling mechanisms, how the vulnerability can arise within them, and how to prevent vulnerabilities of this class.

 

Establishing State in a Stateless Protocol

To understand session puzzling attacks, it’s necessary to understand the most common pattern used in classic web applications for session handling. Developers of web applications face a fundamental challenge in that the underlying protocol used for communication between clients and servers (HTTP) is stateless. This means that it does not require the server to track the state of clients or to establish the context of individual requests within a broader set of communications – each request is essentially stand-alone and unlinked to earlier or later requests. This means that HTTP does not provide a native mechanism for servers to retain session information or status about each user connection across the duration of multiple requests.

 

client server request response diagram

However, servers require knowing the context of an individual request, in order to make business logic decisions such as “is this request from a user that is logged in and should the request for access to this resource be authorised?”  A naive solution to this may be to send authentication details with every single request. It is not practicable for a server to require that a user re-authenticates each request with a username and password manually, this would get incredibly frustrating for users, but an early solution was to use a mechanism known as Basic Authentication (also basic access authentication) which embeds credentials (base64 encoded) in every request as an HTTP request header:

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

 

server workstation connection diagram

However, this mechanism does not provide advanced session management functionality such as logout, or storage of custom variables within a session object.

 

Session Tokens & Cookies

The idea behind session management is to put requests from the same client in the same context. The most common solution to full session management in classic web applications therefore involves the establishment of a session store at the server side. This is done by issuing an identifier on the server and sending it to the client, then the client would save this identifier and resend it in subsequent requests so the server can identify it. Each session is uniquely identified with a sessionID. The session ID is typically transmitted as a session token to a browser within a “cookie” that can be stored within the local browser and submitted automatically on future requests to preserve state across multiple requests.

 

Session Token Generation

The session management flow is therefore:

  1. The browser makes an initial request to the server;
  2. The server recognises a new request without existing context (session) and generates a new session identifier;
  3. The server stores the session identifier server-side in a session store, linking it to at least sufficient information to “associate” the browser instance with the memory allocation;
  4. The cookie is sent to the client using the Set-Cookie HTTP response header;
  5. The client send the cookie back with every subsequent request to establish the request as being related to a given session;
  6. Cookies are read by the server by parsing the Cookie HTTP request header, and the request interpreted within existing session context.

 

This flow is illustrated below:

 

Session Token Generation diagram

On the server side, the session object will commonly tie to a specific user ID, however it may track additional information such as session state (active, timed out), authentication state (authenticated, unauthenticated), as well as a range of associated memory properties such as flags, identities, and browser instance specific data. Each session object can therefore be relatively complex. Represented in serialised form using JSON, a session object could like something like the below in a given instance:

 

{
“session_id”: 123456,
“userID”: “golden33”,
“null”: null,
“accountID”: 9876565,
“properties”: {
“property1”: “b”,
“property2”: “d”
},
“name”: “Daniel”,
“authenticated”: true
}

 

What can go wrong?

Now that we’ve delved into session objects, we’re in a better position to understand how session puzzling vulnerabilities can occur, when an application makes an incorrect determination of state by incorrectly populating or examining a session object property. This can typically take one of three forms, either:

  1. Via the premature population of session objects with incorrect or unsafe default values; (for example in the above object form by populating the authenticated property by default as true rather than false or null; or
  2. Via sharing a session variable or property between two distinct methods or functions, each of which interprets it differently and hence make inconsistent security decisions; or
  3. Via the unsafe inclusion of input from the user in populating a session variable.

 

Such confusions can typically be exploited simply by browsing resources and performing functions on the website in a specific sequence, in which an earlier operation sets up the session variable, and then a later operation makes a decision based on a property of the session variable set in the earlier operation.

As an example, imagine a scenario in which a password-reset form on a website requests a username be entered. An attacker requests a password reset for an account that is valid, but to which they are no the owner and should not be permitted access. The website safely handles the password reset request, not notifying the attacker of the password but rather emailing a password reset link to the registered user email address. So far, so fine.

However, a vulnerable session handling mechanism may assign a session object to the attacker performing the password reset request, and tie that session ID to the userID being requested to have the password reset. If a secondary page, such as a hypothetical “myAccount” page on the same web application, simply checks that the userID in the attacker’s cookie matches the user ID for the requested resource, the attacker may be able to gain access to the user’s accounts, by having done nothing more than access several resources in a certain sequence.

 

Username session memory diagram

What has happened here is that an attacker has exploited the session variable overloading within the web application to bypass authentication enforcement mechanisms, by finding a webpage that makes an unsafe decision based on the existence of a session variable that contains an identity–related value, which should only be stored or set in the session object after a successful authentication by the user. That is, an attacker first accesses a location in the application that sets session context and then accesses privileged locations that examine this context.

 

What are the Risks?

The risks can be substantial, and can bypass authentication. Since the vulnerability relies on the ability of an attacker to directly set a session token, it also enables them to bypass protection measures such Two Factor Authentication (2FA).

Since the attacker has not performed any malicious actions, only performing valid and official functionality known as a “valid behaviour pattern”, and exploiting business logic, they will also typically be able to avoid detection via SIEM mechanisms etc., and would be able to gain control over a valid account without sending any malicious input.

 

What applications are vulnerable?

Examples have historically been seen in banks and insurance companies, with high profile examples reported against Oracle E-Business Suite, and the Sony PlayStation Network. However all web servers, application servers, and web application environments are potentially susceptible to session variable overloading.

The most effective way to detect these vulnerabilities is to enumerate all of the session variables used and in which context they are valid, in practice this can only be effectively done via a source code review.

 

Mitigation

The primary mitigation would be to avoid storing any unnecessary values in the session object on the server side. However this would impact functionality and is not generally an option. If so, then the best mitigation possible is to ensure that:

  1. New instances of session objects are safely created in that all variables are initiated to correct and safe values
  2. That session variables where they exist are only used for a single consistent purpose within a single function, and not shared across different functions.
  3. That user and admin sessions are handled separately and not from a common session handling mechanism, as well as respected within different network-level contexts ideally (e.g. via IP source restriction) in order to minimise potential consequence of a session overloading attack from compromising administrative accounts
  4. Ensure that user-provided input is never used to populate session variables, and that all session variables passed in from any other module or source (rather than created by the session handling mechanism internally) are strictly validated

 

 

How can AppCheck Help?

AppCheck help you with providing assurance in your entire organisation’s security footprint. AppCheck performs comprehensive checks for a massive range of web application vulnerabilities from first principle to detect vulnerabilities in in-house application code. AppCheck also draws on checks for known infrastructure vulnerabilities in vendor devices and code from a large database of known and published CVEs. The AppCheck Vulnerability Analysis Engine provides detailed rationale behind each finding including a custom narrative to explain the detection methodology, verbose technical detail and proof of concept evidence through safe exploitation.

 

Additional Information

As always, if you require any more information on this topic or want to see what unexpected vulnerabilities AppCheck can pick up in your website and applications then please get in contact with us: info@appcheck-ng.com

Get started with Appcheck

No software to download or install.
Contact us or call us 0113 887 8380

Start your free trial