mirror of
https://github.com/portainer/portainer.git
synced 2026-06-23 04:30:16 +00:00
54 lines
1.4 KiB
Go
54 lines
1.4 KiB
Go
package git
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
|
|
"github.com/portainer/portainer/pkg/libhttp/ssrf"
|
|
|
|
gittransport "github.com/go-git/go-git/v5/plumbing/transport"
|
|
)
|
|
|
|
const gitDefaultPort = 9418
|
|
|
|
// ssrfGitTransport wraps a git:// transport and validates the resolved IP
|
|
// against the SSRF policy before establishing connections.
|
|
type ssrfGitTransport struct {
|
|
inner gittransport.Transport
|
|
}
|
|
|
|
// NewSSRFGitTransport wraps inner and blocks connections to private IP ranges
|
|
// according to the active SSRF policy.
|
|
func NewSSRFGitTransport(inner gittransport.Transport) gittransport.Transport {
|
|
return &ssrfGitTransport{inner: inner}
|
|
}
|
|
|
|
func (t *ssrfGitTransport) NewUploadPackSession(ep *gittransport.Endpoint, auth gittransport.AuthMethod) (gittransport.UploadPackSession, error) {
|
|
if err := checkEndpointSSRF(ep); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return t.inner.NewUploadPackSession(ep, auth)
|
|
}
|
|
|
|
func (t *ssrfGitTransport) NewReceivePackSession(ep *gittransport.Endpoint, auth gittransport.AuthMethod) (gittransport.ReceivePackSession, error) {
|
|
if err := checkEndpointSSRF(ep); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return t.inner.NewReceivePackSession(ep, auth)
|
|
}
|
|
|
|
func checkEndpointSSRF(ep *gittransport.Endpoint) error {
|
|
port := ep.Port
|
|
if port <= 0 {
|
|
port = gitDefaultPort
|
|
}
|
|
|
|
rawURL := fmt.Sprintf("git://%s/", net.JoinHostPort(ep.Host, strconv.Itoa(port)))
|
|
|
|
return ssrf.CheckURL(context.Background(), rawURL)
|
|
}
|