Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RelayState Should Not Be Required in Request #70

Open
cjduffett opened this issue Oct 13, 2017 · 4 comments
Open

RelayState Should Not Be Required in Request #70

cjduffett opened this issue Oct 13, 2017 · 4 comments

Comments

@cjduffett
Copy link
Contributor

cjduffett commented Oct 13, 2017

According to the SAML Profile for Single Sign-On AuthnRequests, the Service Provider MAY send a RelayState along with the request, but that it's not required. See section 4.1.3.1 of this document:
https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf

However, in OneLogin_Saml2_Auth.login() (in auth.py) this parameter is always set, even if return_to is a blank string. For example, a redirect_url returned by login() could look like:

http://acme.onelogin.com/saml/login?SAMLRequest=<b64_encoded_req>&RelayState=

This could potentially be misleading for Identity Providers that detect the RelayState parameter in the request only to discover that it's blank.

I propose that the RelayState parameter should not be set at all if return_to is None, or an empty string (''). If you think that's a reasonable fix, I'll create a PR for you. 🙂

@pitbulk
Copy link
Contributor

pitbulk commented Oct 13, 2017

So your patch is at login method replace

if return_to is not None:

by

if not return_to:

right?

@cjduffett
Copy link
Contributor Author

cjduffett commented Oct 16, 2017

Not quite. I don't think RelayState should be set at all if return_to is blank or not provided. I propose removing the default value of OneLogin_Saml2_Utils.get_self_url_no_query(), so that block reads:

if return_to is not None:
    parameters['RelayState'] = return_to

(without the else clause)

@pitbulk
Copy link
Contributor

pitbulk commented Oct 16, 2017

But that change can break current environments that uses that toolkit and expect that behavior.

@cjduffett
Copy link
Contributor Author

cjduffett commented Oct 17, 2017

After giving it some thought, would it be acceptable to omit the RelayState if RelayState == ''?

This would allow the default None value to continue using the default get_self_url_no_query(), and if it's explicitly set then return_to will still be used. So the logic would instead be:

if return_to is None:
  parameters['RelayState'] = OneLogin_Saml2_Utils.get_self_url_no_query()
elif return_to is not '':
  parameters['RelayState'] = return_to

Something like that? Short of adding a new advanced settings flag to control this, I can't think of a better way to explicitly omit the RelayState from the request.

For my use case I've taken to scrubbing the RelayState from the request after it's returned from the OneLogin_SAML2_Auth client:

def remove_relay_state(url):
    """Removes the RelayState parameter from a SAML login request."""

    if 'RelayState' not in url:
        return url

    # Parse and modify the query parameters
    parts = urlparse(url)
    params = parse_qs(parts.query)
    del params['RelayState']

    # Reconstruct the URL
    query = urlencode(params, doseq=True)
    new_url = urlunparse((
        parts.scheme,
        parts.netloc,
        parts.path,
        parts.params,
        query,
        None, # No fragments
    ))
    return new_url

But that's addressing the symptoms, not the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants