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 ruletype for OSPS-QA-03 #307

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
43 changes: 43 additions & 0 deletions security-baseline/rule-types/github/osps-qa-03.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
tests:
- name: go.mod with no go.sum
def: {}
params: {}
expect: "fail"
git:
repo_base: go_mod_no_go_sum
- name: go.mod with go.sum
def: {}
params: {}
expect: "pass"
git:
repo_base: go_mod_with_go_sum
- name: Gemfile with no Gemfile.lock
def: {}
params: {}
expect: "fail"
git:
repo_base: gemfile_no_lock
- name: Gemfile with Gemfile.lock
def: {}
params: {}
expect: "pass"
git:
repo_base: gemfile_with_lock
- name: package.json with package-lock.json
def: {}
params: {}
expect: "pass"
git:
repo_base: package_json_with_package_lock
- name: package.json with yarn.lock
def: {}
params: {}
expect: "pass"
git:
repo_base: package_json_with_yarn_lock
- name: package.json with no lockfile
def: {}
params: {}
expect: "fail"
git:
repo_base: package_json_no_lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

gem 'rails', '~> 7.0'
gem 'sqlite3', '~> 1.4'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

gem 'rails', '~> 7.0'
gem 'sqlite3', '~> 1.4'
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
GEM
remote: https://rubygems.org/
specs:
rails (7.0.4)
actioncable (= 7.0.4)
actionmailer (= 7.0.4)
actionpack (= 7.0.4)
actionview (= 7.0.4)
activejob (= 7.0.4)
activemodel (= 7.0.4)
activerecord (= 7.0.4)
activestorage (= 7.0.4)
activesupport (= 7.0.4)
railties (= 7.0.4)
sqlite3 (1.4.2)

PLATFORMS
ruby

DEPENDENCIES
rails (~> 7.0)
sqlite3 (~> 1.4)

BUNDLED WITH
2.2.19
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/mindersec/minder-rules-and-profiles

go 1.23.4

require (
github.com/rs/zerolog v1.33.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/mindersec/minder-rules-and-profiles

go 1.23.4

require (
github.com/rs/zerolog v1.33.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "my-app",
"version": "1.0.0",
"description": "A simple project with one dependency",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {},
"scripts": {
"start": "node index.js"
},
"author": "Your Name",
"license": "MIT"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "my-app",
"version": "1.0.0",
"description": "A simple project with one dependency",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {},
"scripts": {
"start": "node index.js"
},
"author": "Your Name",
"license": "MIT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "my-app",
"version": "1.0.0",
"description": "A simple project with one dependency",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {},
"scripts": {
"start": "node index.js"
},
"author": "Your Name",
"license": "MIT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-KnxlP5n7gOxlXj1SxxWnWy0xQQjjfgtA5r+DRfdGp1P0FBrw6zEhmL+u90hQH2JszQXOxj6MSL
73 changes: 73 additions & 0 deletions security-baseline/rule-types/github/osps-qa-03.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
version: v1
release_phase: alpha
type: rule-type
name: osps-qa-03
display_name: Package management file listing dependencies is present
short_failure_message: No package management file listing dependencies was found
severity:
value: info
context:
provider: github
description: |
This rule ensures that the repository provides a dependency list that accounts
for the direct language dependencies when the package management system supports it.
It checks for the presence of a Gemfile.lock, go.sum, package-lock.json or
Cargo.toml according to the package management system used.
guidance: |
Ensure that the repository provides a dependency list that accounts for the direct
language dependencies in the form of a lockfile, for example Gemfile.lock, go.sum,
package-lock.json etc.
Ensure the lockfile is in the same directory as the package file.
def:
in_entity: repository
rule_schema: {}
ingest:
type: git
eval:
type: rego
rego:
type: deny-by-default
def: |
package minder

import rego.v1

default allow := false
default skip := false
default message := "Cannot find lockfile in the same directory as the package file"

package_manager_files := [
{"name": "Gemfile", "lockfiles": ["Gemfile.lock"]},
{"name": "go.mod", "lockfiles": ["go.sum"]},
{"name": "package.json", "lockfiles": ["package-lock.json", "yarn.lock"]},
{"name": "Cargo.toml", "lockfiles": ["Cargo.lock"]},
]

skip if {
# Skip if no package manager file exists
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at QA-03, I think if there's a language in the repo identified by GitHub, we should be ensuring that there are package files, rather than ignoring repos that also don't check in Gemfile/etc.

We could find the set of detected languages with a call to the repo config data source. At least for npm and Go, I know that a go.mod / package.json is needed to declare a module at all, whether or not it has dependencies, so checking for those files makes sense.

every package_manager in package_manager_files {
required_files := file.ls_glob(sprintf("./%s", [package_manager.name]))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the glob library we're using in Minder doesn't support ** patterns, which is why this only looks at the root directory. This is probably something we want to change in the Minder code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah -- we could also use file.walk for this:

Suggested change
required_files := file.ls_glob(sprintf("./%s", [package_manager.name]))
all_files := file.walk(".")
package_manager_files = [ filepath |
filepath := all_files[_];
glob.match("**/" + package_manager[_].name, ["/"], filepath)
]

count(required_files) == 0
}
}

allow if {
# Ensure that we find the required file
some package_manager in package_manager_files
package_files := file.ls_glob(sprintf("./%s", [package_manager.name]))
count(package_files) > 0

# Get the directory for the package file
some package_path in package_files
dir := trim_suffix(package_path, sprintf("/%s", [package_manager.name]))

# Ensure a lockfile exists for the required file in the same directory
lockfile_exists(dir, package_manager.lockfiles)
}
Comment on lines +55 to +67
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an allow if or a constraints if the lockfile is missing? i.e. if I have:

./go.mod
./go.sum
./package.json

(No lockfile for NPM)

Is this a "pass" or a "fail"? I suspect it's a fail for the NPM ecosystem, even if it's a pass for the Go ecosystem.


lockfile_exists(dir, lockfiles) if {
some lockfile in lockfiles
count(file.ls_glob(sprintf("%s/%s", [dir, lockfile]))) > 0
}