Skip to content

Read only the target argument of redirect sinks - #83

Merged
SizzleUnrlsd merged 2 commits into
mainfrom
fix/django-redirect
Sep 5, 2026
Merged

SizzleUnrlsd merged 2 commits into
mainfrom
fix/django-redirect

Conversation

@SizzleUnrlsd

Copy link
Copy Markdown
Contributor

Summary

Fourth item of #71: redirect sinks read their target only.

  • Acceptance tests first (test: define redirect sinks as reading their target only), implementation follows.
  • Django's redirect("url-name", arg) and redirect("url-name", pk=arg) resolve a URL pattern with the extra arguments as route parameters; HttpResponseRedirect(to), HttpResponsePermanentRedirect(to) and Flask's redirect(location, code) take the target first too. The five sinks now restrict REDIRECT to argument 0 through Sink.positions, the mechanism SQL statements already use, so attacker-controlled data in the other arguments is not an open redirect while a tainted target still is.
  • Snapshots: healthchecks drops from 87 to 13 open-redirect findings; DjangoGoat loses its three redirect('profile', pk=user.pk) findings and keeps its real ones. What remains on healthchecks is redirect(request.GET.get("next")) behind the project's own _allow_redirect check, reported as a hotspot, plus redirect(request.path) and reverse(...) paths with a query string taken from the request, which are same-origin by construction and a candidate for a later refinement.

Part of #71.

@SizzleUnrlsd SizzleUnrlsd self-assigned this Sep 5, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit 74431d2 into main Sep 5, 2026
10 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the fix/django-redirect branch September 5, 2026 12:50
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.

1 participant