From b3a55a6402b53a94eb5ac7abd001bf7bdec35245 Mon Sep 17 00:00:00 2001 From: Blake Stoddard Date: Fri, 19 Jun 2020 14:26:56 -0400 Subject: [PATCH 1/3] Allow allowing/blocks hosts by IP range --- README.md | 6 ++++-- imageproxy.go | 11 +++++++++++ imageproxy_test.go | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebd573c09..c32f0ffcd 100644 --- a/README.md +++ b/README.md @@ -208,9 +208,11 @@ Alternately, try running: 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. +prefix a host value with `*.` to allow or deny all sub-domains. You can +also specify a netblock in CIDR notation (`127.0.0.0/8`) -- this is useful for +blocking reserved ranges like `127.0.0.0/8`, `192.168.0.0/16`, etc. -If a host matches both an allowed an a denied host, the request will be denied. +If a host matches both an allowed a denied host, the request will be denied. ### Allowed Content-Type List ### diff --git a/imageproxy.go b/imageproxy.go index 6721056ea..d973f2318 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -28,6 +28,7 @@ import ( "io/ioutil" "log" "mime" + "net" "net/http" "net/url" "path" @@ -324,6 +325,16 @@ func hostMatches(hosts []string, u *url.URL) bool { if strings.HasPrefix(host, "*.") && strings.HasSuffix(u.Host, host[2:]) { return true } + // Checks whether the host in u is an IP + if ip := net.ParseIP(u.Host); ip != nil { + // Checks whether our current host is a CIDR + if _, ipnet, err := net.ParseCIDR(host); err == nil { + // Checks if our host contains the IP in u + if ok := ipnet.Contains(ip) == true; ok { + return true + } + } + } } return false diff --git a/imageproxy_test.go b/imageproxy_test.go index 33267f8f2..3346724f2 100644 --- a/imageproxy_test.go +++ b/imageproxy_test.go @@ -172,6 +172,7 @@ func TestAllowed(t *testing.T) { {"http://test/image", emptyOptions, nil, []string{"test"}, nil, nil, nil, false}, {"http://test/image", emptyOptions, []string{"test"}, []string{"test"}, nil, nil, nil, false}, {"http://test/image", Options{Signature: "NDx5zZHx7QfE8E-ijowRreq6CJJBZjwiRfOVk_mkfQQ="}, nil, []string{"test"}, nil, key, nil, false}, + {"http://127.0.0.1/image", emptyOptions, nil, []string{"127.0.0.0/8"}, nil, nil, nil, false}, } for _, tt := range tests { From 4184305e80a92e70cd01854a9c5b43749877a0d4 Mon Sep 17 00:00:00 2001 From: Blake Stoddard Date: Fri, 19 Jun 2020 20:17:17 -0400 Subject: [PATCH 2/3] Actually fix the typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c32f0ffcd..02d5782e2 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ prefix a host value with `*.` to allow or deny all sub-domains. You can also specify a netblock in CIDR notation (`127.0.0.0/8`) -- this is useful for blocking reserved ranges like `127.0.0.0/8`, `192.168.0.0/16`, etc. -If a host matches both an allowed a denied host, the request will be denied. +If a host matches both an allowed and denied host, the request will be denied. ### Allowed Content-Type List ### From f646549b81a69f8d783fdd5ac6a4ee76dade0ea4 Mon Sep 17 00:00:00 2001 From: Blake Stoddard Date: Fri, 19 Jun 2020 20:18:12 -0400 Subject: [PATCH 3/3] Cleanup the conditional logic on if an IP is in a netblock --- imageproxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imageproxy.go b/imageproxy.go index d973f2318..da8aac20c 100644 --- a/imageproxy.go +++ b/imageproxy.go @@ -330,7 +330,7 @@ func hostMatches(hosts []string, u *url.URL) bool { // Checks whether our current host is a CIDR if _, ipnet, err := net.ParseCIDR(host); err == nil { // Checks if our host contains the IP in u - if ok := ipnet.Contains(ip) == true; ok { + if ipnet.Contains(ip) { return true } }