MCPcopy Index your code
hub / github.com/coder/coder / validateRedirectURIs

Function validateRedirectURIs

codersdk/oauth2_validation.go:122–185  ·  view source on GitHub ↗

validateRedirectURIs validates redirect URIs according to RFC 7591, 8252

(uris []string, tokenEndpointAuthMethod OAuth2TokenEndpointAuthMethod)

Source from the content-addressed store, hash-verified

120
121// validateRedirectURIs validates redirect URIs according to RFC 7591, 8252
122func validateRedirectURIs(uris []string, tokenEndpointAuthMethod OAuth2TokenEndpointAuthMethod) error {
123 if len(uris) == 0 {
124 return xerrors.New("at least one redirect URI is required")
125 }
126
127 for i, uriStr := range uris {
128 if uriStr == "" {
129 return xerrors.Errorf("redirect URI at index %d cannot be empty", i)
130 }
131
132 uri, err := url.Parse(uriStr)
133 if err != nil {
134 return xerrors.Errorf("redirect URI at index %d is not a valid URL: %w", i, err)
135 }
136
137 if err := validateScheme(uri); err != nil {
138 return xerrors.Errorf("redirect URI at index %d: %w", i, err)
139 }
140
141 // The urn:ietf:wg:oauth:2.0:oob scheme passed validation
142 // above but needs no further checks.
143 if uri.Scheme == "urn" {
144 continue
145 }
146
147 // Determine if this is a public client based on token endpoint auth method
148 isPublicClient := tokenEndpointAuthMethod == OAuth2TokenEndpointAuthMethodNone
149
150 // Handle different validation for public vs confidential clients
151 if uri.Scheme == "http" || uri.Scheme == "https" {
152 // HTTP/HTTPS validation (RFC 8252 section 7.3)
153 if uri.Scheme == "http" {
154 if isPublicClient {
155 // For public clients, only allow loopback (RFC 8252)
156 if !isLoopbackAddress(uri.Hostname()) {
157 return xerrors.Errorf("redirect URI at index %d: public clients may only use http with loopback addresses (127.0.0.1, ::1, localhost)", i)
158 }
159 } else {
160 // For confidential clients, allow localhost for development
161 if !isLocalhost(uri.Hostname()) {
162 return xerrors.Errorf("redirect URI at index %d must use https scheme for non-localhost URLs", i)
163 }
164 }
165 }
166 } else {
167 // Custom scheme validation for public clients (RFC 8252 section 7.1)
168 if isPublicClient {
169 // For public clients, custom schemes should follow RFC 8252 recommendations
170 // Should be reverse domain notation based on domain under their control
171 if !isValidCustomScheme(uri.Scheme) {
172 return xerrors.Errorf("redirect URI at index %d: custom scheme %s should use reverse domain notation (e.g. com.example.app)", i, uri.Scheme)
173 }
174 }
175 // For confidential clients, custom schemes are less common but allowed
176 }
177
178 // Prevent URI fragments (RFC 6749 section 3.1.2)
179 if uri.Fragment != "" || strings.Contains(uriStr, "#") {

Callers 1

ValidateMethod · 0.85

Calls 8

validateSchemeFunction · 0.85
isLoopbackAddressFunction · 0.85
isLocalhostFunction · 0.85
isValidCustomSchemeFunction · 0.85
NewMethod · 0.65
ParseMethod · 0.65
ErrorfMethod · 0.45
ContainsMethod · 0.45

Tested by

no test coverage detected