diff --git a/README.md b/README.md index 61ff57e..37e8916 100644 --- a/README.md +++ b/README.md @@ -183,19 +183,28 @@ Reload the [codercat URL][], and you should now get an error message. You can specify multiple hosts as a comma separated list, or prefix a host value with `*.` to allow all sub-domains as well. -### Allowed Hosts List ### +### Allowed and Denied Hosts List ### You can limit the remote hosts that the proxy will fetch images from using the -`allowHosts` flag. This is useful, for example, for locking the proxy down to -your own hosts to prevent others from abusing it. Of course if you want to -support fetching from any host, leave off the allowHosts flag. Try it out by -running: +`allowHosts` and `denyHosts` flags. This is useful, for example, for locking +the proxy down to your own hosts to prevent others from abusing it. Of course +if you want to support fetching from any host, leave off these flags. + +Try it out by running: imageproxy -allowHosts example.com -Reload the [codercat URL][], and you should now get an error message. You can -specify multiple hosts as a comma separated list, or prefix a host value with -`*.` to allow all sub-domains as well. +Reload the [codercat URL][], and you should now get an error message. +Alternately, try running: + + imageproxy -denyHosts octodex.github.com + +Reloading the [codercat URL][] will still return an error message. + +You can specify multiple hosts as a comma separated list to either flag, or +prefix a host value with `*.` to allow or deny all sub-domains as well. + +If a host matches both an allowed an a denied host, the request will be denied. ### Allowed Content-Type List ### diff --git a/cmd/imageproxy/main.go b/cmd/imageproxy/main.go index 175e538..3778bac 100644 --- a/cmd/imageproxy/main.go +++ b/cmd/imageproxy/main.go @@ -44,6 +44,7 @@ const defaultMemorySize = 100 var addr = flag.String("addr", "localhost:8080", "TCP address to listen on") var allowHosts = flag.String("allowHosts", "", "comma separated list of allowed remote hosts") var whitelist = flag.String("whitelist", "", "deprecated. use 'allowHosts' instead") +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 baseURL = flag.String("baseURL", "", "default base URL for relative remote URLs") var cache tieredCache @@ -70,6 +71,9 @@ func main() { if *allowHosts != "" { p.AllowHosts = strings.Split(*allowHosts, ",") } + if *denyHosts != "" { + p.DenyHosts = strings.Split(*denyHosts, ",") + } if *referrers != "" { p.Referrers = strings.Split(*referrers, ",") } diff --git a/imageproxy.go b/imageproxy.go index f2dbcca..3959f5f 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -49,6 +49,10 @@ type Proxy struct { // Whitelist should no longer be used. Use "AllowHosts" instead. Whitelist []string + // DenyHosts specifies a list of remote hosts that images cannot be + // proxied from. + DenyHosts []string + // Referrers, when given, requires that requests to the image // proxy come from a referring host. An empty list means all // hosts are allowed. @@ -225,6 +229,10 @@ func (p *Proxy) allowed(r *Request) error { return fmt.Errorf("request does not contain an allowed referrer: %v", r) } + if validHost(p.DenyHosts, r.URL) { + return fmt.Errorf("request contains a denied host %v", r) + } + if len(p.AllowHosts) == 0 && len(p.SignatureKey) == 0 { return nil // no allowed hosts or signature key, all requests accepted }