Skip to content

Commit

Permalink
Merge pull request #111 from jfrog/GH-109-malicious-policy
Browse files Browse the repository at this point in the history
GH-109 add malicious_package attribute to security policy.
  • Loading branch information
danielmkn authored Mar 23, 2023
2 parents 1a67efe + 2cc04e9 commit 499f1ea
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 37 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.11.0 (March 22, 2023). Tested on Artifactory 7.55.8 and Xray 3.69.3

IMPROVEMENTS:
* resource/xray_security_policy: added new attribute `malicious_package`. It allows to create a violation on any malicious package detected.
Issue: [#109](https://github.com/jfrog/terraform-provider-xray/issues/109)
PR: [#111](https://github.com/jfrog/terraform-provider-xray/pull/111)

## 1.10.0 (March 16, 2023). Tested on Artifactory 7.55.7 and Xray 3.67.9

IMPROVEMENTS:
Expand Down
35 changes: 34 additions & 1 deletion docs/resources/security_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,38 @@ resource "xray_security_policy" "cvss_score" {
}
}
}
resource "xray_security_policy" "malicious_package" {
name = "test-security-policy-mal-pkg"
description = "Security policy description"
type = "security"
project_key = "testproj"
rule {
name = "rule-name-mp"
priority = 1
criteria {
malicious_package = true
}
actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = true
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled
block_download {
unscanned = true
active = true
}
}
}
}
```

<!-- schema generated by tfplugindocs -->
Expand Down Expand Up @@ -127,7 +159,8 @@ Optional:
Optional:

- `cvss_range` (Block List, Max: 1) The CVSS score range to apply to the rule. This is used for a fine-grained control, rather than using the predefined severities. The score range is based on CVSS v3 scoring, and CVSS v2 score is CVSS v3 score is not available. (see [below for nested schema](#nestedblock--rule--criteria--cvss_range))
- `fix_version_dependant` (Boolean) Default value is `false`. Issues that do not have a fixed version are not generated until a fixed version is available.
- `fix_version_dependant` (Boolean) Default value is `false`. Issues that do not have a fixed version are not generated until a fixed version is available. Must be `false` with `malicious_package` enabled.
- `malicious_package` (Boolean) Default value is `false`. Generating a violation on a malicious package.
- `min_severity` (String) The minimum security vulnerability severity that will be impacted by the policy.

<a id="nestedblock--rule--criteria--cvss_range"></a>
Expand Down
32 changes: 32 additions & 0 deletions examples/resources/xray_security_policy/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,35 @@ resource "xray_security_policy" "cvss_score" {
}
}
}

resource "xray_security_policy" "malicious_package" {
name = "test-security-policy-mal-pkg"
description = "Security policy description"
type = "security"
project_key = "testproj"

rule {
name = "rule-name-mp"
priority = 1

criteria {
malicious_package = true
}

actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = true
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled

block_download {
unscanned = true
active = true
}
}
}
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-log v0.4.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.14.0
github.com/jfrog/terraform-provider-shared v1.8.0
github.com/jfrog/terraform-provider-shared v1.11.1
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
golang.org/x/text v0.7.0
)
Expand Down Expand Up @@ -64,7 +64,7 @@ require (
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/zclconf/go-cty v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jfrog/terraform-provider-shared v1.8.0 h1:kaAN8/F1NgZa+V/LbDYUHk3hzCxa5yISBqak7NHvCmI=
github.com/jfrog/terraform-provider-shared v1.8.0/go.mod h1:oIzDjD2mOlfXymkzwp5kbFG3Bqy3ymVGYX50CrCxiIE=
github.com/jfrog/terraform-provider-shared v1.11.1 h1:oRK5c5Rt0wYTKrRqr+t+fspDPgn/PT5TKjCzxehfoz0=
github.com/jfrog/terraform-provider-shared v1.11.1/go.mod h1:n6855hIUDhypnXsJl8UrstVFkcnL2uW4FLLr3cKGXjU=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
Expand Down Expand Up @@ -276,8 +276,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0=
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
Expand Down
6 changes: 5 additions & 1 deletion pkg/xray/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ type PolicyRuleCriteria struct {
CVSSRange *PolicyCVSSRange `json:"cvss_range,omitempty"`
// Omitempty is used in FixVersionDependant because an empty field throws an error in Xray below 3.44.3
FixVersionDependant bool `json:"fix_version_dependant,omitempty"`
MaliciousPackage bool `json:"malicious_package,omitempty"`
// We use pointer for CVSSRange to address nil-verification for non-primitive types.
// Unlike primitive types, when the non-primitive type in the struct is set
// to nil, the empty key will be created in the JSON body anyway.
Expand Down Expand Up @@ -298,7 +299,9 @@ func unpackSecurityCriteria(tfCriteria map[string]interface{}) *PolicyRuleCriter
if v, ok := tfCriteria["fix_version_dependant"]; ok {
criteria.FixVersionDependant = v.(bool)
}

if v, ok := tfCriteria["malicious_package"]; ok {
criteria.MaliciousPackage = v.(bool)
}
// This is also picky about not allowing empty values to be set
cvss := unpackCVSSRange(tfCriteria["cvss_range"].([]interface{}))
if cvss == nil {
Expand Down Expand Up @@ -580,6 +583,7 @@ func packSecurityCriteria(criteria *PolicyRuleCriteria) []interface{} {
}
m["min_severity"] = minSeverity
m["fix_version_dependant"] = criteria.FixVersionDependant
m["malicious_package"] = criteria.MaliciousPackage

return []interface{}{m}
}
Expand Down
43 changes: 41 additions & 2 deletions pkg/xray/resource_xray_security_policy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package xray

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/jfrog/terraform-provider-shared/validator"
Expand All @@ -18,7 +21,13 @@ func resourceXraySecurityPolicyV2() *schema.Resource {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Default value is `false`. Issues that do not have a fixed version are not generated until a fixed version is available.",
Description: "Default value is `false`. Issues that do not have a fixed version are not generated until a fixed version is available. Must be `false` with `malicious_package` enabled.",
},
"malicious_package": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Default value is `false`. Generating a violation on a malicious package.",
},
"cvss_range": {
Type: schema.TypeList,
Expand Down Expand Up @@ -56,7 +65,37 @@ func resourceXraySecurityPolicyV2() *schema.Resource {
Importer: &schema.ResourceImporter{
StateContext: resourceImporterForProjectKey,
},
CustomizeDiff: criteriaMaliciousPkgDiff,
Schema: getPolicySchema(criteriaSchema, commonActionsSchema),
}
}

Schema: getPolicySchema(criteriaSchema, commonActionsSchema),
var criteriaMaliciousPkgDiff = func(ctx context.Context, diff *schema.ResourceDiff, v interface{}) error {
rules := diff.Get("rule").([]interface{})
if len(rules) == 0 {
return nil
}
criteria := rules[0].(map[string]interface{})["criteria"].(*schema.Set).List()
if len(criteria) == 0 {
return nil
}

criterion := criteria[0].(map[string]interface{})
maliciousPackage := criterion["malicious_package"].(bool)
fixVersionDependant := criterion["fix_version_dependant"].(bool)
minSeverity := criterion["min_severity"].(string)
cvssRange := criterion["cvss_range"].([]interface{})
// If `malicious_package` is enabled in the UI, `fix_version_dependant` is set to `false` in the UI call.
// UI itself doesn't have this checkbox at all. We are adding this check to avoid unexpected behavior.
if maliciousPackage && fixVersionDependant {
return fmt.Errorf("fix_version_dependant must be set to false if malicious_package is true")
}
if (maliciousPackage && len(minSeverity) > 0) && (maliciousPackage && len(cvssRange) > 0) {
return fmt.Errorf("malicious_package can't be set to true together with min_severity and/or cvss_range")
}
if len(minSeverity) > 0 && len(cvssRange) > 0 {
return fmt.Errorf("min_severity can't be set together with cvss_range")
}

return nil
}
Loading

0 comments on commit 499f1ea

Please sign in to comment.