Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OSPS Baseline Level 1 rules. #265

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions data-sources/ghapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,13 @@ rest:
type: string
repo:
type: string
repo_config:
endpoint: https://api.github.com/repos/{owner}/{repo}
parse: json
input_schema:
type: object
properties:
owner:
type: string
repo:
type: string
41 changes: 0 additions & 41 deletions profiles/github/security_baseline_1.yaml

This file was deleted.

49 changes: 49 additions & 0 deletions rule-types/github/branch_protection_allow_deletions.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
tests:
- name: "force push not allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "pass"
http:
status: 200
body: '{"allow_deletions": {"enabled": false}}'
- name: "force push allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 200
body: '{"allow_deletions": {"enabled": true}}'
- name: "not found"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 404
body: '{"woot": "woot"}'
- name: "internal error"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 502
body: '{"woot": "woot"}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
tests:
- name: "force push not allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "pass"
http:
status: 200
body: '{"allow_force_pushes": {"enabled": false}}'
- name: "force push allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 200
body: '{"allow_force_pushes": {"enabled": true}}'
- name: "not found"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 404
body: '{"woot": "woot"}'
- name: "internal error"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 502
body: '{"woot": "woot"}'
68 changes: 35 additions & 33 deletions rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,50 +131,52 @@ func TestRuleTypes(t *testing.T) {

require.NoError(t, os.Setenv("REGO_ENABLE_PRINT", "true"))

// iterate rule types directory
err := walkRuleTypesTests(t, func(t *testing.T, rt *minderv1.RuleType, tc *RuleTest, rtDataPath string) {
var opts []tkv1.Option
if rt.Def.Ingest.Type == "git" {
opts = append(opts, gitTestOpts(t, tc, rtDataPath))
} else if rt.Def.Ingest.Type == "rest" {
opts = append(opts, httpTestOpts(t, tc, rtDataPath))
} else {
t.Skipf("Unsupported ingest type %s", rt.Def.Ingest.Type)
}
for _, folder := range []string{"rule-types", "security-baseline/rule-types"} {
// iterate rule types directory
err := walkRuleTypesTests(t, folder, func(t *testing.T, rt *minderv1.RuleType, tc *RuleTest, rtDataPath string) {
var opts []tkv1.Option
if rt.Def.Ingest.Type == "git" {
opts = append(opts, gitTestOpts(t, tc, rtDataPath))
} else if rt.Def.Ingest.Type == "rest" {
opts = append(opts, httpTestOpts(t, tc, rtDataPath))
} else {
t.Skipf("Unsupported ingest type %s", rt.Def.Ingest.Type)
}

ztw := zerolog.NewTestWriter(t)
zerolog.SetGlobalLevel(zerolog.DebugLevel)
ctx := zerolog.New(ztw).With().Timestamp().Logger().WithContext(context.Background())
ztw := zerolog.NewTestWriter(t)
zerolog.SetGlobalLevel(zerolog.DebugLevel)
ctx := zerolog.New(ztw).With().Timestamp().Logger().WithContext(context.Background())

tk := tkv1.NewTestKit(opts...)
rte, err := rtengine.NewRuleTypeEngine(ctx, rt, tk, nil)
require.NoError(t, err)
tk := tkv1.NewTestKit(opts...)
rte, err := rtengine.NewRuleTypeEngine(ctx, rt, tk, nil)
require.NoError(t, err)

val := rte.GetRuleInstanceValidator()
require.NoError(t, val.ValidateRuleDefAgainstSchema(tc.Def), "Failed to validate rule definition against schema")
require.NoError(t, val.ValidateParamsAgainstSchema(tc.Params), "Failed to validate params against schema")
val := rte.GetRuleInstanceValidator()
require.NoError(t, val.ValidateRuleDefAgainstSchema(tc.Def), "Failed to validate rule definition against schema")
require.NoError(t, val.ValidateParamsAgainstSchema(tc.Params), "Failed to validate params against schema")

if tk.ShouldOverrideIngest() {
rte.WithCustomIngester(tk)
}
if tk.ShouldOverrideIngest() {
rte.WithCustomIngester(tk)
}

_, err = rte.Eval(ctx, tc.Entity.Entity, tc.Def, tc.Params, tkv1.NewVoidResultSink())
if tc.Expect == ExpectPass {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
_, err = rte.Eval(ctx, tc.Entity.Entity, tc.Def, tc.Params, tkv1.NewVoidResultSink())
if tc.Expect == ExpectPass {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})

if err != nil {
t.Error(err)
if err != nil {
t.Error(err)
}
}
}

func walkRuleTypesTests(t *testing.T, testfunc RuleTypeTestFunc) error {
func walkRuleTypesTests(t *testing.T, folder string, testfunc RuleTypeTestFunc) error {
t.Helper()

return filepath.Walk("rule-types", func(path string, info os.FileInfo, err error) error {
return filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions security-baseline/data-sources/ghapi.yaml
37 changes: 37 additions & 0 deletions security-baseline/profiles/security-baseline-level-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
version: v1
type: profile
name: security-baseline-level-1
display_name: OSPS Security Baseline - Level 1
context:
provider: github
alert: "off"
remediate: "off"
repository:
# OSPS-AC-03: Prevent overwriting git history
- name: osps-ac-03
type: osps-ac-03
def: {}
# OSPS-AC-04: Prevent permanent branch deletion
- name: osps-ac-04
type: osps-ac-04
def: {}
# OSPS-DO-01: Projects has public discussion mechanisms
- name: osps-do-01
type: osps-do-01
def: {}
# OSPS-DO-02: Enforce CONTRIBUTING file presence
- name: osps-do-02
type: osps-do-02
def: {}
# OSPS-LE-02: Ensure OSI/FSF approved license
- name: osps-le-02
type: osps-le-02
def: {}
# OSPS-LE-03: LICENSE or COPYING files are available available
- name: osps-le-03
type: osps-le-03
def: {}
# OSPS-QA-01: Repository visibility check
- name: osps-qa-01
type: osps-qa-01
def: {}
49 changes: 49 additions & 0 deletions security-baseline/rule-types/github/osps-ac-03.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
tests:
- name: "force push not allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "pass"
http:
status: 200
body: '{"allow_force_pushes": {"enabled": false}}'
- name: "force push allowed"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 200
body: '{"allow_force_pushes": {"enabled": true}}'
- name: "not found"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 404
body: '{"woot": "woot"}'
- name: "internal error"
def: {}
params: {}
entity:
type: repository
entity:
owner: "mindersec"
name: "minder"
expect: "fail"
http:
status: 502
body: '{"woot": "woot"}'
38 changes: 38 additions & 0 deletions security-baseline/rule-types/github/osps-ac-03.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: v1
release_phase: alpha
type: rule-type
name: osps-ac-03
display_name: Prevent overwriting git history
short_failure_message: Force pushes are allowed
severity:
value: info
context:
provider: github
description: Disallow force pushes to the branch
guidance: |
Ensure that the appropriate setting is disabled for the branch
protection rule.

This setting prevents users with push access to force push to the
branch.

For more information, see [GitHub's
documentation](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule).
def:
in_entity: repository
rule_schema: {}
ingest:
type: rest
rest:
endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ .Entity.DefaultBranch }}/protection'
parse: json
fallback:
- http_code: 404
body: |
{"http_status": 404, "message": "Not Protected"}
eval:
type: jq
jq:
- ingested:
def: ".allow_force_pushes.enabled"
constant: false
Loading
Loading