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

feat: Allow configuring redirect secure checker everywhere #489

Merged
merged 3 commits into from
Oct 11, 2020

Conversation

mitar
Copy link
Contributor

@mitar mitar commented Sep 30, 2020

Proposed changes

I have been reading this part of the code and found out some things I could improve.

Checklist

  • I have read the contributing guidelines
  • I have read the security policy
  • I confirm that this pull request does not address a security
    vulnerability. If this pull request addresses a security vulnerability, I
    confirm that I got green light (please contact
    security@ory.sh) from the maintainers to push
    the changes.
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation within the code base (if appropriate)

Further comments

This is changing/cleaning some security logic used by fosite. I do not think any of these changes are changing anything really exploitable, but I still think it will harden and cleanup things a bit. Or at least make it more consistent.

@@ -131,10 +131,6 @@ func isLoopbackURI(requested *url.URL, registeredURI string) bool {
return false
}

if registered.Scheme != "http" || !isLoopbackAddress(registered.Host) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is redundant. So I removed it.

Copy link
Member

Choose a reason for hiding this comment

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

While that's currently true, removing explicit checks for implicit ones opens up a big opportunity for regression issues. Given that this is security sensitive, and that you want to have this removed, please either write a test covering this exact case or point to the test case that already covers this logic. Thanks! :)

Copy link
Contributor Author

@mitar mitar Oct 1, 2020

Choose a reason for hiding this comment

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

But this is logically redundant. It is literally the opposite than the next case. It is De Morgan law.

Compare:

registered.Scheme != "http" || !isLoopbackAddress(registered.Host)

and:

requested.Scheme == "http" && isLoopbackAddress(requested.Host)

There is no way one can write a test case here because it is behaving exactly the same with or without this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, you just want a test case where using http scheme returns false and using a http scheme without loopback address returns false? I think those are already covered.

Copy link
Member

Choose a reason for hiding this comment

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

Exactly!

That test tests IsRedirectURISecure which does not use isLoopbackURI so I think this is neither covered explicitly nor implicitly.

}

func IsLocalhost(redirectURI *url.URL) bool {
hn := redirectURI.Hostname()
return strings.HasSuffix(hn, ".localhost") || hn == "127.0.0.1" || hn == "localhost"
return strings.HasSuffix(hn, ".localhost") || hn == "127.0.0.1" || hn == "::1" || hn == "localhost"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

IPv6 localhost is still localhost.

authorize_helper_test.go Outdated Show resolved Hide resolved
@@ -38,6 +39,7 @@ import (
type OpenIDConnectRequestValidator struct {
AllowedPrompt []string
Strategy jwt.JWTStrategy
IsRedirectURISecure func(*url.URL) bool
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding this for completeness. We are allowing configuring IsRedirectURISecure in some places, but not in all. I added it here so that we can configure it here as well.

@@ -75,7 +90,7 @@ func (v *OpenIDConnectRequestValidator) ValidatePrompt(ctx context.Context, req
// be processed as if no previous request had been approved.

if stringslice.Has(prompt, "none") {
if !(req.GetRedirectURI().Scheme == "https" || (fosite.IsLocalhost(req.GetRedirectURI()) && req.GetRedirectURI().Scheme == "http")) {
if !v.secureChecker()(req.GetRedirectURI()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So instead of duplicating code, I moved all this code to IsRedirectURISecure.

authorize_helper_test.go Outdated Show resolved Hide resolved
@@ -131,10 +131,6 @@ func isLoopbackURI(requested *url.URL, registeredURI string) bool {
return false
}

if registered.Scheme != "http" || !isLoopbackAddress(registered.Host) {
Copy link
Member

Choose a reason for hiding this comment

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

While that's currently true, removing explicit checks for implicit ones opens up a big opportunity for regression issues. Given that this is security sensitive, and that you want to have this removed, please either write a test covering this exact case or point to the test case that already covers this logic. Thanks! :)

authorize_helper.go Show resolved Hide resolved
@@ -131,10 +131,6 @@ func isLoopbackURI(requested *url.URL, registeredURI string) bool {
return false
}

if registered.Scheme != "http" || !isLoopbackAddress(registered.Host) {
Copy link
Member

Choose a reason for hiding this comment

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

Exactly!

That test tests IsRedirectURISecure which does not use isLoopbackURI so I think this is neither covered explicitly nor implicitly.

authorize_helper.go Show resolved Hide resolved
authorize_helper_test.go Outdated Show resolved Hide resolved
@mitar
Copy link
Contributor Author

mitar commented Oct 2, 2020

OK. Are you open to having IsRedirectURISecureStrict or something alongside IsRedirectURISecure so that one can pick one or the other? I can keep then IsRedirectURISecure as a default and explain in IsRedirectURISecureStrict's docstring the reasoning behind it?

@mitar mitar requested a review from aeneasr October 7, 2020 04:22
@mitar
Copy link
Contributor Author

mitar commented Oct 7, 2020

Addressed review comments.

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

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

Nice, this looks great!

@aeneasr aeneasr merged commit e87d091 into ory:master Oct 11, 2020
@mitar mitar deleted the redirect-validation branch October 12, 2020 02:11
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.

None yet

2 participants