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

Change redirect after login form submit #944

Merged
merged 4 commits into from
Apr 19, 2021

Conversation

petrakohorst
Copy link
Member

Use uri_for on redirect URI only if no params are attached.

(This problem only happens when submitting the login form! Prior redirects to shibboleth instances for example are exempt from this, because they don't submit the login form.)

When redirecting to a URL that has parameters attached, the sub uri_for does not recognize these parameters as such. The sub expects parameters to be given separately from the base URI.
Instead, in this case, the full URL is used as $path (expecting a clean URL path). This results in undecoded questionmarks in the actual redirect URI and the user lands on a 404 page.

Example:
Requested URL is http://localhost:5001/librecat/search/admin?sort=author.asc
User gets to the login form, logs in.

The redirect, however, will lead to: http://localhost:5001/librecat/search/admin%3Fsort=author.asc

@coveralls
Copy link

coveralls commented Apr 1, 2021

Coverage Status

Coverage remained the same at 81.388% when pulling 7449365 on pr/fix_redirect_after_login into e46ee58 on dev.

@nicolasfranck
Copy link
Contributor

Why is there even a call to uri_for when a full url is expected?
I would rather suggest to change the previous line from

my $return_url = params->{return_url} || '/librecat';

to

my $return_url = params->{return_url} || uri_for('/librecat');

@nicolasfranck
Copy link
Contributor

mm, you're right: this route expects a local path in $return_url,
and that is why "external" links are filtered out.

@nicolasfranck
Copy link
Contributor

nicolasfranck commented Apr 6, 2021

I've look through the code, and it seems that return_url should be a full url, and just a path,
like /librecat on this line suggests.

But a check against external links cannot be done like this as it strips too much.
What if the application is served behind a proxy, and so has a prefix?

Proposal:

  • default url should be full url
- my $return_url = params->{return_url} || '/librecat';
+ my $return_url = params->{return_url} || uri_for('/librecat')->as_string;
  • return_url should be replaced by that default url when not starting with the full prefix uri_base (e.g. https://myhost/prefix)
- $return_url =~ s{^[a-zA-Z:]+(\/\/)[^\/]+}{};
+ $return_url = uri_for("/librecat")->as_string if index( $return_url, request->uri_base() ) != 0;

and then just redirect to that url

@nicolasfranck
Copy link
Contributor

@petrakohorst I've made some changes. Can you confirm if it works?

@petrakohorst
Copy link
Member Author

@nicolasfranck Yes, it works perfectly with your changes!

@nicolasfranck nicolasfranck merged commit 71aa167 into dev Apr 19, 2021
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

3 participants