[management] Refuse HTTP redirects on IdP clients (#7579)

This commit is contained in:
Bethuel Mmbaga
2026-09-24 20:48:40 +03:00
committed by GitHub
parent 15a13bc99b
commit 222c6d53e2
11 changed files with 29 additions and 73 deletions
+1 -7
View File
@@ -132,13 +132,7 @@ type ConnectionOptions struct {
// NewAuth0Manager creates a new instance of the Auth0Manager
func NewAuth0Manager(config Auth0ClientConfig, appMetrics telemetry.AppMetrics) (*Auth0Manager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -7
View File
@@ -49,13 +49,7 @@ type AuthentikCredentials struct {
// NewAuthentikManager creates a new instance of the AuthentikManager.
func NewAuthentikManager(config AuthentikClientConfig, appMetrics telemetry.AppMetrics) (*AuthentikManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -7
View File
@@ -54,13 +54,7 @@ type azureProfile map[string]any
// NewAzureManager creates a new instance of the AzureManager.
func NewAzureManager(config AzureClientConfig, appMetrics telemetry.AppMetrics) (*AzureManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -9
View File
@@ -4,10 +4,8 @@ import (
"context"
"encoding/base64"
"fmt"
"net/http"
"strings"
"sync"
"time"
"github.com/dexidp/dex/api/v2"
log "github.com/sirupsen/logrus"
@@ -44,13 +42,7 @@ func NewDexManager(config DexClientConfig, appMetrics telemetry.AppMetrics) (*De
return nil, fmt.Errorf("dex IdP configuration is incomplete, GRPCAddr is missing")
}
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: 10 * time.Second,
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
return &DexManager{
+1 -8
View File
@@ -4,7 +4,6 @@ import (
"context"
"encoding/base64"
"fmt"
"net/http"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2/google"
@@ -44,13 +43,7 @@ func (gc *GoogleWorkspaceCredentials) Authenticate(_ context.Context) (JWTToken,
// NewGoogleWorkspaceManager creates a new instance of the GoogleWorkspaceManager.
func NewGoogleWorkspaceManager(ctx context.Context, config GoogleWorkspaceClientConfig, appMetrics telemetry.AppMetrics) (*GoogleWorkspaceManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -7
View File
@@ -58,13 +58,7 @@ type JumpCloudCredentials struct {
// NewJumpCloudManager creates a new instance of the JumpCloudManager.
func NewJumpCloudManager(config JumpCloudClientConfig, appMetrics telemetry.AppMetrics) (*JumpCloudManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -7
View File
@@ -59,13 +59,7 @@ type keycloakProfile struct {
// NewKeycloakManager creates a new instance of the KeycloakManager.
func NewKeycloakManager(config KeycloakClientConfig, appMetrics telemetry.AppMetrics) (*KeycloakManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+1 -7
View File
@@ -40,13 +40,7 @@ type OktaCredentials struct {
// NewOktaManager creates a new instance of the OktaManager.
func NewOktaManager(config OktaClientConfig, appMetrics telemetry.AppMetrics) (*OktaManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
config.Issuer = baseURL(config.Issuer)
+1 -7
View File
@@ -83,13 +83,7 @@ type pocketIdUserGroupDto struct {
}
func NewPocketIdManager(config PocketIdClientConfig, appMetrics telemetry.AppMetrics) (*PocketIdManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}
+19
View File
@@ -2,6 +2,8 @@ package idp
import (
"encoding/json"
"errors"
"net/http"
"net/url"
"os"
"strings"
@@ -81,6 +83,23 @@ const (
defaultTimeout = 10 * time.Second
)
// errRedirectRefused is returned instead of http.ErrUseLastResponse so the
// client closes the redirect response rather than handing it back unread.
var errRedirectRefused = errors.New("redirect refused")
func newHTTPClient() *http.Client {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
return &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
CheckRedirect: func(*http.Request, []*http.Request) error {
return errRedirectRefused
},
}
}
// idpTimeout returns a timeout value for the IDP
func idpTimeout() time.Duration {
timeoutStr, ok := os.LookupEnv(idpTimeoutEnv)
+1 -7
View File
@@ -160,13 +160,7 @@ func verifyJWTConfig(config ZitadelClientConfig) error {
// NewZitadelManager creates a new instance of the ZitadelManager.
func NewZitadelManager(config ZitadelClientConfig, appMetrics telemetry.AppMetrics) (*ZitadelManager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
httpTransport.MaxIdleConns = 5
httpClient := &http.Client{
Timeout: idpTimeout(),
Transport: httpTransport,
}
httpClient := newHTTPClient()
helper := JsonParser{}