aboutsummaryrefslogtreecommitdiffstats
path: root/modules/hostmatcher
diff options
context:
space:
mode:
authorJason Song <i@wolfogre.com>2023-10-18 17:44:36 +0800
committerGitHub <noreply@github.com>2023-10-18 09:44:36 +0000
commit4e98224a4501238286ee3fd5ed911958951da9b0 (patch)
tree462c9e987f18ecd2fa2e23a302a277149ce9c3c0 /modules/hostmatcher
parent8abc1aae4ab5b03be0bcbdd390bb903b54ccd21a (diff)
downloadgitea-4e98224a4501238286ee3fd5ed911958951da9b0.tar.gz
gitea-4e98224a4501238286ee3fd5ed911958951da9b0.zip
Support allowed hosts for webhook to work with proxy (#27655)
When `webhook.PROXY_URL` has been set, the old code will check if the proxy host is in `ALLOWED_HOST_LIST` or reject requests through the proxy. It requires users to add the proxy host to `ALLOWED_HOST_LIST`. However, it actually allows all requests to any port on the host, when the proxy host is probably an internal address. But things may be even worse. `ALLOWED_HOST_LIST` doesn't really work when requests are sent to the allowed proxy, and the proxy could forward them to any hosts. This PR fixes it by: - If the proxy has been set, always allow connectioins to the host and port. - Check `ALLOWED_HOST_LIST` before forwarding.
Diffstat (limited to 'modules/hostmatcher')
-rw-r--r--modules/hostmatcher/http.go18
1 files changed, 15 insertions, 3 deletions
diff --git a/modules/hostmatcher/http.go b/modules/hostmatcher/http.go
index 65f5f78b14..c743f6efb3 100644
--- a/modules/hostmatcher/http.go
+++ b/modules/hostmatcher/http.go
@@ -7,12 +7,17 @@ import (
"context"
"fmt"
"net"
+ "net/url"
"syscall"
"time"
)
// NewDialContext returns a DialContext for Transport, the DialContext will do allow/block list check
func NewDialContext(usage string, allowList, blockList *HostMatchList) func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return NewDialContextWithProxy(usage, allowList, blockList, nil)
+}
+
+func NewDialContextWithProxy(usage string, allowList, blockList *HostMatchList, proxy *url.URL) func(ctx context.Context, network, addr string) (net.Conn, error) {
// How Go HTTP Client works with redirection:
// transport.RoundTrip URL=http://domain.com, Host=domain.com
// transport.DialContext addrOrHost=domain.com:80
@@ -26,11 +31,18 @@ func NewDialContext(usage string, allowList, blockList *HostMatchList) func(ctx
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
- Control: func(network, ipAddr string, c syscall.RawConn) (err error) {
- var host string
- if host, _, err = net.SplitHostPort(addrOrHost); err != nil {
+ Control: func(network, ipAddr string, c syscall.RawConn) error {
+ host, port, err := net.SplitHostPort(addrOrHost)
+ if err != nil {
return err
}
+ if proxy != nil {
+ // Always allow the host of the proxy, but only on the specified port.
+ if host == proxy.Hostname() && port == proxy.Port() {
+ return nil
+ }
+ }
+
// in Control func, the addr was already resolved to IP:PORT format, there is no cost to do ResolveTCPAddr here
tcpAddr, err := net.ResolveTCPAddr(network, ipAddr)
if err != nil {