From 40c8c242906db1da8048f90b091858a8d3d895be Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 18 Aug 2025 15:01:24 +0200 Subject: [PATCH 1/2] Update jsonschema library --- api/resource_types.go | 4 ++-- go.mod | 14 +++++++------- go.sum | 42 ++++++++++++++++++++++-------------------- helper/metadata.go | 14 +++++++++----- helper/secret.go | 14 +++++++++----- 5 files changed, 49 insertions(+), 39 deletions(-) diff --git a/api/resource_types.go b/api/resource_types.go index 3bdc1bc..b643238 100644 --- a/api/resource_types.go +++ b/api/resource_types.go @@ -17,8 +17,8 @@ type ResourceType struct { } type ResourceTypeSchema struct { - Resource json.RawMessage `json:"resource"` - Secret json.RawMessage `json:"secret"` + Resource map[string]any `json:"resource"` + Secret map[string]any `json:"secret"` } // GetResourceTypesOptions is a placeholder for future options diff --git a/go.mod b/go.mod index 464635a..8d2cdee 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,16 @@ module github.com/passbolt/go-passbolt go 1.23.0 require ( - github.com/ProtonMail/gopenpgp/v3 v3.1.3 + github.com/ProtonMail/gopenpgp/v3 v3.3.0 github.com/google/go-querystring v1.1.0 github.com/google/uuid v1.6.0 - github.com/santhosh-tekuri/jsonschema v1.2.4 + github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 ) require ( - github.com/ProtonMail/go-crypto v1.1.6 // indirect - github.com/cloudflare/circl v1.6.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/sys v0.30.0 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect + github.com/cloudflare/circl v1.6.1 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect ) diff --git a/go.sum b/go.sum index be3dc48..a84e837 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,31 @@ -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/ProtonMail/gopenpgp/v3 v3.1.3 h1:nxUd0Na4MeElx0sA1t6U8/IxmjmCv3MKnTJGhEUK+qY= -github.com/ProtonMail/gopenpgp/v3 v3.1.3/go.mod h1:Ve9JYzwGau9DT0F9C9gsuEBU/T3Zbk0j1/+mPpWBogc= -github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= -github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/ProtonMail/gopenpgp/v3 v3.3.0 h1:N6rHCH5PWwB6zSRMgRj1EbAMQHUAAHxH3Oo4KibsPwY= +github.com/ProtonMail/gopenpgp/v3 v3.3.0/go.mod h1:J+iNPt0/5EO9wRt7Eit9dRUlzyu3hiGX3zId6iuaKOk= +github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= +github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= -github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= +github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/helper/metadata.go b/helper/metadata.go index 8cbb009..5b0f4fd 100644 --- a/helper/metadata.go +++ b/helper/metadata.go @@ -1,15 +1,13 @@ package helper import ( - "bytes" "context" "encoding/json" "fmt" - "strings" "github.com/ProtonMail/gopenpgp/v3/crypto" "github.com/passbolt/go-passbolt/api" - "github.com/santhosh-tekuri/jsonschema" + "github.com/santhosh-tekuri/jsonschema/v6" ) func GetResourceMetadata(ctx context.Context, c *api.Client, resource *api.Resource, rType *api.ResourceType) (string, error) { @@ -75,7 +73,7 @@ func validateMetadata(rType *api.ResourceType, metadata string) error { comp := jsonschema.NewCompiler() - err = comp.AddResource("metadata.json", bytes.NewReader(schemaDefinition.Resource)) + err = comp.AddResource("metadata.json", schemaDefinition.Resource) if err != nil { return fmt.Errorf("Adding Json Schema: %w", err) } @@ -85,7 +83,13 @@ func validateMetadata(rType *api.ResourceType, metadata string) error { return fmt.Errorf("Compiling Json Schema: %w", err) } - err = schema.Validate(strings.NewReader(metadata)) + var parsedMetadata map[string]any + err = json.Unmarshal([]byte(metadata), &parsedMetadata) + if err != nil { + return fmt.Errorf("Unmarshal Secret: %w", err) + } + + err = schema.Validate(parsedMetadata) if err != nil { return fmt.Errorf("Validating Metadata with Schema: %w", err) } diff --git a/helper/secret.go b/helper/secret.go index 502bfe7..4866f7d 100644 --- a/helper/secret.go +++ b/helper/secret.go @@ -1,13 +1,11 @@ package helper import ( - "bytes" "encoding/json" "fmt" - "strings" "github.com/passbolt/go-passbolt/api" - "github.com/santhosh-tekuri/jsonschema" + "github.com/santhosh-tekuri/jsonschema/v6" ) func validateSecretData(rType *api.ResourceType, secretData string) error { @@ -54,7 +52,7 @@ func validateSecretData(rType *api.ResourceType, secretData string) error { comp := jsonschema.NewCompiler() - err = comp.AddResource("secret.json", bytes.NewReader(schemaDefinition.Secret)) + err = comp.AddResource("secret.json", schemaDefinition.Secret) if err != nil { return fmt.Errorf("Adding Json Schema: %w", err) } @@ -64,7 +62,13 @@ func validateSecretData(rType *api.ResourceType, secretData string) error { return fmt.Errorf("Compiling Json Schema: %w", err) } - err = schema.Validate(strings.NewReader(secretData)) + var parsedSecretData map[string]any + err = json.Unmarshal([]byte(secretData), &parsedSecretData) + if err != nil { + return fmt.Errorf("Unmarshal Secret: %w", err) + } + + err = schema.Validate(parsedSecretData) if err != nil { return fmt.Errorf("Validating Secret Data with Schema: %w", err) } From c5c92590c133fe0b7f2b2dd8df9dd48c1323ae8c Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 18 Aug 2025 15:02:22 +0200 Subject: [PATCH 2/2] Validate Secret on Get --- helper/resource_get.go | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/helper/resource_get.go b/helper/resource_get.go index 64fcc1f..36c8498 100644 --- a/helper/resource_get.go +++ b/helper/resource_get.go @@ -37,23 +37,24 @@ func GetResourceFromData(c *api.Client, resource api.Resource, secret api.Secret ctx := context.TODO() + rawSecretData, err := c.DecryptMessage(secret.Data) + if err != nil { + return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) + } + + err = validateSecretData(&rType, rawSecretData) + if err != nil { + return "", "", "", "", "", "", fmt.Errorf("Validate Secret Data: %w", err) + } + switch rType.Slug { case "password-string": - var err error - pw, err = c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } + pw = rawSecretData name = resource.Name username = resource.Username uri = resource.URI desc = resource.Description case "password-and-description": - rawSecretData, err := c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } - var secretData api.SecretDataTypePasswordAndDescription err = json.Unmarshal([]byte(rawSecretData), &secretData) if err != nil { @@ -65,11 +66,6 @@ func GetResourceFromData(c *api.Client, resource api.Resource, secret api.Secret pw = secretData.Password desc = secretData.Description case "password-description-totp": - rawSecretData, err := c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } - var secretData api.SecretDataTypePasswordDescriptionTOTP err = json.Unmarshal([]byte(rawSecretData), &secretData) if err != nil { @@ -103,11 +99,6 @@ func GetResourceFromData(c *api.Client, resource api.Resource, secret api.Secret uri = metadata.URIs[0] } - rawSecretData, err := c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } - var secretData api.SecretDataTypeV5Default err = json.Unmarshal([]byte(rawSecretData), &secretData) if err != nil { @@ -133,11 +124,6 @@ func GetResourceFromData(c *api.Client, resource api.Resource, secret api.Secret uri = metadata.URIs[0] } - rawSecretData, err := c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } - var secretData api.SecretDataTypeV5DefaultWithTOTP err = json.Unmarshal([]byte(rawSecretData), &secretData) if err != nil { @@ -166,11 +152,6 @@ func GetResourceFromData(c *api.Client, resource api.Resource, secret api.Secret // Not available in the Secret desc = metadata.Description - rawSecretData, err := c.DecryptMessage(secret.Data) - if err != nil { - return "", "", "", "", "", "", fmt.Errorf("Decrypting Secret Data: %w", err) - } - pw = rawSecretData case "v5-totp-standalone": rawMetadata, err := GetResourceMetadata(ctx, c, &resource, &rType)