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

Security: protect against open redirects #415

Closed
Tracked by #418
afeld opened this issue Apr 11, 2022 · 3 comments
Closed
Tracked by #418

Security: protect against open redirects #415

afeld opened this issue Apr 11, 2022 · 3 comments
Labels
back-end Django views, sessions, middleware, models, migrations etc. security Changes to improve or maintain the availability and resilience of the app

Comments

@afeld
Copy link
Contributor

afeld commented Apr 11, 2022

The origin set in session.py is used for history and (as of #414) redirection after login.

if origin is not None:
logger.debug(f"Update session {_ORIGIN}")
request.session[_ORIGIN] = origin

Currently, all cases where the origin are set are "trusted", but I could imagine a case where we take that path from a query parameter, leaving ourselves vulnerable to an open redirect vulnerability. We should validate the URL/path being passed.

Info about open redirects:

@afeld afeld added bug Something isn't working back-end Django views, sessions, middleware, models, migrations etc. labels Apr 11, 2022
@afeld afeld moved this to Icebox in Digital Services Apr 11, 2022
@thekaveman
Copy link
Member

thekaveman commented Apr 11, 2022

A straightforward way to implement this protection might be to move the usage of Django's reverse() helper from the callers of update() into the function itself.

That would embed and enforce the assumption that the origin is a safe identifier for a known Django application route. A call to reverse() with an invalid route name or a random external URL would fail, causing the update to fail.

E.g. where right now, say in a view, we might call update() like:

session.update(request, origin=reverse("eligibility:start"))

We change the session.update() code as follows:

if origin is not None: 
     logger.debug(f"Update session {_ORIGIN}") 
     request.session[_ORIGIN] = reverse(origin)

And callers like:

session.update(request, origin="eligibility:start")

Though we have a few places where a direct URL is passed that would need to be updated, e.g. in the agency_index() view function. In that example we'd need to pass an extra parameter into the update() method to be able to resolve the agency's index page with the core:agency_index route definition.

@thekaveman thekaveman moved this from Icebox to Backlog in Digital Services Apr 11, 2022
@afeld
Copy link
Contributor Author

afeld commented Apr 11, 2022

@afeld afeld mentioned this issue Apr 12, 2022
4 tasks
@thekaveman thekaveman added security Changes to improve or maintain the availability and resilience of the app and removed bug Something isn't working labels Apr 12, 2022
@thekaveman thekaveman moved this from Backlog to This Sprint in Digital Services Apr 12, 2022
@thekaveman thekaveman moved this from This Sprint to Backlog in Digital Services Apr 12, 2022
@thekaveman thekaveman mentioned this issue Apr 20, 2022
12 tasks
@afeld afeld removed the status in Digital Services Apr 27, 2022
@afeld
Copy link
Contributor Author

afeld commented May 9, 2022

Looked through the app and we don't have any redirects coming from parameters, so not going to worry about this for now.

@afeld afeld closed this as completed May 9, 2022
@afeld afeld moved this to Done in Digital Services May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
back-end Django views, sessions, middleware, models, migrations etc. security Changes to improve or maintain the availability and resilience of the app
Projects
Archived in project
Development

No branches or pull requests

2 participants