I use the faceted_search module on my site. You can search the site by using the facets of the search which creates an URL like this:
http://localhost/en/facetsearch/results/author:1
If the user then wants to login, the function drupal_get_destination is used and the URL of the login page looks like this:
http://localhost/en/login?destination=facetsearch%2Fresults%2Fauthor%3A1
That's all right. But then in drupal_goto, the destination URL gets decoded: facetsearch/results/author:1
and parsed: host: facetsearch, port: 1, path: /results/author:1
The path is used for the redirect and leads to a page not found error. If I have a faceted search parameter like city:"munich" there is no problem, the URL doesn't get split. It seams that parse_url declares the value of the parameter author as port. On php.net/parse_url site there is a note that this function doesn't work with relative URLs.
This might be no Faceted Search Issue, but maybe somebody her already knows what to do.
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | 337261-parse_url_in_drupal_goto.patch | 623 bytes | chrisns |
| #6 | drupal_goto-parse_url.patch | 3.26 KB | john morahan |
| #3 | drupal_goto-parse_url.patch | 2.22 KB | john morahan |
| #2 | drupal_goto-parse_url.patch | 851 bytes | john morahan |
Comments
Comment #1
john morahan commentedI just ran into the same issue with logintoboggan for D6 - it's a core bug IMO; drupal_goto should not use parse_url on a relative URL if php.net says it doesn't work.
This would have to be fixed in D7 first and backported, I think. I will try to provide a patch soon if nobody else does.
Comment #2
john morahan commentedHere's the beginnings of one idea. Needs a test.
Comment #3
john morahan commentedComment #4
catchDoes this only ever need to be run in drupal_goto(), if there's other use cases, should we make drupal_parse_url() or similar?
Comment #5
john morahan commentedHmm, good point. A quick grep of core reveals 8 more references to parse_url(). Most of them are probably legitimate (i.e. expect a full URL), but the one in menu.admin.inc looks suspicious -- and sure enough, try to add a menu link to node/add/page?test=foo:/:bar and you get an error "The path '/add/page' is either invalid or you do not have access to it."
Comment #6
john morahan commentedComment #7
john morahan commentedHmm, one unintended consequence of this is that drupal_goto will now happily redirect to an absolute URL in the destination. Not sure if that's a good thing or a bad thing.
Comment #8
coltrane@John Morahan, I think its a good thing and I haven't heard any reason so far it'd be a problem. This dev list thread is relevant: http://lists.drupal.org/pipermail/development/2008-May/029772.html
Comment #9
coltrane#107830: Support external sites in destination request in drupal_goto was marked a duplicate of this.
Comment #10
frankcarey commented+1 I would like to see this!
Comment #12
john morahan commentedsuspected test bot failure
Comment #13
Mark Theunissen commentedI have also just encountered this bug in Drupal 6 using the Menu module. Unable to create a link to a URL with a colon in it. +1 from me!
Comment #14
cburschkaYou can't execute a regular expression and then use the match groups without first checking if the expression matched. If the expression didn't match, you will see notices about $matches[1] not being defined.
What you need is
Comment #15
john morahan commentedHow would it not match?
Comment #16
cburschka/^([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/Oh, whoops. I misread a part of it (regexes are my personal nemesis). Yes, it seems that this pattern should match any string, so a check probably isn't required.
Comment #17
john morahan commentedHmm...
http://googlewebmastercentral.blogspot.com/2009/01/open-redirect-urls-is...
would we need to worry about this?
Comment #19
c960657 commentedSee #553262: Make getAbsoluteURL() standard compliant that suggests a new function, drupal_parse_url(), that supports parsing relative URLs.
Comment #20
willmoy commented#203571: Custom logout redirects to external sites depends on this issue. Seems like we could solve the open redirect issue by adding an argument $external = FALSE to drupal_goto(), which was only overridden to permit external redirects in suitable contexts.
Comment #21
c960657 commentedI believe this has been fixed in #578520: Make $query in url() only accept an array.
Comment #23
fizk commentedI'm not sure how this was fixed by #578520: Make $query in url() only accept an array.
I'm trying to use login_destination to redirect from an SSL login page to a NON-SSL front page. Using "http://www.example.com" isn't working because of this bug.
Comment #24
chrisns commentedpatches above didn't work for me, at least not with drupal 6.22 so made this one that does based on the one in comment 2
Comment #26
kleinmp commentedYes, this still seems to be an issue in Drupal 7 as it is noted in drupal_parse_url() that 'relative URL "foo/bar:1" isn't properly parsed'.
Comment #27
BassistJimmyJam commented#6: drupal_goto-parse_url.patch queued for re-testing.
Comment #28
neilt17 commentedJust in case anyone still needs to fix this issue when using Faceted Search in Drupal 6, just appending a dot to the destination url on login where there is just one taxonomy term on the url does it. So you could do this (a bit of a hack really):