fix(redirect): improve security in HTTP to HTTPS redirection

This commit is contained in:
2026-07-04 14:39:41 +08:00
parent 481ccad05e
commit 33a29b04e4
4 changed files with 21 additions and 10 deletions

View File

@@ -51,7 +51,9 @@ func NewHTTP2HTTPSRedirectPlugin(_ PluginContext, options v1.ClientPluginOptions
p.s = &http.Server{ p.s = &http.Server{
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
http.Redirect(w, req, buildHTTPSRedirectURL(req, opts.HTTPSPort), http.StatusFound) // Not an open redirect: the target scheme is fixed to https and the
// host is the one the client already connected to.
http.Redirect(w, req, buildHTTPSRedirectURL(req, opts.HTTPSPort), http.StatusFound) //nolint:gosec // G710
}), }),
ReadHeaderTimeout: 60 * time.Second, ReadHeaderTimeout: 60 * time.Second,
} }

View File

@@ -70,7 +70,7 @@ func (w *logCapture) String() string {
// levels parses the captured JSON log output and returns the level of each entry. // levels parses the captured JSON log output and returns the level of each entry.
func (w *logCapture) levels() []charmlog.Level { func (w *logCapture) levels() []charmlog.Level {
var levels []charmlog.Level var levels []charmlog.Level
for _, line := range strings.Split(strings.TrimSpace(w.String()), "\n") { for line := range strings.SplitSeq(strings.TrimSpace(w.String()), "\n") {
if line == "" { if line == "" {
continue continue
} }

View File

@@ -164,9 +164,8 @@ func (w *RotateFileWriter) cleanupOldLogs(now time.Time) {
} }
name := f.Name() name := f.Name()
if strings.HasPrefix(name, base+".") {
// Extract date from filename (base.YYYY-MM-DD) // Extract date from filename (base.YYYY-MM-DD)
dateStr := strings.TrimPrefix(name, base+".") if dateStr, ok := strings.CutPrefix(name, base+"."); ok {
if len(dateStr) == 10 { if len(dateStr) == 10 {
fileDate, err := time.Parse("2006-01-02", dateStr) fileDate, err := time.Parse("2006-01-02", dateStr)
if err == nil && fileDate.Before(cutoffDate) { if err == nil && fileDate.Before(cutoffDate) {

View File

@@ -15,7 +15,9 @@
package vhost package vhost
import ( import (
"net"
"net/http" "net/http"
"net/url"
"strconv" "strconv"
"sync" "sync"
@@ -73,11 +75,19 @@ func (r *HTTPSRedirector) Redirect(rw http.ResponseWriter, req *http.Request) bo
return false return false
} }
target := "https://" + host target := url.URL{
if r.port != 443 { Scheme: "https",
target += ":" + strconv.Itoa(r.port) Host: host,
Path: req.URL.Path,
RawPath: req.URL.RawPath,
RawQuery: req.URL.RawQuery,
} }
target += req.URL.RequestURI() if r.port != 443 {
http.Redirect(rw, req, target, http.StatusMovedPermanently) target.Host = net.JoinHostPort(host, strconv.Itoa(r.port))
}
// Not an open redirect: the host is validated against the registered
// domain set above, the scheme is fixed, and only the same-host path and
// query are echoed back.
http.Redirect(rw, req, target.String(), http.StatusMovedPermanently) //nolint:gosec // G710
return true return true
} }