Skip to content

Commit

Permalink
add cors check (#4725)
Browse files Browse the repository at this point in the history
* add cors check

Signed-off-by: Shovan Maity <[email protected]>

* add cors check custom middleware

Signed-off-by: Shovan Maity <[email protected]>

* change default url

Signed-off-by: Shovan Maity <[email protected]>

---------

Signed-off-by: Shovan Maity <[email protected]>
Signed-off-by: Shovan Maity <[email protected]>
  • Loading branch information
shovanmaity authored Jun 25, 2024
1 parent 902cfde commit 17085b4
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 71 deletions.
28 changes: 12 additions & 16 deletions chaoscenter/authentication/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

grpcHandler "github.com/litmuschaos/litmus/chaoscenter/authentication/api/handlers/grpc"
"github.com/litmuschaos/litmus/chaoscenter/authentication/api/middleware"
grpcPresenter "github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter/protos"
"github.com/litmuschaos/litmus/chaoscenter/authentication/api/routes"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/entities"
Expand All @@ -20,7 +21,6 @@ import (

"google.golang.org/grpc"

"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/kelseyhightower/envconfig"
Expand All @@ -29,22 +29,22 @@ import (
)

type Config struct {
JwtSecret string `required:"true" split_words:"true"`
AdminUsername string `required:"true" split_words:"true"`
AdminPassword string `required:"true" split_words:"true"`
DbServer string `required:"true" split_words:"true"`
DbUser string `required:"true" split_words:"true"`
DbPassword string `required:"true" split_words:"true"`
JwtSecret string `required:"true" split_words:"true"`
AdminUsername string `required:"true" split_words:"true"`
AdminPassword string `required:"true" split_words:"true"`
DbServer string `required:"true" split_words:"true"`
DbUser string `required:"true" split_words:"true"`
DbPassword string `required:"true" split_words:"true"`
AllowedOrigins []string `split_words:"true" default:"litmuschaos.io?,localhost:([0-9]+)?"`
}

var config Config

func init() {
log.SetFormatter(&log.JSONFormatter{})
log.SetReportCaller(true)
printVersion()

var c Config

err := envconfig.Process("", &c)
err := envconfig.Process("", &config)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -158,11 +158,7 @@ func runRestServer(applicationService services.ApplicationService) {
gin.SetMode(gin.ReleaseMode)
gin.EnableJsonDecoderDisallowUnknownFields()
app := gin.Default()
app.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowHeaders: []string{"*"},
AllowCredentials: true,
}))
app.Use(middleware.ValidateCors(config.AllowedOrigins))
// Enable dex routes only if passed via environment variables
if utils.DexEnabled {
routes.DexRouter(app, applicationService)
Expand Down
55 changes: 55 additions & 0 deletions chaoscenter/authentication/api/middleware/cors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package middleware

import (
"net/http"
"regexp"
"strings"

"github.com/gin-gonic/gin"
)

const (
AllowedOrigin string = "Access-Control-Allow-Origin"
AllowedMethods string = "Access-Control-Allow-Methods"
AllowedHeaders string = "Access-Control-Allow-Headers"
AllowedCredentials string = "Access-Control-Allow-Credentials"
)

func ValidateCors(allowedOrigins []string) gin.HandlerFunc {
return func(c *gin.Context) {
origin := c.GetHeader("Origin")
if origin == "" {
origin = c.Request.Host
}

validOrigin := false
for _, allowedOrigin := range allowedOrigins {
match, err := regexp.MatchString(allowedOrigin, origin)
if err == nil && match {
validOrigin = true
c.Writer.Header().Set(AllowedOrigin, origin)
break
}
}

if !validOrigin {
c.JSON(http.StatusForbidden, gin.H{
"error": "Invalid origin",
})
c.Abort()
return
}

c.Writer.Header().Set(AllowedMethods, strings.Join([]string{
"GET",
"POST",
"PUT",
"DELETE",
"OPTIONS",
}, ","))
c.Writer.Header().Set(AllowedHeaders, "*")
c.Writer.Header().Set(AllowedCredentials, "true")

c.Next()
}
}
3 changes: 1 addition & 2 deletions chaoscenter/authentication/go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module github.com/litmuschaos/litmus/chaoscenter/authentication

go 1.22
go 1.22.0

require (
github.com/coreos/go-oidc/v3 v3.1.0
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.4
Expand Down
2 changes: 0 additions & 2 deletions chaoscenter/authentication/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw=
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
Expand Down
57 changes: 57 additions & 0 deletions chaoscenter/graphql/server/api/middleware/cors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package middleware

import (
"net/http"
"regexp"
"strings"

"github.com/gin-gonic/gin"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/utils"
)

const (
AllowedOrigin string = "Access-Control-Allow-Origin"
AllowedMethods string = "Access-Control-Allow-Methods"
AllowedHeaders string = "Access-Control-Allow-Headers"
AllowedCredentials string = "Access-Control-Allow-Credentials"
)

func ValidateCors() gin.HandlerFunc {
return func(c *gin.Context) {
allowedOrigins := utils.Config.AllowedOrigins
origin := c.GetHeader("Origin")
if origin == "" {
origin = c.Request.Host
}

validOrigin := false
for _, allowedOrigin := range allowedOrigins {
match, err := regexp.MatchString(allowedOrigin, origin)
if err == nil && match {
validOrigin = true
c.Writer.Header().Set(AllowedOrigin, origin)
break
}
}

if !validOrigin {
c.JSON(http.StatusForbidden, gin.H{
"error": "Invalid origin",
})
c.Abort()
return
}

c.Writer.Header().Set(AllowedMethods, strings.Join([]string{
"GET",
"POST",
"PUT",
"DELETE",
"OPTIONS",
}, ","))
c.Writer.Header().Set(AllowedHeaders, "*")
c.Writer.Header().Set(AllowedCredentials, "true")

c.Next()
}
}
3 changes: 1 addition & 2 deletions chaoscenter/graphql/server/go.mod
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
module github.com/litmuschaos/litmus/chaoscenter/graphql/server

go 1.22
go 1.22.0

require (
github.com/99designs/gqlgen v0.17.47
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24
github.com/argoproj/argo-workflows/v3 v3.3.5
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0
github.com/go-git/go-git/v5 v5.12.0
github.com/golang-jwt/jwt v3.2.2+incompatible
Expand Down
2 changes: 0 additions & 2 deletions chaoscenter/graphql/server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,6 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw=
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
Expand Down
21 changes: 13 additions & 8 deletions chaoscenter/graphql/server/server.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package main

import (
"regexp"
"strconv"

"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/api/middleware"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaoshub"
Expand Down Expand Up @@ -80,12 +80,7 @@ func setupGin() *gin.Engine {
router := gin.New()
router.Use(middleware.DefaultStructuredLogger())
router.Use(gin.Recovery())
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowHeaders: []string{"*"},
AllowCredentials: true,
}))

router.Use(middleware.ValidateCors())
return router
}

Expand Down Expand Up @@ -114,7 +109,17 @@ func main() {
KeepAlivePingInterval: 10 * time.Second,
Upgrader: websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
origin := r.Header.Get("Origin")
if origin == "" {
origin = r.Host
}
for _, allowedOrigin := range utils.Config.AllowedOrigins {
match, err := regexp.MatchString(allowedOrigin, origin)
if err == nil && match {
return true
}
}
return false
},
},
})
Expand Down
79 changes: 40 additions & 39 deletions chaoscenter/graphql/server/utils/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,46 @@ var (
)

type Configuration struct {
Version string `required:"true"`
InfraDeployments string `required:"true" split_words:"true"`
DbServer string `required:"true" split_words:"true"`
JwtSecret string `required:"true" split_words:"true"`
LitmusPortalNamespace string `required:"true" split_words:"true"`
DbUser string `required:"true" split_words:"true"`
DbPassword string `required:"true" split_words:"true"`
ChaosCenterScope string `required:"true" split_words:"true"`
SubscriberImage string `required:"true" split_words:"true"`
EventTrackerImage string `required:"true" split_words:"true"`
ArgoWorkflowControllerImage string `required:"true" split_words:"true"`
ArgoWorkflowExecutorImage string `required:"true" split_words:"true"`
LitmusChaosOperatorImage string `required:"true" split_words:"true"`
LitmusChaosRunnerImage string `required:"true" split_words:"true"`
LitmusChaosExporterImage string `required:"true" split_words:"true"`
ContainerRuntimeExecutor string `required:"true" split_words:"true"`
WorkflowHelperImageVersion string `required:"true" split_words:"true"`
ServerServiceName string `split_words:"true"`
NodeName string `split_words:"true"`
Ingress string `split_words:"true"`
IngressName string `split_words:"true"`
ChaosCenterUiEndpoint string `split_words:"true" default:"localhost:8080"`
TlsCertB64 string `split_words:"true"`
TlsSecretName string `split_words:"true"`
LitmusAuthGrpcEndpoint string `split_words:"true" default:"localhost"`
LitmusAuthGrpcPort string `split_words:"true" default:":3030"`
KubeConfigFilePath string `split_words:"true"`
RemoteHubMaxSize string `split_words:"true"`
SkipSslVerify string `split_words:"true"`
SelfInfraNodeSelector string `split_words:"true"`
SelfInfraTolerations string `split_words:"true"`
HttpPort string `split_words:"true" default:"8080"`
RpcPort string `split_words:"true" default:"8000"`
InfraCompatibleVersions string `required:"true" split_words:"true"`
DefaultHubGitURL string `required:"true" default:"https://github.com/litmuschaos/chaos-charts"`
DefaultHubBranchName string `required:"true" split_words:"true"`
CustomChaosHubPath string `split_words:"true" default:"/tmp/"`
DefaultChaosHubPath string `split_words:"true" default:"/tmp/default/"`
EnableGQLIntrospection string `split_words:"true" default:"false"`
Version string `required:"true"`
InfraDeployments string `required:"true" split_words:"true"`
DbServer string `required:"true" split_words:"true"`
JwtSecret string `required:"true" split_words:"true"`
LitmusPortalNamespace string `required:"true" split_words:"true"`
DbUser string `required:"true" split_words:"true"`
DbPassword string `required:"true" split_words:"true"`
ChaosCenterScope string `required:"true" split_words:"true"`
SubscriberImage string `required:"true" split_words:"true"`
EventTrackerImage string `required:"true" split_words:"true"`
ArgoWorkflowControllerImage string `required:"true" split_words:"true"`
ArgoWorkflowExecutorImage string `required:"true" split_words:"true"`
LitmusChaosOperatorImage string `required:"true" split_words:"true"`
LitmusChaosRunnerImage string `required:"true" split_words:"true"`
LitmusChaosExporterImage string `required:"true" split_words:"true"`
ContainerRuntimeExecutor string `required:"true" split_words:"true"`
WorkflowHelperImageVersion string `required:"true" split_words:"true"`
ServerServiceName string `split_words:"true"`
NodeName string `split_words:"true"`
Ingress string `split_words:"true"`
IngressName string `split_words:"true"`
ChaosCenterUiEndpoint string `split_words:"true" default:"localhost:8080"`
TlsCertB64 string `split_words:"true"`
TlsSecretName string `split_words:"true"`
LitmusAuthGrpcEndpoint string `split_words:"true" default:"localhost"`
LitmusAuthGrpcPort string `split_words:"true" default:":3030"`
KubeConfigFilePath string `split_words:"true"`
RemoteHubMaxSize string `split_words:"true"`
SkipSslVerify string `split_words:"true"`
SelfInfraNodeSelector string `split_words:"true"`
SelfInfraTolerations string `split_words:"true"`
HttpPort string `split_words:"true" default:"8080"`
RpcPort string `split_words:"true" default:"8000"`
InfraCompatibleVersions string `required:"true" split_words:"true"`
DefaultHubGitURL string `required:"true" default:"https://github.com/litmuschaos/chaos-charts"`
DefaultHubBranchName string `required:"true" split_words:"true"`
CustomChaosHubPath string `split_words:"true" default:"/tmp/"`
DefaultChaosHubPath string `split_words:"true" default:"/tmp/default/"`
EnableGQLIntrospection string `split_words:"true" default:"false"`
AllowedOrigins []string `split_words:"true" default:"litmuschaos.io?,localhost:([0-9]+)?"`
}

var Config Configuration

0 comments on commit 17085b4

Please sign in to comment.