Skip to content

Commit

Permalink
Merge pull request #3470 from slahirucd7/choreo
Browse files Browse the repository at this point in the history
Resource path content length validation
  • Loading branch information
slahirucd7 authored Dec 12, 2023
2 parents b047f0b + 483694d commit e1a23b2
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions adapter/config/default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ var defaultConfig = &Config{
SecuredListenerPort: 9095,
ClusterTimeoutInSeconds: 20,
EnforcerResponseTimeoutInSeconds: 20,
MaximumResourcePathLengthInKB: -1,
KeyStore: keystore{
KeyPath: "/home/wso2/security/keystore/mg.key",
CertPath: "/home/wso2/security/keystore/mg.pem",
Expand Down
1 change: 1 addition & 0 deletions adapter/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type envoy struct {
Upstream envoyUpstream
Connection connection
RateLimit rateLimit
MaximumResourcePathLengthInKB int16
}

type connectionTimeouts struct {
Expand Down
6 changes: 6 additions & 0 deletions adapter/internal/oasparser/model/open_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/getkin/kin-openapi/openapi3"
"github.com/google/uuid"
"github.com/wso2/product-microgateway/adapter/config"
logger "github.com/wso2/product-microgateway/adapter/internal/loggers"
)

Expand Down Expand Up @@ -130,7 +131,12 @@ func setResourcesOpenAPI(openAPI openapi3.Swagger) ([]*Resource, error) {
// resource level if vendor ext is not present at each resource level.
val, found := resolveDisableSecurity(openAPI.ExtensionProps)
if openAPI.Paths != nil {
conf, _ := config.ReadConfigs()
for path, pathItem := range openAPI.Paths {
if conf.Envoy.MaximumResourcePathLengthInKB != -1 &&
isResourcePathLimitExceeds(path, int(conf.Envoy.MaximumResourcePathLengthInKB)) {
return nil, errors.New("path: " + path + " exceeds maximum allowed length")
}
// Checks for resource level security. (security is disabled in resource level using x-wso2-disable-security extension)
isResourceLvlSecurityDisabled, foundInResourceLevel := resolveDisableSecurity(pathItem.ExtensionProps)
methodsArray := make([]*Operation, len(pathItem.Operations()))
Expand Down
16 changes: 13 additions & 3 deletions adapter/internal/oasparser/model/swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/go-openapi/spec"
"github.com/google/uuid"
"github.com/wso2/product-microgateway/adapter/config"
logger "github.com/wso2/product-microgateway/adapter/internal/loggers"
)

Expand All @@ -44,7 +45,11 @@ func (swagger *MgwSwagger) SetInfoSwagger(swagger2 spec.Swagger) error {
swagger.vendorExtensions = swagger2.VendorExtensible.Extensions
swagger.securityScheme = setSecurityDefinitions(swagger2)
swagger.security = swagger2.Security
swagger.resources = setResourcesSwagger(swagger2)
parsedResources, resourceParsingError := setResourcesSwagger(swagger2)
if resourceParsingError != nil {
return errors.New("one of the resource paths in the swagger definition exceeds maximum allowed content length")
}
swagger.resources = parsedResources
swagger.apiType = HTTP
swagger.xWso2Basepath = swagger2.BasePath
// According to the definition, multiple schemes can be mentioned. Since the microgateway can assign only one scheme
Expand Down Expand Up @@ -80,13 +85,18 @@ func (swagger *MgwSwagger) SetInfoSwagger(swagger2 spec.Swagger) error {
}

// setResourcesSwagger sets swagger (openapi v2) paths as mgwSwagger resources.
func setResourcesSwagger(swagger2 spec.Swagger) []*Resource {
func setResourcesSwagger(swagger2 spec.Swagger) ([]*Resource, error) {
var resources []*Resource
// Check if the "x-wso2-disable-security" vendor ext is present at the API level.
// If API level vendor ext is present, then the same key:value should be added to
// resourve level, if it's not present at resource level using "addResourceLevelDisableSecurity"
if swagger2.Paths != nil {
conf, _ := config.ReadConfigs()
for path, pathItem := range swagger2.Paths.Paths {
if conf.Envoy.MaximumResourcePathLengthInKB != -1 &&
isResourcePathLimitExceeds(path, int(conf.Envoy.MaximumResourcePathLengthInKB)) {
return nil, errors.New("path: " + path + " exceeds maximum allowed length")
}
disableSecurity, found := swagger2.VendorExtensible.Extensions.GetBool(xWso2DisableSecurity)
// Checks for resource level security, if security is disabled in resource level,
// below code segment will override above two variable values (disableSecurity & found)
Expand Down Expand Up @@ -161,7 +171,7 @@ func setResourcesSwagger(swagger2 spec.Swagger) []*Resource {
}
}
}
return SortResources(resources)
return SortResources(resources), nil
}

// Sets security definitions defined in swagger 2 format.
Expand Down
3 changes: 2 additions & 1 deletion adapter/internal/oasparser/model/swagger_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ func TestSetResourcesSwagger(t *testing.T) {
},
}
for _, item := range dataItems {
resultResources := setResourcesSwagger(item.input)
parsedResources, _ := setResourcesSwagger(item.input)
resultResources := parsedResources
if item.result != nil {
assert.Equal(t, item.result[0].path, resultResources[0].GetPath(), item.message)
resultResources[0].GetMethod()[0].iD = item.result[0].methods[0].iD
Expand Down
8 changes: 8 additions & 0 deletions adapter/internal/oasparser/model/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,11 @@ func createDefaultAPIYaml() APIYaml {
},
}
}

func isResourcePathLimitExceeds(path string, maximumAllowedResourceLength int) bool {
strLength := len(path)
if float32(strLength)/1024 > float32(maximumAllowedResourceLength) {
return true
}
return false
}
2 changes: 2 additions & 0 deletions resources/conf/config.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ sandboxVhost = "sandbox.host"
systemHost = "localhost"
# Hostname for API Resources exposed within the cluster (eg: /.wellknown/jwks and /testkey)
internalServiceHost = "localhost"
# Allowed maximum resource path content size in KB
maximumResourcePathLengthInKB = -1

# Configurations of key store used in Choreo Connect Router
[router.keystore]
Expand Down

0 comments on commit e1a23b2

Please sign in to comment.