Skip to content

redirect-trailing-slash-handler can end up redirecting to external URL #337

@svdm

Description

@svdm

This requires a specific route configuration that includes a route that can potentially match a path that starts with //, for example in this minimal setup:

(def app
  (ring/ring-handler
    (ring/router
     [["/ping" {:get (constantly {:status 200, :body "ping"})}]
      ["/*" {:get (constantly nil)}]]
     {:conflicts (fn [c])})
    (ring/redirect-trailing-slash-handler {:method :strip})))

A request like the following can end up redirecting to an absolute URL outside the app instead of to the relative path that the slash-handler is intending:

(app {:uri "//metosin.github.io/reitit/" :request-method :get})
; {:status 301, :headers {"Location" "//metosin.github.io/reitit"}, :body ""}
;; NB: Browsers will interpret this as a redirect to https://metosin.github.io/reitit

What happens is the following, taking //foo/ as a (shorter) example:

  1. The wildcard route matches //foo/, but returns nil
  2. The URL ends with a /, so the slash-handler will strip it
  3. The slash-handler uses match-by-path with the stripped URL //foo, this matches the wildcard route (again)
  4. The slash-handler returns Location: //foo in its response, sending the client off to a strange place.

Of course in the real world you wouldn't have a wildcard route that always returns nil, but one could have e.g. a resource-handler on that route that returns nil for any path that does not match a resource filename.

This behaviour could be fixed by stripping multiple slashes at the start of the path before returning it as Location in the slash handler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions