Basic Authentication over HTTPS – A Recipe for Disaster

Background

 

The idea of middleware services has been around for a while, but in different incarnations. It started out as CORBA, then moved to Web Services and finally REST. Although REST gets most of its publicity from startups exposing application-specific APIs through public interfaces, larger and more established companies are using REST for unifying backend systems. For example, instead of having multiple views of customer information in different systems (CRM, Salesforce.com, Oracle ERP, authorization, etc.) you have a single source of truth that exposes customer information to different applications through a REST API.

 

The benefits are enormous in comparison to CORBA or proprietary Web Service APIs. You don’t need to learn a differing set of APIs across different languages. You don’t have to worry about compatibility issues. Everything happens over HTTP and nearly all languages support HTTP out of the box. The semantics of interacting with REST services are the same regardless of the client language and compatibility issues are almost negligible. You would think that you have come up with the ideal solution but lets look into it further.

 

Problem

 

Authentication is required when accessing backend systems (systems running on a secured network which only application servers have access to). The documentation of many of the REST client APIs suggests the use of Basic Authentication over HTTPS. Basic authentication allows for two ways of embedding of credentials in the REST request. 

 

The first is as a base64-encoded header as shown in the following sample code:

 

URL url = new URL(“https://alm_url/qcbin/authentication-point/authenticate”);

URLConnection uc = url.openConnection();


String val = (new StringBuffer("username").append(":").append("password")).toString();


byte[] base = val.getBytes();

String authorizationString = "Basic " + new String(new Base64().encode(base));

uc.setRequestProperty ("Authorization", authorizationString);

InputStream in = url.openStream();

 

The second is directly in the URL. The following sample code exemplifies this case:

 

//From application code contacting the server
response = RestClient.get “https://#{@user_name}:#{@user_password}@alm_url/qcbin/authentication-point/authenticate”

 

Which do you think developers will use and do you see the problem?

 

 

If you don’t see it, let me help you out. First, note that:

 

@user_name is typically something created by the user (untrusted).

 

Notice how the second sample code example points to some type of authentication REST service. If a disgruntled insider knows the format of the authentication information provided by the REST service, he could fool the application into contacting a malicious server instead of the backend server, which could in turn return full admin rights.

 

This would permit the attacker to create usernames of the form:

 

www.someserver.com#x=
www.someserver.com?x=
www.someserver.com;x=

 

Then the request from the second code example above would look produce the following:

 

response = RestClient.get “https://www.someserver.com;x=:zzz@alm_url/qcbin/authentication-point/authenticate

 

The request would go to the hacker’s server instead of the intended one and would return:

 

{

            “roles”: [“Admin”]

}

 

Now, the insider would be allowed into the application with full admin privileges. If you think this was a contrived example, you will be surprised to know that the URL above was taken directly from a discussion list posting.

 

In order to leverage Fortify to identify this problem in selected REST clients, look for relevant findings in Resource Injection or Open Redirect categories depending on the client used.

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.