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

Avoid unauthorized redirect loops #2900

Merged
merged 1 commit into from
May 4, 2017
Merged

Conversation

jone
Copy link
Member

@jone jone commented May 1, 2017

The require_login script was customized in order to support MS Office
probing, which happens without the session (cookies).

The old implementation had issues:

  • When the request had a payload, such as a POST request, the payload
    did not survive the redirect. When a ++add++ could be rendered but not
    posted, this caused the form to reload empty without an error.
  • When the unauthorized exception did not happen during traversal but
    during publishing a redirect loop was created.

In order to fix this issues I rewrote the require_login script to be
more robust.

  • No longer redirect when the request method is not GET.
  • When redirecting, add a marker GET parameter for detecting loopbacks
    and breaking redirect loops.
  • No longer catch all exceptions; catch only the Unauthorized exception.
  • Remove GET-Params when converting to a path when probing.
  • Crash on purpose when came_from is not within our site root.

Besides fixing a bunch of actual redirect loops in the application this change allows us to move on to a newer ftw.testbrowser later, without downgrading the HTTP error handling.

@jone jone requested a review from lukasgraf May 1, 2017 16:20
Copy link
Member

@lukasgraf lukasgraf left a comment

Choose a reason for hiding this comment

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

Just a minor typo, LGTM otherwise! 👍 Thanks for cleaning up this mess! 🍝



came_from_url = request.get('came_from')
if 'require_login_awoid_loop=' in came_from_url.split('?')[-1]:
Copy link
Member

Choose a reason for hiding this comment

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

awoid -> avoid (also in commit message, PR title and changelog 😜 )

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops


came_from_path = came_from_url[len(portal_url):].split('?')[0].split('#')[0]
try:
# Probe for an actualy Unauthorized exception while traversing.
Copy link
Member

Choose a reason for hiding this comment

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

actualy -> actual

else:
# Attach a marker so that we can detect redirect loops.
if '?' in came_from_url:
came_from_url += '&require_login_awoid_loop=true'
Copy link
Member

Choose a reason for hiding this comment

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

Hmm. I'm not too excited about this staying in user-visible URLs (apart from some URLs becoming a bit ugly). What if a user ends up on a document this way, and decides to copy & paste this link from the address bar into a word document? 😝 Not a big deal though.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, that is not nice, but I didn't find a better solution. Cookies wouldn't be a good idea because they are session-wide. I also thought about using an abbreviation, but it doesn't really make it better.

Do you have another idea how to detect redirect loops?

@lukasgraf
Copy link
Member

I would suggest to deploy this to dev.onegovgever.ch quickly after merge - we should give this a thorough test with Virtual Hosting + CAS Portal as well.

(The CAS server URL (https://dev.onegovgever.ch/portal) for example is outside the Plone portal URL (https://dev.onegovgever.ch/fd/), though I couldn't think of a case where this would end up in came_from).

@jone jone changed the title Awoid unauthorized redirect loops Avoid unauthorized redirect loops May 2, 2017
The require_login script was customized in order to support MS Office
probing, which happens without the session (cookies).

The old implementation had issues:
- When the request had a payload, such as a POST request, the payload
  did not survive the redirect. When a ++add++ could be rendered but not
  posted, this caused the form to reload empty without an error.
- When the unauthorized exception did not happen during traversal but
  during publishing a redirect loop was created.

In order to fix this issues I rewrote the require_login script to be
more robust.
- No longer redirect when the request method is not GET.
- When redirecting, add a marker GET parameter for detecting loopbacks
  and breaking redirect loops.
- No longer catch all exceptions; catch only the Unauthorized exception.
- Remove GET-Params when converting to a path when probing.
- Crash on purpose when came_from is not within our site root.
@jone jone force-pushed the jone-unauthorized-redirects branch from efc380c to 89eb287 Compare May 2, 2017 06:48
@jone
Copy link
Member Author

jone commented May 2, 2017

@lukasgraf thanks for the review; I amended according to your comments.

@jone
Copy link
Member Author

jone commented May 2, 2017

Be aware: the discussion about the GET parameter is now "outdated" because of a name change, but it is not really fixed.

@lukasgraf lukasgraf merged commit 434d877 into master May 4, 2017
@lukasgraf lukasgraf deleted the jone-unauthorized-redirects branch May 4, 2017 07:43
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.

2 participants