diff --git a/internal/plugin/manager.go b/internal/plugin/manager.go index 7aad027..bd6170b 100644 --- a/internal/plugin/manager.go +++ b/internal/plugin/manager.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "net" "net/http" "net/url" "os" @@ -16,6 +17,7 @@ import ( "runtime" "sort" "strings" + "syscall" "time" "github.com/himattm/prism/internal/fsutil" @@ -468,7 +470,32 @@ func (m *Manager) addFromDirectURL(rawURL string) error { return fmt.Errorf("unsupported URL scheme: %s", parsedURL.Scheme) } - resp, err := http.Get(parsedURL.String()) + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.DisableKeepAlives = true + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + Control: func(network, address string, c syscall.RawConn) error { + host, _, err := net.SplitHostPort(address) + if err != nil { + return err + } + if idx := strings.IndexByte(host, '%'); idx != -1 { + host = host[:idx] + } + ip := net.ParseIP(host) + if ip != nil && ip.String() == "169.254.169.254" { + return fmt.Errorf("access to cloud metadata IP is forbidden") + } + return nil + }, + } + transport.DialContext = dialer.DialContext + client := &http.Client{ + Timeout: 10 * time.Second, + Transport: transport, + } + resp, err := client.Get(parsedURL.String()) if err != nil { return fmt.Errorf("failed to fetch plugin: %w", err) }