mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
MM-69213: Validate Azure storage account names and use httpservice for custom endpoints (#37014)
* Validate Azure storage account name format For the commercial and government clouds the storage account name becomes part of the service hostname, so enforce Azure's documented format (3 to 24 lowercase letters and digits) both in config validation and when building the service URL. Also treat an empty AzureCloud as commercial, consistent with the URL builder. * Route Azure custom endpoints through httpservice The Azure custom-cloud backend now issues requests through httpservice's transport rather than the SDK default, so they honor ServiceSettings.AllowedUntrustedInternalConnections like other outbound connections. The commercial and government clouds keep the SDK default transport, which Private Link deployments rely on. The allowlist value is plumbed into FileBackendSettings, and the host/IP checks are factored into a shared httpservice helper that MakeTransport now uses too.
This commit is contained in:
committed by
GitHub
parent
0a497aa3e8
commit
82106eb77e
@@ -71,6 +71,58 @@ func (h *HTTPServiceImpl) MakeClient(trustURLs bool) *http.Client {
|
||||
}
|
||||
}
|
||||
|
||||
// isAllowedInternalHost reports whether host appears verbatim in a
|
||||
// space/comma-separated AllowedUntrustedInternalConnections value.
|
||||
func isAllowedInternalHost(host, allowedUntrustedInternalConnections string) bool {
|
||||
return slices.Contains(strings.FieldsFunc(allowedUntrustedInternalConnections, splitFields), host)
|
||||
}
|
||||
|
||||
// checkInternalIP returns nil if ip may be dialed, or an error if it is a
|
||||
// reserved-range or self-assigned IP not covered by a CIDR entry in the
|
||||
// space/comma-separated AllowedUntrustedInternalConnections value.
|
||||
func checkInternalIP(ip net.IP, allowedUntrustedInternalConnections string) error {
|
||||
reservedIP := IsReservedIP(ip)
|
||||
|
||||
ownIP, err := IsOwnIP(ip)
|
||||
if err != nil {
|
||||
// If there is an error getting the self-assigned IPs, default to the secure option
|
||||
return fmt.Errorf("unable to determine if IP is own IP: %w", err)
|
||||
}
|
||||
|
||||
// If it's not a reserved IP and it's not self-assigned IP, accept the IP
|
||||
if !reservedIP && !ownIP {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise it needs to be explicitly added to AllowedUntrustedInternalConnections
|
||||
for _, allowed := range strings.FieldsFunc(allowedUntrustedInternalConnections, splitFields) {
|
||||
if _, ipRange, err := net.ParseCIDR(allowed); err == nil && ipRange.Contains(ip) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if reservedIP {
|
||||
return fmt.Errorf("IP %s is in a reserved range and not in AllowedUntrustedInternalConnections", ip)
|
||||
}
|
||||
return fmt.Errorf("IP %s is a self-assigned IP and not in AllowedUntrustedInternalConnections", ip)
|
||||
}
|
||||
|
||||
// NewTransportForInternalConnections returns a transport that applies the same
|
||||
// AllowedUntrustedInternalConnections filtering as MakeTransport, but takes the
|
||||
// allowlist as a static value instead of reading it from a config service. It is
|
||||
// for callers that have the allowlist string but not an HTTPService.
|
||||
func NewTransportForInternalConnections(insecure bool, allowedUntrustedInternalConnections string) *MattermostTransport {
|
||||
allowHost := func(host string) bool {
|
||||
return isAllowedInternalHost(host, allowedUntrustedInternalConnections)
|
||||
}
|
||||
|
||||
allowIP := func(ip net.IP) error {
|
||||
return checkInternalIP(ip, allowedUntrustedInternalConnections)
|
||||
}
|
||||
|
||||
return NewTransport(insecure, allowHost, allowIP)
|
||||
}
|
||||
|
||||
func (h *HTTPServiceImpl) MakeTransport(trustURLs bool) *MattermostTransport {
|
||||
insecure := h.configService.Config().ServiceSettings.EnableInsecureOutgoingConnections != nil && *h.configService.Config().ServiceSettings.EnableInsecureOutgoingConnections
|
||||
|
||||
@@ -78,38 +130,14 @@ func (h *HTTPServiceImpl) MakeTransport(trustURLs bool) *MattermostTransport {
|
||||
return NewTransport(insecure, nil, nil)
|
||||
}
|
||||
|
||||
// The allowlist is read inside the closures so a long-lived client picks up
|
||||
// config changes on each dial.
|
||||
allowHost := func(host string) bool {
|
||||
if h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections == nil {
|
||||
return false
|
||||
}
|
||||
return slices.Contains(strings.FieldsFunc(*h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections, splitFields), host)
|
||||
return isAllowedInternalHost(host, model.SafeDereference(h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections))
|
||||
}
|
||||
|
||||
allowIP := func(ip net.IP) error {
|
||||
reservedIP := IsReservedIP(ip)
|
||||
|
||||
ownIP, err := IsOwnIP(ip)
|
||||
if err != nil {
|
||||
// If there is an error getting the self-assigned IPs, default to the secure option
|
||||
return fmt.Errorf("unable to determine if IP is own IP: %w", err)
|
||||
}
|
||||
|
||||
// If it's not a reserved IP and it's not self-assigned IP, accept the IP
|
||||
if !reservedIP && !ownIP {
|
||||
return nil
|
||||
}
|
||||
|
||||
// In the case it's the self-assigned IP, enforce that it needs to be explicitly added to the AllowedUntrustedInternalConnections
|
||||
for _, allowed := range strings.FieldsFunc(model.SafeDereference(h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections), splitFields) {
|
||||
if _, ipRange, err := net.ParseCIDR(allowed); err == nil && ipRange.Contains(ip) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if reservedIP {
|
||||
return fmt.Errorf("IP %s is in a reserved range and not in AllowedUntrustedInternalConnections", ip)
|
||||
}
|
||||
return fmt.Errorf("IP %s is a self-assigned IP and not in AllowedUntrustedInternalConnections", ip)
|
||||
return checkInternalIP(ip, model.SafeDereference(h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections))
|
||||
}
|
||||
|
||||
return NewTransport(insecure, allowHost, allowIP)
|
||||
|
||||
Reference in New Issue
Block a user