Skip to content

2019 Q1 Recurity Assessment: Open Redirect

https://gitlab.com/gitlab-com/gl-security/engineering/issues/329

Details

Within the Oauth/:GeoAuthController for the secondary Geo node, a redirect is triggered after successful authentication. The redirect target is designated by th login_state in ee/app/controllers/oauth/geo_auth_controller.rb as follows:

def after_sign_in_with_gitlab(token)
  session[:access_token] = token
  # Prevent alert from popping up on the first page shown after authentication.
  flash[:alert] = nil
  redirect_to(login_state.return_to /| root_path)
end

The login_state is comprised of a salt, the redirect URL and an HMAC over the redirect URL (see also chapters 3.1 and 3.2). Furthermore, the login_state value will be used as a state parameter within the OAuth flow for login to the secondary note (see chapter 3.4). The initial generation of the state parameter is taking place upon a GET request towards /users/sign_in on the secondary node. The open redirect issue results from the fact that a tampered HOST header will be reflected in the login_state 's redirect target. The secondary node will redirect to arbitrary hosts when an attacker mounts a CSRF attack using such a pre-generated state parameter (see also chapter 3.4).

Reproduction Steps

The following curl command can be utilized to verify the issue: curl https://secondary.recurity.gogitlab.com/users/sign_in -H 'Host: this.is.not.my.host' The redirect target can be observed in the state parameter below:

<html><body>You are being <a href="https://this.is.not.my.host/oauth/geo/auth?
state=c16d2268f8f25667%3A771b6d0015a023f9ec6746b9e00bbbd49587aa5285babf77c73e5fda1d
af9d8c%3Ahttps%3A%2F%2Fthis.is.not.my.host%2F">redirected</a>.</body></html>

Also note that, if the HOST header is not spoofable, the X-Forwarded-Host header might be utilized as well. Both vectors were available on the test environment.

Recommendation

This issue can be mitigated in two different places. First, the application should not generate redirect targets for other hosts. Second, the input to redirect_to should be sanitized in a way that no other hosts can be supplied as a target. Recurity Labs is in favor of implementing both mitigation approaches as they do not exclude each other.

Edited by Douglas Barbosa Alexandre