diff --git a/rule-types/common/golangci_gosec_enabled.test.yaml b/rule-types/common/golangci_gosec_enabled.test.yaml new file mode 100644 index 0000000..3a4a641 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.test.yaml @@ -0,0 +1,81 @@ +--- +tests: + - name: "Gosec is explicitly enabled in .golangci.yml" + def: {} + params: {} + expect: "pass" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: enabled_in_golangci_yml + + - name: "Missing in .golangci.yml" + def: {} + params: {} + expect: "fail" + entity: *test-repo + git: + repo_base: missing_in_golangci_yml + + - name: "all linters are enabled" + def: {} + params: {} + expect: "pass" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: all_linters_enabled + + - name: "all linters enabled and gosec is disabled" + def: {} + params: {} + expect: "fail" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: all_linters_enabled_and_gosec_disabled + + - name: "all linters are disabled and gosec is missing" + def: {} + params: {} + expect: "fail" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: all_linters_disabled_and_gosec_missing + + - name: "all linters are disabled and gosec is enabled" + def: {} + params: {} + expect: "pass" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: all_linters_disabled_and_gosec_enabled + + - name: "rule is skipped" + def: {} + params: {} + expect: "skip" + entity: &test-repo + type: repository + entity: + owner: "coolhead" + name: "haze-wave" + git: + repo_base: no_golangci_yml \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_enabled/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_enabled/.golangci.yml new file mode 100644 index 0000000..c5b49fd --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_enabled/.golangci.yml @@ -0,0 +1,16 @@ +linters: + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - canonicalheader + - containedctx + - contextcheck + - copyloopvar + - cyclop + - decorder + - depguard + - dogsled + - gosec \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_missing/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_missing/.golangci.yml new file mode 100644 index 0000000..416aff6 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_disabled_and_gosec_missing/.golangci.yml @@ -0,0 +1,15 @@ +linters: + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - canonicalheader + - containedctx + - contextcheck + - copyloopvar + - cyclop + - decorder + - depguard + - dogsled \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled/.golangci.yml new file mode 100644 index 0000000..c818a84 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled/.golangci.yml @@ -0,0 +1,2 @@ +linters: + enable-all: true \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled_and_gosec_disabled/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled_and_gosec_disabled/.golangci.yml new file mode 100644 index 0000000..0b9ce84 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/all_linters_enabled_and_gosec_disabled/.golangci.yml @@ -0,0 +1,4 @@ +linters: + enable-all: true + disable: + - gosec diff --git a/rule-types/common/golangci_gosec_enabled.testdata/enabled_in_golangci_yml/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/enabled_in_golangci_yml/.golangci.yml new file mode 100644 index 0000000..771a440 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/enabled_in_golangci_yml/.golangci.yml @@ -0,0 +1,3 @@ +linters: + enable: + - gosec \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/missing_in_golangci_yml/.golangci.yml b/rule-types/common/golangci_gosec_enabled.testdata/missing_in_golangci_yml/.golangci.yml new file mode 100644 index 0000000..b689fe7 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/missing_in_golangci_yml/.golangci.yml @@ -0,0 +1,14 @@ +linters: + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - canonicalheader + - containedctx + - contextcheck + - copyloopvar + - cyclop + - decorder + - depguard + - dogsled \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.testdata/no_golangci_yml/README.md b/rule-types/common/golangci_gosec_enabled.testdata/no_golangci_yml/README.md new file mode 100644 index 0000000..9f26b63 --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.testdata/no_golangci_yml/README.md @@ -0,0 +1 @@ +Foo \ No newline at end of file diff --git a/rule-types/common/golangci_gosec_enabled.yaml b/rule-types/common/golangci_gosec_enabled.yaml new file mode 100644 index 0000000..02aab4e --- /dev/null +++ b/rule-types/common/golangci_gosec_enabled.yaml @@ -0,0 +1,93 @@ +--- +version: v1 +release_phase: alpha +type: rule-type +name: golangci_gosec_enabled +display_name: Ensure gosec is enabled in the golangci-lint configuration +short_failure_message: Gosec is disabled in the golangci-lint configuration +severity: + value: medium +context: {} +description: | + Gosec is a security linter for Go. It is important to have it enabled in the + golangci-lint configuration to ensure that security issues are caught early + in the development process. +guidance: | + If you are explicitly enabling linters in your golangci-lint configuration (`disable-all: true`), + make sure that gosec is one of them. To do so, add the following to your .golangci.yml + + ```yaml + linters: + enable: + - gosec + ``` + + If you are enabling all linters but disabling gosec explicitly, make sure that you have a good reason + for doing so. Else, remove gosec from the `disable` list in your .golangci.yml +def: + in_entity: repository # The entity type the rule applies to + rule_schema: {} + ingest: + type: git + git: + eval: + type: rego + rego: + type: deny-by-default + def: | + package minder + + import rego.v1 + + default allow := false + + default gosec_config_file := "" + + gosec_config_file := ".golangci.yml" if { + file.exists(".golangci.yml") + } + + gosec_config_file := ".golangci.yaml" if { + file.exists(".golangci.yaml") + } + + gosec_config_file := ".golangci.json" if { + file.exists(".golangci.json") + } + + skip if { + gosec_config_file == "" + } + + allow if { + glcilint_str := file.read(gosec_config_file) + gcilintcfg := parse_yaml(glcilint_str) + + print(gcilintcfg) + gosec_enabled(gcilintcfg["linters"]) + } + + # If all linters are enabled and we're not disabling anything, gosec should be enabled + gosec_enabled(linters_cfg) if { + linters_cfg["enable-all"] == true + + not linters_cfg["disable"] + } + + # If all linters are enabled, Let's make sure gosec is not disabled + gosec_enabled(linters_cfg) if { + linters_cfg["enable-all"] == true + + linter := linters_cfg["disable"][_] + + linter != "gosec" + } + + # Let's make sure gosec is explicitly enabled otherwise + gosec_enabled(linters_cfg) if { + linters := linters_cfg["enable"] + + "gosec" in linters + } + + message := "Gosec is disabled in the golangci-lint configuration" diff --git a/rule-types/gitlab/gitlab_release_contains_evidence.yaml b/rule-types/gitlab/gitlab_release_contains_evidence.yaml new file mode 100644 index 0000000..17f37c5 --- /dev/null +++ b/rule-types/gitlab/gitlab_release_contains_evidence.yaml @@ -0,0 +1,38 @@ +--- +version: v1 +type: rule-type +name: gitlab_release_contains_evidence +display_name: Gitlab release contains evidence +short_failure_message: Release does not contain evidence +severity: + value: medium +context: + provider: gitlab +release_phase: alpha +description: | + Foo bar +guidance: | + Bar baz +def: + in_entity: release + rule_schema: {} + ingest: + type: rest + rest: + endpoint: '/projects/{{ mapGet .Entity.Properties "gitlab/project_id" }}/releases/{{ mapGet .Entity.Properties "gitlab/tag" }}' + parse: json + eval: + type: rego + rego: + type: deny-by-default + def: | + package minder + + default allow := false + default message := "Release does not contain evidences" + + allow { + # Check that there is at least one evidence included in the release + count(input.ingested.evidences) > 0 + } + diff --git a/rule-types/gitlab/gitlab_release_contains_sig_and_cert.yaml b/rule-types/gitlab/gitlab_release_contains_sig_and_cert.yaml new file mode 100644 index 0000000..b8deec1 --- /dev/null +++ b/rule-types/gitlab/gitlab_release_contains_sig_and_cert.yaml @@ -0,0 +1,42 @@ +--- +version: v1 +type: rule-type +name: gitlab_release_contains_sig_and_cert +display_name: Gitlab release contains signature and certificate +short_failure_message: Release does not contain signature and certificate +severity: + value: medium +context: + provider: gitlab +release_phase: alpha +description: | + The release should contain a signature and a certificate to ensure the authenticity and integrity of the release + assets. This rule verifies that the release assets contain a signature and a certificate. +guidance: | + To ensure the authenticity and integrity of the release assets, include a signature and a certificate in the release. + This will allow users to verify the authenticity and integrity of the release assets. +def: + in_entity: release + rule_schema: {} + ingest: + type: rest + rest: + endpoint: '/projects/{{ mapGet .Entity.Properties "gitlab/project_id" }}/releases/{{ mapGet .Entity.Properties "gitlab/tag" }}' + parse: json + eval: + type: rego + rego: + type: deny-by-default + def: | + package minder + + default allow := false + default message := "Release does not contain " + + allow { + count(input.ingested.assets) > 0 + count(input.ingested.assets.links) > 0 + + count([a | a := input.ingested.assets.links[_]; contains(a.url, ".sig")]) > 0 + count([a | a := input.ingested.assets.links[_]; contains(a.url, ".crt")]) > 0 + }