0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2024-12-16 21:56:43 -05:00

Add option to disable following redirects (#237)

When redirects are followed, ensure that they are still allowed per AllowHosts/DenyHosts
This commit is contained in:
Blake Stoddard 2020-09-10 04:40:59 -04:00 committed by GitHub
parent 32a8bea35f
commit 52f4360543
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 1 deletions

View file

@ -48,6 +48,7 @@ var allowHosts = flag.String("allowHosts", "", "comma separated list of allowed
var denyHosts = flag.String("denyHosts", "", "comma separated list of denied remote hosts") var denyHosts = flag.String("denyHosts", "", "comma separated list of denied remote hosts")
var referrers = flag.String("referrers", "", "comma separated list of allowed referring hosts") var referrers = flag.String("referrers", "", "comma separated list of allowed referring hosts")
var includeReferer = flag.Bool("includeReferer", false, "include referer header in remote requests") var includeReferer = flag.Bool("includeReferer", false, "include referer header in remote requests")
var followRedirects = flag.Bool("followRedirects", true, "follow redirects")
var baseURL = flag.String("baseURL", "", "default base URL for relative remote URLs") var baseURL = flag.String("baseURL", "", "default base URL for relative remote URLs")
var cache tieredCache var cache tieredCache
var signatureKeys signatureKeyList var signatureKeys signatureKeyList
@ -90,6 +91,7 @@ func main() {
} }
p.IncludeReferer = *includeReferer p.IncludeReferer = *includeReferer
p.FollowRedirects = *followRedirects
p.Timeout = *timeout p.Timeout = *timeout
p.ScaleUp = *scaleUp p.ScaleUp = *scaleUp
p.Verbose = *verbose p.Verbose = *verbose

View file

@ -63,6 +63,9 @@ type Proxy struct {
// is included in remote requests. // is included in remote requests.
IncludeReferer bool IncludeReferer bool
// FollowRedirects controls whether imageproxy will follow redirects or not.
FollowRedirects bool
// DefaultBaseURL is the URL that relative remote URLs are resolved in // DefaultBaseURL is the URL that relative remote URLs are resolved in
// reference to. If nil, all remote URLs specified in requests must be // reference to. If nil, all remote URLs specified in requests must be
// absolute. // absolute.
@ -186,6 +189,21 @@ func (p *Proxy) serveImage(w http.ResponseWriter, r *http.Request) {
// pass along the referer header from the original request // pass along the referer header from the original request
copyHeader(actualReq.Header, r.Header, "referer") copyHeader(actualReq.Header, r.Header, "referer")
} }
if p.FollowRedirects {
// FollowRedirects is true (default), ensure that the redirected host is allowed
p.Client.CheckRedirect = func(newreq *http.Request, via []*http.Request) error {
if hostMatches(p.DenyHosts, newreq.URL) || (len(p.AllowHosts) > 0 && !hostMatches(p.AllowHosts, newreq.URL)) {
http.Error(w, msgNotAllowedInRedirect, http.StatusForbidden)
return errNotAllowed
}
return nil
}
} else {
// FollowRedirects is false, don't follow redirects
p.Client.CheckRedirect = func(newreq *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
}
resp, err := p.Client.Do(actualReq) resp, err := p.Client.Do(actualReq)
if err != nil { if err != nil {
@ -271,7 +289,8 @@ var (
errDeniedHost = errors.New("request contains a denied host") errDeniedHost = errors.New("request contains a denied host")
errNotAllowed = errors.New("request does not contain an allowed host or valid signature") errNotAllowed = errors.New("request does not contain an allowed host or valid signature")
msgNotAllowed = "requested URL is not allowed" msgNotAllowed = "requested URL is not allowed"
msgNotAllowedInRedirect = "requested URL in redirect is not allowed"
) )
// allowed determines whether the specified request contains an allowed // allowed determines whether the specified request contains an allowed