HTTP Verb Tampering in ASP.NET

We’re only a few days into 2016, and it didn’t take long for me to see a web application vulnerability that has been documented for over 10 years: HTTP Verb Tampering. This vulnerability occurs when a web application responds to more HTTP verbs than necessary for the application to properly function. Clever attackers can exploit this vulnerability by sending unexpected HTTP verbs in a request (e.g. HEAD or a FAKE verb). In some cases, the application may bypass authorization rules and allow the attacker to access protected resources. In others, the application may display detailed stack traces in the browser and provide the attacker with internal information about the system.

This issue has been recognized in the J2EE development stack for many years, which is well supported by most static analysis tools. But, this particular application wasn’t using J2EE. I’ve been doing static code analysis for many years, and I must admit – this is the first time I’ve seen this issue in an ASP.NET web application. Let’s explore this verb tampering scenario and see what the vulnerability looks like in ASP.NET.

Authorization Testing
Consider the following example. A web page named “DeleteUser.aspx” accepts one URL parameter called “user”. Logging in as an “Admin”, the following snippet shows a simple GET request to delete the user account for “bob”. In this example, the application correctly returns a 200 OK response code telling me the request was successful.

[sourcecode]
GET /account/deleteuser.aspx?user=bob HTTP/1.1
Host: localhost:3060
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: .ASPXAUTH=0BD6E325C92D9E7A6FF307BBE3B4BA7E97FB49B44B518D9391A43837DE983F6E7C5EC42CD6AB5
Connection: keep-alive
[/sourcecode]

Obviously, this is an important piece of functionally that should be restricted to privileged users. Let’s test the same request again, this time without the Cookie header. This makes an anonymous (i.e. unauthenticated request) to delete the user account for “bob”. As expected, the application correctly returns a 302 response code to the login page, which tells me the request was denied.

[sourcecode]
GET /account/deleteuser.aspx?user=bob HTTP/1.1
Host: localhost:3060
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
[/sourcecode]

Similarly, I logged in as a non-admin user and tried the same request again with the non-admin’s cookie. As expected, the application responds with a 302 response code to the login page. At this point, the access control rules seem to be working perfectly.

Hunt the Bug
During the security assessment, I noticed something very interesting in the application’s web.config file. The following code example shows the authorization rule for the delete user page. Can you find the vulnerability in this configuration?

[sourcecode]
<location path=”DeleteUser.aspx”>
<system.web>
<authorization>
<allow roles=”Admin” verbs=”GET” />
<deny users=”*” verbs=”GET” />
</authorization>
</system.web>
</location>
[/sourcecode]

Recognizing this vulnerability requires an understanding of how the ASP.NET authorization rules work. The framework starts at the top of the list and checks each rule until the first “true” condition is met. Any rules after the first match are ignored. If no matching rules are found, the framework’s default allow all rule is used (e.g. <allow users=”*” />).

In the example above, the development team intended to configure the following rules:

  • Allow users in the “Admin” role access to the “DeleteUser.aspx” page
  • Deny all users access to the “DeleteUser.aspx” page
  • Otherwise, the default rule allows all users

But, the “verbs” attribute accidentally creates a verb tampering issue. The “verbs” attribute is a rarely used feature in the ASP.NET framework that restricts each rule to a set of HTTP verbs. The configuration above actually enforces the following rules:

  • If the verb is a GET, then allow users in the “Admin” role access to the “DeleteUser.aspx” page
  • If the verb is a GET, then deny all users access to the “DeleteUser.aspx” page
  • Otherwise, the default rule allows all users

Verb Tampering

Now that we know what the authorization rules actually enforce, are you wondering the same thing I am? Will this web site really allow me to delete a user if I submit a verb other than GET? Let’s find out by submitting the following unauthenticated request using the HEAD verb. Sure enough, the server responds with a 200 OK response code and deletes Bob’s account.

[sourcecode]
HEAD /account/deleteuser.aspx?user=bob HTTP/1.1
Host: localhost:3060
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
[/sourcecode]

For what it’s worth, we could also submit the following POST request with any parameter and achieve the same result. Both verbs bypass the broken authorization rules above.

[sourcecode]
POST /account/deleteuser.aspx?user=bob HTTP/1.1
Host: localhost:3060
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 3

x=1
[/sourcecode]

Secure Configuration
Luckily for our development team, the HTTP verb tampering issue is very simple to correct. By removing the “verb” attributes in the new configuration shown below, ASP.NET enforces the access control constraints for all HTTP verbs (e.g. GET, POST, PUT, DELETE, HEAD, TRACE, DEBUG).

[sourcecode]
<location path=”DeleteUser.aspx”>
<system.web>
<authorization>
<allow roles=”Admin” />
<deny users=”*” />
</authorization>
</system.web>
</location>
[/sourcecode]

It is also a best practice to also disable HTTP verbs that are not needed for the application to function. For example, if the application does not need PUT or DELETE methods, configure the web server to return a 405 Method Not Allowed status code. Doing so will reduce the likelihood of HTTP verb tampering vulnerabilities being exploited.

It should be noted that the sample tests in this blog were run against ASP.NET 4.5 and IIS 8.0. Older versions may react differently, but the fundamental problem remains the same.

To learn more about securing your .NET applications, sign up for DEV544: Secure Coding in .NET!

References:
[1] http://www.kernelpanik.org/docs/kernelpanik/bme.eng.pdf
[2] http://www.aspectsecurity.com/research-presentations/bypassing-vbaac-with-http-verb-tampering
[3] http://www.hpenterprisesecurity.com/vulncat/en/vulncat/java/http_verb_tampering.html
[4] https://msdn.microsoft.com/en-us/library/8d82143t(vs.71).aspx

About the Author
Eric Johnson (Twitter: @emjohn20) is a Senior Security Consultant at Cypress Data Defense, Application Security Curriculum Product Manager at SANS, and a certified SANS instructor. He is the lead author and instructor for DEV544 Secure Coding in .NET, as well as an instructor for DEV541 Secure Coding in Java/JEE. Eric serves on the advisory board for the SANS Securing the Human Developer awareness training program and is a contributing author for the developer security awareness modules. Eric’s previous experience includes web and mobile application penetration testing, secure code review, risk assessment, static source code analysis, security research, and developing security tools. He completed a bachelor of science in computer engineering and a master of science in information assurance at Iowa State University, and currently holds the CISSP, GWAPT, GSSP-.NET, and GSSP-Java certifications.

ASP.NET MVC: Using Identity for Authentication and Authorization

Guest Editor: Today’s post is from Taras Kholopkin. Taras is a Solutions Architect at SoftServe, Inc. In this post, Taras will take a look at the authentication and authorization security features built into the ASP.NET MVC framework.

Implementing authentication and authorization mechanisms into a web application with a powerful ASP.NET Identity system has become a trivial task. The ASP.NET system was originally created to satisfy membership requirements, covering Forms Authentication with a SQL Server database for user names, passwords and profile data. It now includes a more substantial range of web application data storage options.

One of the advantages of the ASP.NET system is its two-folded usage: it may be either added to an existing project or configured during the creation of an application. ASP.NET Identity libraries are available through NuGet Packages, so they may be added to existing project via NuGet Package Manager by simply searching for Microsoft ASP.NET Identity.

Configuration during creation of an ASP.NET project is easy. Here’s an example:

Creating a new ASP.NET web application

In Visual Studio 2013, all the authentication options are available on the “New Project” screen. Simply select the ‘Change Authentication’ button, and you are presented with the following options: Individual User Accounts, Organizational Accounts, or Windows Authentication. The detailed description of each authentication type can be found here.

Authentication Options

In this case, we opt for ‘Individual User Accounts.’ With ‘Individual User Accounts,’ the default behavior of ASP.NET Identity provides local user registration by creating a username and password, or by signing in with social network providers such as Google+, Facebook, Twitter, or their Microsoft account. The default data storage for user profiles in ASP.NET Identity is a SQL Server database, but can also be configured for MySQL, Azure, MongoDB, and many more.

Authentication

The auto-generated project files contain several class that handle authentication for the application:

App_Start/Startup.Auth.cs – Contains the authentication configuration setup during bootstrap of ASP.NET MVC application. See the following ConfigureAuth snippet:

[sourcecode]
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context, user manager and signin manager to use a single
//instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.CreatePerOwinContext(ApplicationSignInManager.Create);

// Enable the application to use a cookie to store information for the signed
// in user and to use a cookie to temporarily store information about a user
// logging in with a third party login provider
// Configure the sign in cookie
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(“/Account/Login”),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user
// logs in. This is a security feature which is used when you change
// a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) =>
user.GenerateUserIdentityAsync(manager))
}
});

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

// Enables the application to temporarily store user information when they are
// verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie
, TimeSpan.FromMinutes(5));

// Enables the application to remember the second login verification factor such
// as phone or email.
// Once you check this option, your second step of verification during the login
// process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

// Enable login in with third party login providers
app.UseTwitterAuthentication(
consumerKey: “[Never hard-code this]”,
consumerSecret: “[Never hard-code this]”);
}
[/sourcecode]

A few things in this class are very important to the authentication process:

  • The CookieAuthenticationOptions class controls the authentication cookie’s HttpOnly, Secure, and timeout options.
  • Two-factor authentication via email or SMS is built into ASP.NET Identity
  • Social logins via Microsoft, Twitter, Facebook, or Google are supported.

Additional details regarding configuration of authentication can be found here.

App_Start/IdentityConfig.cs – Configuring and extending ASP.NET Identity:

ApplicationUserManager – This class extends UserManager from ASP.NET Identity. In the Create snippet below, password construction rules, account lockout settings, and two-factor messages are configured:

[sourcecode]
public class ApplicationUserManager : UserManager
{
public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore(context.Get()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};

// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};

// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;

// Register two factor authentication providers. This application uses Phone
// and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider(“Phone Code”, new PhoneNumberTokenProvider
{
MessageFormat = “Your security code is {0}”
});

manager.RegisterTwoFactorProvider(“Email Code”, new EmailTokenProvider
{
Subject = “Security Code”,
BodyFormat = “Your security code is {0}”
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider(dataProtectionProvider.Create(“ASP.NET Identity”));
}
return manager;
}
}
[/sourcecode]

You’ll notice a few important authentication settings in this class:

  • The PasswordValidator allows 6 character passwords by default. This should be modified to fit your organization’s password policy
  • The password lockout policy disables user accounts for 5 minutes after 5 invalid attempts
  • If two-factor is enabled, the email or SMS services and messages are configured for the application user manager

Models/IdentityModels.cs – This class defines the User Identity that is used in authentication and stored to the database (ApplicationUser extends IdentityUser from ASP.NET Identity). The “default” database schema provided by ASP.NET Identity is limited of the box. It is generated by the EntityFramework with CodeFirst approach during the first launch of the web application. More information on how the ApplicationUser class can be extended with new fields can be found here.

[sourcecode]
public class ApplicationUser : IdentityUser
{
//Add custom user properties here

public async Task GenerateUserIdentityAsync(UserManager manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

// Add custom user claims here
return userIdentity;
}
}
[/sourcecode]

Controllers/AccountController.cs – Finally, we get to the class that is actually using the configuration for performing registration and authentication. The initial implementation of login is shown below:

[sourcecode]
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}

var result = await SignInManager.PasswordSignInAsync(model.Email
, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View(“Lockout”);
case SignInStatus.RequiresVerification:
return RedirectToAction(“SendCode”, new { ReturnUrl = returnUrl
, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError(“”, “Invalid login attempt.”);
return View(model);
}
}
[/sourcecode]

It is important to realize that the Login action sets the shouldLockout parameter to false by default. This means that account lockout is disabled, and vulnerable to brute force password attacks out of the box. Make sure you modify this code and set shouldLockout to true if your application requires the lockout feature.

Looking at the code above, we can see that the social login functionality and two-factor authentication is automatically handled by ASP.NET Identity and does not require additional code.

Authorization

Having created an account, proceed with setting up your authorization rules. The authorize attribute ensures that the identity of a User operating with a particular resource is known and is not anonymous.

[sourcecode]
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}

[Authorize(Roles=”Admin”)]
public ActionResult About()
{
ViewBag.Message = “Your application description page.”;
return View();
}

public ActionResult Contact()
{
ViewBag.Message = “Your contact page.”;
return View();
}
}
[/sourcecode]

Adding Authorize attribute to HomeController class guarantees authenticated access to all the actions in the controller. Role-based authorization is done by adding the authorize attribute with the Roles parameter. The example above shows the Roles=”Admin” on the About() action, meaning that access to the About() action can be performed only by an authorized User that has the role of Admin.

To learn more about securing your .NET applications with ASP.NET Identity, sign up for DEV544: Secure Coding in .NET!

About the author
Taras Kholopkin is a Solutions Architect at SoftServe, and a frequent contributor to the SoftServe United blog. Taras has worked more than nine years in the industry, including extensive experience within the US IT Market. He is responsible for software architectural design and development of Enterprise and SaaS Solutions (including Healthcare Solutions).

Password Tracking in Malicious iOS Apps

In this article, John Bielich and Khash Kiani introduce OAuth, and demonstrate one type of approach in which a malicious native client application can compromise sensitive end-user data.

Earlier this year, Khash posted a paper entitled: Four Attacks on OAuth – How to Secure Your OAuth Implementation that introduced a common protocol flow, with specific examples and a few insecure implementations.  For more information about the protocol, various use cases and key concepts, please refer to the mentioned post and any other freely available OAuth resources on the web.

This article assumes that the readers are familiar with the detailed principles behind OAuth, and that they know how to make GET and POST requests over HTTPS.  However, we will still provide a high-level introduction to the protocol.

OAuth

OAuth is a user-centric authorization protocol that is gaining popularity within the social networking space, and amongst other resource providers such as Google and SalesForce. Furthermore, sites such as Facebook are increasingly positioning themselves as Single Sign-On (SSO) providers for other sites using OAuth as the platform. This makes credentials from such providers extremely high-value targets for attackers.

OAuth is a permission-based authorization scheme.

It allows a user to grant access to a third-party application to access his or her protected content hosted by a different site.  This is done by having the user redirected to the OAuth provider and authenticating on that server, thereby bypassing the need for the client application to know the credentials.  The main goal this protocol attempts to achieve is defeating the password anti-pattern in which users share their credentials with various third-party applications for their service offerings.

OAuth and Embedded Mobile Applications

In mobile operating systems such as iOS, there are controls that can be embedded into the application that enable the login page to be served up within the application itself (in this example, UIWebView). This is often done by client applications to provide a good user experience. However, this approach violates the trust context by not using a web browser (Safari) external to the app.  Several of the browser controls and the OAuth redirect schemes are not applicable to facilitating user authorization.

The ideal application flow typically consists of the following steps:

1.     The client application requests a specific scope of access.

2.     The client application switches the user to an external web browser, and displays the OAuth authentication page, asking for consent and user permission to grant access to the client application.

3.     Upon user authentication and approval, the client application receives an Access Token that can be leveraged to access protected resources hosted by Service Provider.

4.     The callback feature of OAuth is typically leveraged to call the local client app in this scenario.

Building a Malicious Google OAuth Client

As mentioned, the main purpose behind OAuth is to defeat the password anti-pattern, preventing identity attacks through a delegation model where users do not share their Server credentials with third-party Client applications.  However, by using embedded web components with OAuth in native mobile applications, we can provide an attack landscape for malicious rich clients to easily compromise user credentials. This compromise would be undetected by either the user or the service provider, and is especially sneaky, as it provides the user with a false sense of safety in the authentication workflow.

In this section, we will demonstrate a malicious iOS application using Google’s own OAuth sample iOS application.  Our simple modifications will steal user’s credentials as they login through Google’s authorization endpoint.

The Attack

This sample exploit consists of the following overall approach:

1.     Downloading the native OAuthSampleTouch mobile Google application.

2.     Using XCode and the iOS SDK, modify the UIWebViewDelegate’s webView:shouldStartLoadWithRequest:navigationType: callback method to intercept the login page before sending the POST request.

3.     Capture the credentials out of the HTTP body.

4.     Use the captured credentials. In this case, we simply output the values. We could easily store or send the credentials in the background to another destination.

The Attack Details

First step is to download, compile and run OAuthSampleTouch that comes with the gtm-oauth code. This is the sample app that uses the Google framework which we are compromising.

figure 1 – install OAuthSampleTouch

Secondly, find the GTMOAuthViewControllerTouch. This class handles the interaction for the sample app, including the UIWebView for authentication.

figure 2 – edit GTMOAuthViewController

Thirdly, insert the malicious code in the webView:shouldStartLoadWithRequest:navigation that will process the request being sent before it is sent from your device. This code effectively does the following:

  • Grabs the HTTP BODY and assigns it to a string
  • Creates an array of string components separated by the “&” token to get a name/value pair per array element
  • Iterates through the values, grabbing the “Email” and “Passwd” name/value pairs, which are Google’s username / password fields

figure 3- insert evil code in the webView:shouldStartLoadWithRequest:navigationType

Fourthly, we authenticate and grant access to the device.

figure 4 – OAuth process with an embedded view

And lastly, we finish authenticating, granting access, and view the compromised credentials.

figure 5 – outputting credentials

Solutions

The best solution for Client application developers is to follow the recommended flow and use an external browser (in this case, Safari).  Although it might diminish the user experience, this approach will allow the user to be assured that the authentication process is outside the context of the application altogether.

From a user’s perspective, do not trust native OAuth applications that do not follow the recommended flow and are not capturing your credentials in a trusted and neutral 3rd party application, such as Safari.

And lastly, the protocol needs to mature its support for native mobile applications to implement a stricter client authentication process with consumer credentials, a better browser API support, and also properly notify the OAuth providers upon unauthorized access.

About the Authors

John Bielich is a security consultant with  14 years of experience building and securing web-based software applications, as well as over one year in iOS development and security. He can be reached at:  john@codeshuffle.com

Khash Kiani is a principal security consultant and researcher with over 13 years of experience in building and securing software applications for large defense, insurance, retail, technology, and health care organizations. He specializes in application security integration, penetration testing, and social-engineering assessments. Khash currently holds the GIAC GWAPT, GCIH, and GSNA certifications, has published papers and articles on various application security concerns, and spoken at Blackhat US. He can be reached at:  khash@thinksec.com

If you liked this post check out SANS’ new class on Secure iOS App Development.

 

 

 

 

 

 

 

Four Attacks on OAuth – How to Secure Your OAuth Implementation

This article briefly introduces an emerging open-protocol technology, OAuth, and presents scenarios and examples of how insecure implementations of OAuth can be abused maliciously.  We examine the characteristics of some of these attack vectors, and discuss ideas on countermeasures against possible attacks on users or applications that have implemented this protocol.

An Introduction to the Protocol

OAuth is an emerging authorization standard that is being adopted by a growing number of sites such as Twitter, Facebook, Google, Yahoo!, Netflix, Flickr, and several other Resource Providers and social networking sites.  It is an open-web specification for organizations to access protected resources on each other’s web sites.  This is achieved by allowing users to grant a third-party application access to their protected content without having to provide that application with their credentials.

Unlike Open ID, which is a federated authentication protocol, OAuth, which stands for Open Authorization, is intended for delegated authorization only and it does not attempt to address user authentication concerns.

There are several excellent online resources, referenced at the end of this article, that provide great material about the protocol and its use. However, we need to define a few key OAuth concepts that will be referenced throughout this article:

Key Concepts

  • Server or the Resource Provider controls all OAuth restrictions and is a web site or web services API where User keeps her protected data
  • User or the Resource Owner is a member of the Resource Provider, wanting to share certain resources with a third-party web site
  • Client or Consumer Application is typically a web-based or mobile application that wants to access User’s Protected Resources
  • Client Credentials are the consumer key and consumer secret used to authenticate the Client
  • Token Credentials are the access token and token secret used in place of User’s username and password

Example

The actual business functionality in this example is real. However, the names of the organizations and users are fictional.

MyBillManager.com provides Avon Barksdale a bill consolidation service based on the trust Avon has established with various Resource Providers, including BaltimoreCellular.com.

In the diagram below, we have demonstrated a typical OAuth handshake (aka OAuth dance) and delegation workflow, which includes the perspectives of the User, Client, and the Server in our example:

Figure 1: The entire OAuth1.0 Process Workflow

Insecure Implementations and Solutions

In this section, we will examine some of the security challenges and insecure implementations of the protocol, and provide solution ideas. It is important to note that like most other protocols, OAuth does not provide native security nor does it guarantee the privacy of protected data.  It relies on the implementers of OAuth, and other protocols such as SSL, to protect the exchange of data amongst parties. Consequently, most security risks described below do not reside within the protocol itself, but rather its use.

1. Lack Of Data Confidentiality and Server Trust

While analyzing the specification, and the way OAuth leverages the keys, tokens, and secrets to establish the digital signatures and secure the requests, one realizes that much of the effort put into this protocol was to avoid the need to use HTTPS requests all together. The specification attempts to provide fairly robust schemes to ensure the integrity of a request using its signatures; however it cannot guarantee a request’s confidentiality, and that could result in several threats, some of which are listed below.

1.1 Brute Force Attacks Against the Server

An attacker with access to the network will be able to eavesdrop on the traffic and gain access to the specific request parameters and attributes such as oauth_signature, consumer_key, oauth_token, signature_method (HMAC-SHA1), timestamp, or custom parameter data. These values could assist the attacker in gaining enough understanding of the request to craft a packet and launch a brute force attack against the Server. Creating tokens and shared-secrets that are long, random and resistant to these types of attacks can reduce this threat.

1.2 Lack of Server Trust

This protocol is all about authenticating the Client (consumer key and secret) and the User to the Server, but not the other way around. There is no protocol support to check the authenticity of the Server during the handshakes. So essentially, through phishing or other exploits, user requests can be directed to a malicious Server where the User can receive malicious or misleading payloads. This could adversely impact the Users, but also the Client and Server in terms of their credibility and bottom-line.

1.3 Solutions

As we have seen, the OAuth signature methods were primarily designed for insecure communications, mainly non-HTTPS.  Therefore, TLS/SSL is the recommended approach to prevent any eavesdropping during the data exchange.

Furthermore, Resource Providers can limit the likelihood of a replay attack from a tampered request by implementing protocol’s Nonce and Timestamp attributes.  The value of oauth_nonce attribute is a randomly generated number to sign the Client request, and the oauth_timestamp defines the retention timeframe of the Nonce.  The following example from Twitter .NET Development for OAuth Integration demonstrates the creation of these attributes by the application:


Figure 2: Sample oauth_nonce and oauth_timestamp methods

2. Insecure Storage of Secrets

The two areas of concern are to protect:

  • Shared-secrets on the Server
  • Consumer secrets on cross-platform clients

2.1 Servers

On the Server, in order to compute the oauth_signature, the Server must be able to access the shared-secrets (a signed combination of consumer secret and token secret) in plaintext format as opposed to a hashed value. Naturally, if the Server and all its shared-secrets were to be compromised via physical access or social engineering exploits, the attacker could own all the credentials and act on behalf of any Resource Owner of the compromised Server.

2.2 Clients

OAuth Clients use the consumer key and consumer secret combination to provide their authenticity to the Server. This allows:

  • Clients to uniquely identify themselves to the Server, giving the Resource Provider the ability to keep track of the source of all requests
  • The Server to let the User know which Client application is attempting to gain access to their account and protected resource

Securing the consumer secret on browser-based web application clients introduces the same exact challenges as securing shared-secrets on the Server. However, the installed mobile and desktop applications become much more problematic:

OAuth’s dependency on browser-based authorization creates an inherit implementation problem for mobile or desktop applications that by default do not run in the User’s browser. Moreover, from a pure security perspective, the main concern is when implementers store and obfuscate the key/secret combination in the Client application itself. This makes the key-rotation nearly impossible and enables unauthorized access to the decompiled source code or binary where the consumer secret is stored.  For instance, to compromise the Client Credentials for Twitter’s Client on Android, an attacker can simply disassemble the classes.dex with Android dissembler tool, dexdump:

# dexdump – d classes.dex

2.3 The Threats

It is important to understand that the core function of the consumer secret is to let the Server know which Client is making the request. So essentially, a compromised consumer secret does NOT directly grant access to User’s protected data.  However, compromised consumer credentials could lead to the following security threats:

  • In use cases where the Server MUST keep track of all Clients and their authenticity to fulfill a business requirement, (charge the Client for each User request, or for client application provisioning tasks) safeguarding consumer credential becomes critical
  • The attacker can use the compromised Client Credentials to imitate a valid Client and launch a phishing attack, where he can submit a request to the Server on behalf of the victim and gain access to sensitive data

Regardless of the use case, whenever the consumer secret of a popular desktop or mobile Client application is compromised, the Server must revoke access for ALL users of the compromised Client application. The Client must then register for a new key (a lengthy process), embed it into the application as part of a new release and deploy it to all its Users. A nightmarish process that could take weeks to restore service; and will surely impact the Client’s credibility and business objectives.

2.4 Solutions

Protecting the integrity of the Client Credentials and Token Credentials works fairly well when it comes to storing them on servers. The secrets can be isolated and stored in a database or file-system with proper access control, file permission, physical security, and even database or disk encryption.

For securing Client Credentials on mobile application clients, follow security best practices for storing sensitive, non-stale data such as application passwords and secrets.

The majority of current OAuth mobile and desktop Client applications embed the Client Credentials directly into the application.  This solution leaves a lot to be desired on the security front.

Few alternative implementations have attempted to reduce the security risks by obfuscation or simply shifting the security threat elsewhere:

  • Obfuscate the consumer secret by splitting it into segments or shifting characters by an offset, then embed it in the application
  • Store the Client Credentials on the Client’s backend server.  The credentials can then be negotiated with the front-end application prior to the Client/Server handshake.  However, nothing is going to stop a rogue client to retrieve the Client Credentials from application’s back-end server, making this design fundamentally unsound

Let’s consider a better architectural concept that might require some deviation from the typical OAuth flow:

  • The Service Provider could require certain Clients to bind their Consumer Credentials with a device-specific identifier (similar to a session id).  Prior to the initial OAuth handshake, the mobile or desktop application can authenticate the User to the Client application via username and password.  The mobile Client can then call home to retrieve the Device ID from the Client’s back-end server and store it securely on the device itself (e.g. iOS Keychain).   Once the initial request is submitted to the Serve with both the Client Credentials and Device ID, the Service Provider can validate the authenticity of the Device ID against the Client’s back-end server.

The example below illustrates this solution:


Figure 3 :  alternative solution for authenticating OAuth Clients

OAuth’s strength is that it never exposes a User’s Server credentials to the Client application. Instead, it provides the Client application with temporary access authorization that User can revoke if necessary.  So ultimately, regardless of the solution, when the Server cannot be sure of the authenticity of the Client’s key/secret, it should not solely rely on these attributes to validate the Client.

3. OAuth Implementation with Flawed Session Management

As described in the first example (see figure 1), during the authorization step, the User is prompted by the Server to enter his login credentials to grant permission.  The user then is redirected back to the Client application to complete the flow.  The main issue is with a specific OAuth Server implementation, such as Twitter’s, where the user remains logged in on the Server even after leaving the Client application.

This session management issue, in-conjunction with Server’s implementation of OAuth Auto Processing, to automatically process authorization requests from clients that have been previously authorized by the Server, present serious security concerns.

Let’s take a closer look at Twitter’s implementation:

There are numerous third-party Twitter applications to read or send Tweets; and as of August of 2010, all third-party Twitter applications had to exclusively use OAuth for their delegation-based integration with Twitter APIs.  Here is an example of this flawed implementation:

twitterfeed is a popular application that allows blog feeds to user’s Twitter accounts.

Avon Barksdale registers and signs into his twitterfeed client.  He then selects a publishing service such as Twitter to post his blog.


Figure 4: twitterfeed.com client authorization page

Avon is directed to Twitter’s authorization endpoint where he signs into Twitter and grants access.

Figure 5 : Twitter’s authorization page for third-party applications

Now, Avon is redirected back to twitterfeed where he completes the feed; and then signs out of twitterfeed and walks away.


Figure 6: twitterfeed’s workflow page post server authorization

A malicious user with access to the unattended browser can now fully compromise Avon’s Twitter account; and deal with the consequences of his action!


Figure 7:  Twitter session remains valid in the background after user signs out of twitterfeed.com

3.1 The Threat

The User might not be aware that he has a Server session open with the Resource Provider in the background.  He could simply just log out of his Client session and step away from his browser.  The threat is elevated when leaving a session unattended becomes inevitable in use cases where public computers are used to access OAuth-enabled APIs.  Imagine if Avon was a student who frequently accessed public computers for his daily tweet feeds. He could literally leave a Twitter session on every computer he uses.

3.2 Solutions

Resource Providers such as Twitter should always log the User out after handling the third-party OAuth authorization flow in situations where the User was not already logged into the Server before the OAuth initiation request.

Auto Processing should be turned off.  That is, servers should not automatically process requests from clients that have been previously authorized by the resource owner.  If the consumer secret is compromised, a rogue Client can gain ongoing unauthorized access to protected resources without the User’s explicit approval.

4. Session Fixation Attack with OAuth

OAuth key contributor, Eran Hammer Lahav, has published a detailed post, referenced at the end of this article, about this specific attack that caused a major disruption to many OAuth consumers and providers.  For instance, Twitter had to turn-off its third-party integration APIs for an extended period of time, impacting its users as well as all the third-party applications that depended on Twitter APIs.

In summary, the Session Fixation flaw makes it possible for an attacker to use social-engineering tactics to lure users into exposing their data via few simple steps:

  • Attacker uses a valid Client app to initiate a request to the Resource Provider to obtain a temporary Request Token.  He then receives a redirect URI with this token:

http://resource_provider.com/oauth/authorize?oauth_token=XyZ

  • At a later time, the attacker uses social-engineering and phishing tactics to lure a victim to follow the redirect link with the server-provided Request Token
  • The victim follows the link, and grants client access to protected resources. This process authorizes the Request Token and associates it with the Resource Owner

The above steps demonstrate that the Resource Provider has no way of knowing whose Request Token is being authorized, and cannot distinguish between the two users.

  • The Attacker constructs the callback URI with the “authorized” Access Token and returns to the Client:

http://client_app.com/feeds/…/oauth_token= XyZ&…

  • If constructed properly, the Attacker’s client account is now associated with victim’s authorized Access Token

The vulnerability is that there is no way for the Server to know whose key it is authorizing during the handshake.  The author describes the attack in detail and proposes risk-reducing solutions. Also, the new version of the protocol, OAuth2.0, attempts to remediate this issue via its Redirect URI being validated with the authorization key exchange.

Summary

As the web grows, more and more sites rely on distributed services and cloud computing.  And in today’s integrated web, users demand more functionality in terms of usability, cross-platform integration, cross-channel experiences and so on.  It is up to the implementers and security professionals to safeguard user and organizational data and ensure business continuity. The implementers should not rely on the protocol to provide all security measures, but instead they should be careful to consider all avenues of attack exposed by the protocol, and design their applications accordingly.

References

Protocol Specification
OAuth Extensions and Code Sample
Google Provider Specification</a
Twitter API References
OAuth session fixation</a

About the Author

Khash Kiani is a senior security consultant at a large health care organization. He specializes in security architecture, application penetration testing, PCI, and social-engineering assessments.  Khash currently holds the GIAC GWAPT, GCIH, and GSNA certifications.  He can be reached at khashsec@gmail.com