mirror of
https://github.com/traefik/traefik.git
synced 2026-06-08 16:22:52 -04:00
Avoid 302 redirect when rewrite-target value is not an absolute URL for ingress-nginx provider
This commit is contained in:
parent
036114bf17
commit
7cacf027a1
2 changed files with 21 additions and 2 deletions
|
|
@ -28,6 +28,9 @@ type rewriteTarget struct {
|
|||
replacement string
|
||||
xForwardedPrefix string
|
||||
name string
|
||||
// absoluteURLRedirect is true when the replacement template is an absolute URL,
|
||||
// indicating the operator explicitly configured a redirect to an external destination.
|
||||
absoluteURLRedirect bool
|
||||
}
|
||||
|
||||
// New creates a new rewrite target middleware.
|
||||
|
|
@ -45,6 +48,10 @@ func New(ctx context.Context, next http.Handler, config dynamic.RewriteTarget, n
|
|||
name: name,
|
||||
}
|
||||
|
||||
if parsed, err := url.Parse(mw.replacement); err == nil && parsed.Scheme != "" {
|
||||
mw.absoluteURLRedirect = true
|
||||
}
|
||||
|
||||
if config.Regex != "" {
|
||||
exp, err := regexp.Compile(strings.TrimSpace(config.Regex))
|
||||
if err != nil {
|
||||
|
|
@ -77,8 +84,9 @@ func (rt *rewriteTarget) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||
newTarget = replacementRegex.ReplaceAllString(rt.replacement, "")
|
||||
}
|
||||
|
||||
// If the replacement resolves to an absolute URL, issue a 302 redirect.
|
||||
if parsed, err := url.Parse(newTarget); err == nil && parsed.Scheme != "" {
|
||||
// Only issue a 302 redirect if the replacement template itself is an absolute URL.
|
||||
// Prevent user-controlled capture group content from injecting an absolute URL redirect.
|
||||
if rt.absoluteURLRedirect {
|
||||
http.Redirect(rw, req, newTarget, http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,17 @@ func TestRewriteTarget(t *testing.T) {
|
|||
expectedStatusCode: http.StatusFound,
|
||||
expectedRedirectURL: "https://bar.example.org/",
|
||||
},
|
||||
{
|
||||
desc: "path with an absolute redirect URL in the capture group should not issue a 302 redirect",
|
||||
path: "/prefix/http://evil.com/malicious",
|
||||
config: dynamic.RewriteTarget{
|
||||
Regex: `^/prefix/(.*)`,
|
||||
Replacement: "$1",
|
||||
},
|
||||
expectedPath: "http://evil.com/malicious",
|
||||
expectedRawPath: "http://evil.com/malicious",
|
||||
expectedStatusCode: http.StatusOK,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
|
|||
Loading…
Reference in a new issue