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

Allow redirects to whitelisted hosts with ports #280

Merged

Conversation

kamaln7
Copy link
Contributor

@kamaln7 kamaln7 commented Oct 11, 2019

This updates IsValidRedirect to allow redirects to whitelisted hosts if a port is set on the redirect URL. Fixes #279.

Description

Use URL.Hostname() instead of URL.Host to strip the port when validating the host against the list of whitelisted domain.

How Has This Been Tested?

Added tests to cover the new use cases. I wasn't sure if I needed to add tests for invalid hosts with ports but let me know and I can add that in.

Checklist:

  • My change requires a change to the documentation or CHANGELOG.
  • I have updated the documentation/CHANGELOG accordingly.
  • I have created a feature (non-master) branch for my PR.

@kamaln7 kamaln7 requested a review from a team October 11, 2019 12:44
loshz
loshz previously approved these changes Oct 11, 2019
Copy link
Member

@loshz loshz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you and congrats on your first contribution! 🎉

@JoelSpeed
Copy link
Member

@kamaln7 Thanks for submitting this PR, I've got an idea about potential improvements, I wonder if we could define some logic so that the whitelist domains could include the port? If no port is set we assume there should be no port set on the request for redirection (ie it's a standard port), if a port is set on the redirect then it must match a whitelisted domain/port combination, WDYT?

Added tests to cover the new use cases. I wasn't sure if I needed to add tests for invalid hosts with ports but let me know and I can add that in.

If you could add some invalid host tests that would be great!

Finally, please make sure to update the changelog and documentation before this gets merged 🙂

@kamaln7
Copy link
Contributor Author

kamaln7 commented Oct 12, 2019

Thanks for the feedback! I'll be sure to update the documentation and changelog, but I want to confirm that the current behavior is what you were looking for.

Provided that the redirect URL matches a whitelisted domain:

  • If the whitelisted domain doesn't contain a port, the redirect URL is considered valid regardless of its port
  • If the whitelisted domain contains a port, the redirect URL will be considered valid only if it matches the same port

I've added some more tests which I believe cover all cases but an extra set of eyes is never a bad idea.

Now, there's something I'm not 100% sure about. Because the whitelisted domains aren't proper URLs, only hosts, I don't use url.Parse() but rather create a url.URL struct manually and set the Host field myself. Then I use URL.Hostname() and URL.Port() as with the redirect URLs.

The code for URL.Hostname() and URL.Port() doesn't use any fields other than Host, so it's fine and it works. But my concern is that by creating the struct manually and not using url.Parse(), the Host isn't validated. That should be fine if you trust operators to use proper domains in the config, but I feel like that might cause unpredictable behavior if an operator uses an invalid host. I do check if URL.Hostname() returns an empty string though I don't know if that's good enough.

I'm not sure how deep you want to go into this so I'd like to hear your thoughts.

@JoelSpeed
Copy link
Member

If the whitelisted domain doesn't contain a port, the redirect URL is considered valid regardless of its port
If the whitelisted domain contains a port, the redirect URL will be considered valid only if it matches the same port

I think if there is no port set on the whitelist domain then we should assume that the request must be on the default port for the protocol (so 80 for http, 443 for https).

Though I would assume that the request wouldn't have a port set when you form it if it's to the default port so I think the check would be to check for an empty port, might be worth testing that assumption though 🤔

@kamaln7
Copy link
Contributor Author

kamaln7 commented Oct 19, 2019

Yes, good point about the port being empty.

I’ll update the code. For wildcard ports I guess we could use “*” as the port assuming that wouldn’t cause issues with parsing. That way it would be backwards compatible too.

@JoelSpeed
Copy link
Member

That sounds like a really good approach! Please make sure there are sufficient tests for all the cases when you make these changes

@kamaln7
Copy link
Contributor Author

kamaln7 commented Oct 23, 2019

Let me know what you think. I had to copy splitHostPort and validOptionalPort from net/url to the package and modify validOptionalPort to allow * as a port. Neither net/url.URL.splitHostPort() nor net.SplitHostPort() work without workarounds.

I also took some time to refactor the tests.

@kamaln7
Copy link
Contributor Author

kamaln7 commented Nov 13, 2019

Hey @JoelSpeed any updates? 😄

Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one minor thing, but other than that it looks great! Apologies for the delay btw 🙈

oauthproxy.go Outdated Show resolved Hide resolved
@kamaln7
Copy link
Contributor Author

kamaln7 commented Nov 14, 2019

No worries, thanks for reviewing!

@kamaln7 kamaln7 requested a review from JoelSpeed November 14, 2019 15:20
@loshz loshz self-requested a review November 19, 2019 17:00
@mnaser
Copy link

mnaser commented Jan 6, 2020

This is super useful and it seems to have been forgotten till it hit merge conflict.

Perhaps @kamaln7 could be kind enough to rebase and we can help land this? :)

@loshz
Copy link
Member

loshz commented Jan 8, 2020

Once conflicts are fixed we can merge.

@kamaln7
Copy link
Contributor Author

kamaln7 commented Jan 8, 2020

Fixed! 😃

@mnaser
Copy link

mnaser commented Jan 15, 2020

@syscll can this be merged now? :)

loshz
loshz previously approved these changes Jan 15, 2020
Copy link
Member

@loshz loshz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@loshz
Copy link
Member

loshz commented Jan 15, 2020

Can you give this a final review @JoelSpeed @steakunderscore

Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @kamaln7

@JoelSpeed JoelSpeed merged commit 038ee16 into oauth2-proxy:master Jan 15, 2020
Jing-ze pushed a commit to Jing-ze/oauth2-proxy that referenced this pull request Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Whitelist domain not working for Host:Port on redirects
4 participants