mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-05-12 16:09:53 +00:00
validate the Redirect_URI
This commit is contained in:
@@ -2,8 +2,11 @@
|
||||
|
||||
package frontend
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
)
|
||||
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) error {
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc, oidcService *service.OidcService) error {
|
||||
return ErrFrontendNotIncluded
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package frontend
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -17,6 +18,8 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/middleware"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/service"
|
||||
"github.com/pocket-id/pocket-id/backend/internal/utils"
|
||||
)
|
||||
|
||||
//go:embed all:dist/*
|
||||
@@ -54,7 +57,28 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) error {
|
||||
// validateRedirectURI validates that the redirect_uri is in the client's allowed callback URLs
|
||||
func validateRedirectURI(ctx any, oidcService *service.OidcService, clientID, redirectURI string) (bool, error) {
|
||||
client, err := oidcService.GetClient(ctx.(context.Context), clientID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If the client has no callback URLs configured, reject the redirect URI
|
||||
if len(client.CallbackURLs) == 0 {
|
||||
return false, fmt.Errorf("client has no callback URLs configured")
|
||||
}
|
||||
|
||||
// Validate the redirect URI against the client's callback URLs
|
||||
_, err = utils.GetCallbackURLFromList(client.CallbackURLs, redirectURI)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc, oidcService *service.OidcService) error {
|
||||
distFS, err := fs.Sub(frontendFS, "dist")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create sub FS: %w", err)
|
||||
@@ -92,12 +116,17 @@ func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) e
|
||||
|
||||
if path == "index.html" {
|
||||
// Check if this is an OAuth2 authorization request with response_mode=form_post
|
||||
// In that case, we need to allow form submissions to the redirect_uri
|
||||
// In that case, we need to validate and allow form submissions to the redirect_uri
|
||||
responseMode := c.Query("response_mode")
|
||||
redirectURI := c.Query("redirect_uri")
|
||||
if responseMode == "form_post" && redirectURI != "" {
|
||||
// Set the allowed form-action in CSP to include the redirect URI
|
||||
middleware.SetAllowedFormAction(c, redirectURI)
|
||||
clientID := c.Query("client_id")
|
||||
if responseMode == "form_post" && redirectURI != "" && clientID != "" {
|
||||
// Validate the redirect_uri against the client's allowlist
|
||||
isValid, err := validateRedirectURI(c.Request.Context(), oidcService, clientID, redirectURI)
|
||||
if err == nil && isValid {
|
||||
// Set the allowed form-action in CSP to include the redirect URI
|
||||
middleware.SetAllowedFormAction(c, redirectURI)
|
||||
}
|
||||
}
|
||||
|
||||
nonce := middleware.GetCSPNonce(c)
|
||||
|
||||
@@ -61,7 +61,7 @@ func initRouter(db *gorm.DB, svc *services) (utils.Service, error) {
|
||||
r.Use(middleware.NewErrorHandlerMiddleware().Add())
|
||||
|
||||
frontendRateLimitMiddleware := middleware.NewRateLimitMiddleware().Add(rate.Every(100*time.Millisecond), 300)
|
||||
err := frontend.RegisterFrontend(r, frontendRateLimitMiddleware)
|
||||
err := frontend.RegisterFrontend(r, frontendRateLimitMiddleware, svc.oidcService)
|
||||
if errors.Is(err, frontend.ErrFrontendNotIncluded) {
|
||||
slog.Warn("Frontend is not included in the build. Skipping frontend registration.")
|
||||
} else if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user