├── .gitignore
├── CHANGELOG
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── build_protos.sh
├── cli
├── cli.go
└── cli_test.go
├── configs
├── configs_test.go
├── defs
│ ├── cassandra-cql.textproto
│ ├── cassandra.textproto
│ ├── centos.textproto
│ ├── cos.textproto
│ ├── elasticsearch-sql.textproto
│ ├── elasticsearch.textproto
│ ├── fallback.textproto
│ ├── generic_linux.textproto
│ ├── generic_yum_linux.textproto
│ ├── mariadb.textproto
│ └── rocky.textproto
├── example.textproto
├── example_mysql.textproto
├── genfullconfig
│ ├── gen_full_config.go
│ └── genfullconfiglib
│ │ ├── gen_full_config_lib.go
│ │ └── gen_full_config_lib_test.go
└── reduced
│ ├── cassandra
│ ├── container_image_scanning.textproto
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── centos_7
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_101
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_105
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_109
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_113
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_117
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_89
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_93
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── cos_97
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── debian_10
│ └── vm_image_scanning.textproto
│ ├── debian_9
│ └── vm_image_scanning.textproto
│ ├── elasticsearch
│ └── instance_scanning.textproto
│ ├── fallback
│ ├── container_image_scanning.textproto
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
│ ├── mariadb
│ └── instance_scanning.textproto
│ └── rocky_85
│ ├── instance_scanning.textproto
│ └── vm_image_scanning.textproto
├── cqlquerier
└── cql_querier.go
├── elsquerier
└── els_querier.go
├── fakedb
└── fakedb.go
├── go.mod
├── go.sum
├── localfilereader
├── local_file_reader.go
└── local_file_reader_test.go
├── localtoast.go
├── localtoast_sql
└── localtoast_sql.go
├── protofilehandler
├── proto_file_handler.go
└── proto_file_handler_test.go
├── scanapi
├── scan_api.go
└── scan_api_test.go
├── scannercommon
├── scanner_common.go
└── scanner_common_test.go
├── scannerlib
├── api_error_wrapper.go
├── configchecks
│ ├── check_common.go
│ ├── configchecks_test.go
│ ├── content_entry_file_check.go
│ ├── content_entry_file_check_test.go
│ ├── file_check.go
│ ├── file_check_test.go
│ ├── group_criteria.go
│ ├── group_criteria_test.go
│ ├── sql_check.go
│ └── sql_check_test.go
├── fileset
│ ├── file_set.go
│ └── file_set_test.go
├── proto
│ ├── api.proto
│ └── scan_instructions.proto
├── repeatconfig
│ ├── repeat_config.go
│ └── repeat_config_test.go
├── scanner.go
├── scanner_test.go
├── testconfigcreator
│ └── test_config_creator.go
└── version.go
└── sqlquerier
├── sql_querier.go
└── sql_querier_test.go
/.gitignore:
--------------------------------------------------------------------------------
1 | # Files
2 | localtoast
3 | gen_full_config
4 |
5 | # Folders
6 | configs/full
7 | scannerlib
8 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 1.1.7:
2 | * L1+L2 benchmarks for Rocky Linux
3 | * L2 benchmarks for distro-independent Linux and COS
4 | * Documentation for building Localtoast with SQL scanning capabilities
5 | * Small fixes in COS benchmarks
6 |
7 | 1.1.6:
8 | * Add support for CassandraDB, ElasticSearch, and CentOS7
9 | * Miscellaneous benchmark fixes
10 |
11 | 1.1.5:
12 | * Add numerous runtime / memory usage optimizations
13 | * Fix race condition caused by opening files multiple times
14 | * Fix smaller TODOs
15 | * Add scan timeout support
16 | * Display more information about failed recursive checks
17 |
18 | 1.1.4:
19 | * Miscellaneous benchmark fixes
20 | * Remove the Basel-related build files
21 | * Make building compatible with older Go versions
22 | * More work on de-duplicating benchmark configs
23 |
24 | 1.1.3:
25 | * Make compilation with "go build" possible
26 | * Fix some of the checks in the COS benchmark config
27 | * Start work on de-duplicating benchmark configs
28 |
29 | 1.1.2:
30 | * Add more detailed error logging
31 | * Set a maximum traversal depth to mitigate loops in cyclic filesystems
32 | * Expand the RepeatConfig instruction capabilities
33 |
34 | 1.1.1:
35 | * Add option to skip symlinks during traversal
36 | * Add option to skip specific replacements in the RepeatConfig
37 | * Remove unused API functions
38 | * Fix some TODOs
39 | * Make instruction deserialization more robust
40 |
41 | 1.1.0:
42 | * Add core functionality for SQL scanning
43 | * Add script for creating reduced benchmark config files
44 | * Implement CheckAlternatives
45 | * Add more features for the RepeatedOptions and ProcessDir instruction
46 |
47 | 1.0.2:
48 | * Force garbage collection during file traversal to improve memory usage a bit
49 |
50 | 1.0.1:
51 | * Switch to using Grafeas's Compliance proto for the benchmark configs
52 | * Add CLI arg for chrooting
53 | * Add CLI arg for opting out files from being traversed
54 |
55 | 1.0.0:
56 | * Add CLI args for opting out files from the scan results
57 | * Add initial benchmark config file for COS 89
58 | * Implement more file check instructions
59 |
60 | 0.0.1:
61 | * Initial version
62 | * Add the basic scanner structure and support for some file check instructions
63 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution;
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code Reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google/conduct/).
29 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | export PATH := $(PATH):$(shell go env GOPATH)/bin
2 |
3 | comma:= ,
4 | empty:=
5 | space:= $(empty) $(empty)
6 | comma-separate = $(subst ${space},${comma},$1)
7 |
8 | # Files under configs/defs/
9 | CONFIG_DEFS = $(call comma-separate,$(wildcard configs/defs/*.textproto))
10 | # Files under configs/reduced/*/
11 | REDUCED_CONFIGS = $(call comma-separate,$(wildcard configs/reduced/*/*.textproto))
12 | # Full configs go under configs/full/*/
13 | FULL_CONFIGS = $(subst /reduced/,/full/,${REDUCED_CONFIGS})
14 |
15 | localtoast: protos
16 | go build localtoast.go
17 |
18 | localtoast_sql: protos
19 | cd localtoast_sql && go build localtoast_sql.go
20 |
21 | test: protos
22 | go test ./...
23 |
24 | configs: protos
25 | mkdir -p configs/full && cp -rf configs/reduced/* configs/full
26 | go build configs/genfullconfig/gen_full_config.go
27 | ./gen_full_config --in=$(REDUCED_CONFIGS),$(CONFIG_DEFS) --out=$(FULL_CONFIGS) --omit-descriptions
28 |
29 | protos:
30 | ./build_protos.sh
31 |
32 | clean:
33 | rm -rf scannerlib/proto/*_go_proto
34 | rm -rf scannerlib/proto/v1
35 | rm -f localtoast
36 | rm -f localtoast_sql/localtoast_sql
37 | rm -rf configs/full
38 | rm -f gen_full_config
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Localtoast
2 | Localtoast is a scanner for running security-related configuration checks such as [CIS benchmarks](https://www.cisecurity.org/cis-benchmarks) in an easily configurable manner.
3 |
4 | The scanner can either be used as a standalone binary to scan the local machine or as a library with a custom wrapper to perform scans on e.g. container images or remote hosts.
5 |
6 | ## How to use
7 |
8 | ### As a standalone binary:
9 |
10 | 1. Install the [build deps](#build-dependencies)
11 | 2. `make`
12 | 3. `sudo ./localtoast --config=configs/example.textproto --result=scan-result.textproto`
13 |
14 |
15 | #### Build and use OS-specific configs:
16 | 1. `make configs`
17 | 2. `sudo ./localtoast --config=configs/full/cos_97/instance_scanning.textproto --result=scan-result.textproto`
18 |
19 | #### Build and run Localtoast with SQL scanning capabilities:
20 | 1. `make configs`
21 | 2. `make localtoast_sql`
22 | 3. `sudo localtoast_sql/localtoast_sql --config=configs/full/cassandra-cql/instance_scanning.textproto --result=scan-result.textproto --cassandra-database=localhost:9042`
23 |
24 | ### As a library:
25 | 1. Import `github.com/google/localtoast/scannerlib` and `github.com/google/localtoast/scanapi` into your Go project
26 | 2. Write a custom implementation for the `scanapi.ScanAPI` interface
27 | 3. Call `scannerlib.Scanner{}.Scan()` with the appropriate config and the implementation
28 |
29 | See the [scan config](scannerlib/proto/api.proto) and [result](scannerlib/proto/scan_instructions.proto) protos for details on the input+output format.
30 |
31 | ## Defining custom checks
32 | To add your own checks to a scan config,
33 |
34 | 1. Define the check in one of the [definition files](configs/defs/cos.textproto)
35 | * [Example](https://github.com/google/localtoast/commit/9c39a52cef30f7ad773b74a38ac9ffa7c4998ca3#diff-1350df51e73d56ca08a90aa7fc47a3032a41d85a7fe5a8b8707387000f43c0be)
36 | * See the [instruction proto](scannerlib/proto/scan_instructions.proto) for details on the instruction syntax
37 | 2. Add a reference to the check in [the scan config](configs/reduced/cos_97/instance_scanning.textproto) you want to extend
38 | * [Example](https://github.com/google/localtoast/commit/9c39a52cef30f7ad773b74a38ac9ffa7c4998ca3#diff-094e7befebe2acf9321eb3406fbb81af2880344086fe40dc97c3d4d915fe0e6e)
39 | 3. Re-build the config file with `make configs`
40 | 4. Use the re-generated config file in your scans, e.g. `sudo ./localtoast --config=configs/full/cos_97/instance_scanning.textproto --result=scan-result.textproto`
41 |
42 | ## Build dependencies
43 | To build Localtoast, you'll need to have the following installed:
44 | * `go`: Follow https://go.dev/doc/install
45 | * `protoc`: Install the appropriate package, e.g. `apt install protobuf-compiler`
46 | * `protoc-gen-go`: Run `go install google.golang.org/protobuf/cmd/protoc-gen-go`
47 |
48 | ## Contributing
49 | Read how to [contribute to Localtoast](CONTRIBUTING.md).
50 |
51 | ## License
52 | Localtoast is released under the [Apache 2.0 license](LICENSE).
53 |
54 | ```
55 | Copyright 2021 Google Inc.
56 |
57 | Licensed under the Apache License, Version 2.0 (the "License");
58 | you may not use this file except in compliance with the License.
59 | You may obtain a copy of the License at
60 |
61 | http://www.apache.org/licenses/LICENSE-2.0
62 |
63 | Unless required by applicable law or agreed to in writing, software
64 | distributed under the License is distributed on an "AS IS" BASIS,
65 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66 | See the License for the specific language governing permissions and
67 | limitations under the License.
68 | ```
69 |
70 | ## Disclaimers
71 |
72 | Localtoast is not an official Google product.
73 |
--------------------------------------------------------------------------------
/build_protos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | rm -rf scannerlib/proto/*_go_proto
3 |
4 | # Install and prepare Grafeas.
5 | if [ ! -e scannerlib/proto/v1 ]; then
6 | wget --no-verbose https://github.com/grafeas/grafeas/archive/220ed72376f81d0dd5233839d22c5627eb8d9494.tar.gz
7 | tar -xf 220ed72376f81d0dd5233839d22c5627eb8d9494.tar.gz
8 | mv grafeas-220ed72376f81d0dd5233839d22c5627eb8d9494/proto/v1 scannerlib/proto
9 | rm -r *220ed72376f81d0dd5233839d22c5627eb8d9494*
10 | fi
11 |
12 | sed -i 's\option go_package = ".*";\option go_package = "github.com/google/localtoast/scannerlib/proto/compliance_go_proto";\g' scannerlib/proto/v1/compliance.proto
13 | sed -i 's\option go_package = ".*";\option go_package = "github.com/google/localtoast/scannerlib/proto/severity_go_proto";\g' scannerlib/proto/v1/severity.proto
14 |
15 | # Compile protos.
16 | protoc -I=scannerlib --go_out=scannerlib/proto scannerlib/proto/*.proto scannerlib/proto/v1/compliance.proto scannerlib/proto/v1/severity.proto
17 |
18 | # Clean up.
19 | mv scannerlib/proto/github.com/google/localtoast/scannerlib/proto/* scannerlib/proto/
20 | rm -r scannerlib/proto/github.com
21 |
--------------------------------------------------------------------------------
/cli/cli.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "errors"
19 | "fmt"
20 | "strings"
21 | "time"
22 | )
23 |
24 | // Flags contains a field for all the cli flags that can be set.
25 | type Flags struct {
26 | ConfigFile string
27 | ResultFile string
28 | ChrootPath string
29 | MySQLDatabase string
30 | CassandraDatabase string
31 | ElasticSearchDatabase string
32 | ElasticSearchSkipVerify bool
33 | BenchmarkOptOutIDs string
34 | ContentOptOutRegexes string
35 | FilenameOptOutRegexes string
36 | TraversalOptOutRegexes string
37 | ShowCompliantBenchmarks bool
38 | MaxCisProfileLevel int
39 | ScanTimeout time.Duration
40 | BenchmarkCheckTimeout time.Duration
41 | }
42 |
43 | // ValidateFlags validates the passed command line flags.
44 | func ValidateFlags(flags *Flags) error {
45 | if len(flags.ConfigFile) == 0 {
46 | return errors.New("--config not set")
47 | }
48 | if len(flags.ResultFile) == 0 {
49 | return errors.New("--result not set")
50 | }
51 |
52 | if len(flags.BenchmarkOptOutIDs) > 0 {
53 | for _, id := range strings.Split(flags.BenchmarkOptOutIDs, ",") {
54 | if len(id) == 0 {
55 | return errors.New("invalid --benchmark-opt-out-ids: ID cannot be left empty")
56 | }
57 | }
58 | }
59 |
60 | // Checks that only one database flag is specified
61 | if len(flags.MySQLDatabase) > 0 && (len(flags.CassandraDatabase) > 0 || len(flags.ElasticSearchDatabase) > 0) {
62 | return errors.New("cannot specify multiple databases")
63 | } else if len(flags.CassandraDatabase) > 0 && len(flags.ElasticSearchDatabase) > 0 {
64 | return errors.New("cannot specify multiple databases")
65 | }
66 |
67 | if err := validateRegexArg(flags.ContentOptOutRegexes, "--content-opt-out-regexes"); err != nil {
68 | return err
69 | }
70 | if err := validateRegexArg(flags.FilenameOptOutRegexes, "--filename-opt-out-regexes"); err != nil {
71 | return err
72 | }
73 | if err := validateRegexArg(flags.TraversalOptOutRegexes, "--traversal-opt-out-regexes"); err != nil {
74 | return err
75 | }
76 |
77 | if flags.MaxCisProfileLevel < 1 {
78 | return errors.New("--max-cis-profile-level must be 1 or higher")
79 | }
80 |
81 | return nil
82 | }
83 |
84 | func validateRegexArg(arg string, name string) error {
85 | if len(arg) == 0 {
86 | return nil
87 | }
88 | for _, regex := range strings.Split(arg, ",") {
89 | if len(regex) == 0 {
90 | return fmt.Errorf("invalid %s: Regex cannot be left empty", name)
91 | }
92 | }
93 | return nil
94 | }
95 |
--------------------------------------------------------------------------------
/cli/cli_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli_test
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/google/localtoast/cli"
21 | )
22 |
23 | func TestValidateFlags(t *testing.T) {
24 | for _, tc := range []struct {
25 | desc string
26 | flags *cli.Flags
27 | expectError bool
28 | }{
29 | {
30 | desc: "Valid config",
31 | flags: &cli.Flags{
32 | ConfigFile: "config.textproto",
33 | ResultFile: "result.textproto",
34 | BenchmarkOptOutIDs: "id1,id2,id3",
35 | ContentOptOutRegexes: "regex1,regex2,regex3",
36 | FilenameOptOutRegexes: "regex1,regex2,regex3",
37 | TraversalOptOutRegexes: "regex1,regex2,regex3",
38 | MaxCisProfileLevel: 3,
39 | MySQLDatabase: "127.0.0.1",
40 | },
41 | expectError: false,
42 | },
43 | {
44 | desc: "Config missing",
45 | flags: &cli.Flags{
46 | ConfigFile: "",
47 | ResultFile: "result.textproto",
48 | MaxCisProfileLevel: 3,
49 | },
50 | expectError: true,
51 | },
52 | {
53 | desc: "Result missing",
54 | flags: &cli.Flags{
55 | ConfigFile: "config.textproto",
56 | ResultFile: "",
57 | MaxCisProfileLevel: 3,
58 | },
59 | expectError: true,
60 | },
61 | {
62 | desc: "Empty benchmark opt-out ID",
63 | flags: &cli.Flags{
64 | ConfigFile: "config.textproto",
65 | ResultFile: "result.textproto",
66 | BenchmarkOptOutIDs: "id1,,id2",
67 | MaxCisProfileLevel: 3,
68 | },
69 | expectError: true,
70 | },
71 | {
72 | desc: "Empty content opt-out regex",
73 | flags: &cli.Flags{
74 | ConfigFile: "config.textproto",
75 | ResultFile: "result.textproto",
76 | ContentOptOutRegexes: "regex1,,regex2",
77 | MaxCisProfileLevel: 3,
78 | },
79 | expectError: true,
80 | },
81 | {
82 | desc: "Empty filename opt-out regex",
83 | flags: &cli.Flags{
84 | ConfigFile: "config.textproto",
85 | ResultFile: "result.textproto",
86 | FilenameOptOutRegexes: "regex1,,regex2",
87 | MaxCisProfileLevel: 3,
88 | },
89 | expectError: true,
90 | },
91 | {
92 | desc: "Empty traversal opt-out regex",
93 | flags: &cli.Flags{
94 | ConfigFile: "config.textproto",
95 | ResultFile: "result.textproto",
96 | TraversalOptOutRegexes: "regex1,regex2,",
97 | MaxCisProfileLevel: 3,
98 | },
99 | expectError: true,
100 | },
101 | {
102 | desc: "Invalid profile level",
103 | flags: &cli.Flags{
104 | ConfigFile: "config.textproto",
105 | ResultFile: "result.textproto",
106 | MaxCisProfileLevel: 0,
107 | },
108 | expectError: true,
109 | },
110 | {
111 | desc: "Multiple database set",
112 | flags: &cli.Flags{
113 | ConfigFile: "config.textproto",
114 | ResultFile: "result.textproto",
115 | MySQLDatabase: "127.0.0.1",
116 | CassandraDatabase: "127.0.0.1",
117 | },
118 | expectError: true,
119 | },
120 | {
121 | desc: "Multiple database set",
122 | flags: &cli.Flags{
123 | ConfigFile: "config.textproto",
124 | ResultFile: "result.textproto",
125 | MySQLDatabase: "127.0.0.1",
126 | ElasticSearchDatabase: "https://elastic:test@localhost:9200",
127 | },
128 | expectError: true,
129 | },
130 | } {
131 | t.Run(tc.desc, func(t *testing.T) {
132 | err := cli.ValidateFlags(tc.flags)
133 | if err == nil && tc.expectError {
134 | t.Errorf("validation passed, expected it to fail")
135 | } else if err != nil && !tc.expectError {
136 | t.Errorf("validation failed with %v, expected it to pass", err)
137 | }
138 | })
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/configs/defs/cassandra-cql.textproto:
--------------------------------------------------------------------------------
1 | benchmark_configs: {
2 | id: "cassandra-default-superuser"
3 | compliance_note: {
4 | version: { cpe_uri: "cpe:/a:apache:cassandra:3.11" version: "1.0.0" benchmark_document: "CIS Apache Cassandra 3.11" }
5 | title: "Ensure the cassandra and superuser roles are separate"
6 | description:
7 | "The default installation of cassandra includes a superuser role named cassandra. This "
8 | "necessitates the creation of a separate role to be the superuser role."
9 | rationale:
10 | "Superuser permissions allow for the creation, deletion, and permission management of "
11 | "other users. Considering the Cassandra role is well known it should not be a superuser or "
12 | "one which is used for any administrative tasks."
13 | remediation: "Create a new super user and remove the super-user role to cassandra"
14 | cis_benchmark: {
15 | profile_level: 1
16 | severity: LOW
17 | }
18 | scan_instructions:
19 | "generic:{check_alternatives:{"
20 | " sql_checks:{"
21 | " target_database: DB_CASSANDRA"
22 | " query: \"SELECT role FROM system_auth.roles WHERE is_superuser = True AND role = 'cassandra' ALLOW FILTERING;\""
23 | " expect_results: false"
24 | " }"
25 | "}}"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/configs/defs/elasticsearch-sql.textproto:
--------------------------------------------------------------------------------
1 | benchmark_configs: {
2 | id: "elasticsearch-default-superuser"
3 | compliance_note: {
4 | version: { cpe_uri: "cpe:/a:elastic:elasticsearch" version: "1.0.0" benchmark_document: "Google-developed benchmark for ElasticSearch" }
5 | title: "Ensure the elasticsearch and superuser roles are separate"
6 | description:
7 | "The default installation of ElasticSearch includes a superuser role named elastic. This "
8 | "necessitates the creation of a separate role to be the superuser role."
9 | rationale:
10 | "Superuser permissions allow for the creation, deletion, and permission management of "
11 | "other users. Considering the elastic user is well known it should not be a superuser or "
12 | "one which is used for any administrative tasks."
13 | remediation: "Create a new super user and remove the superuser role to elastic"
14 | cis_benchmark: {
15 | profile_level: 1
16 | severity: LOW
17 | }
18 | scan_instructions:
19 | "generic{check_alternatives:{"
20 | " sql_checks:{"
21 | " target_database: DB_ELASTICSEARCH"
22 | " query: \"/_security/user/elastic\""
23 | " filter_regex: \".*?superuser.*\""
24 | " expect_results: false"
25 | " }"
26 | "}}"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/configs/example_mysql.textproto:
--------------------------------------------------------------------------------
1 | benchmark_configs: {
2 | id: "no-test-database"
3 | compliance_note: {
4 | version: { cpe_uri: "cpe:/example" version: "1.1.0" }
5 | title: "Ensure the 'test' database is not installed"
6 | description:
7 | "The default MySQL installation comes with an unused database called test. "
8 | "It is recommended that the test database be dropped."
9 | rationale:
10 | "The test database can be accessed by all users and can be used to consume "
11 | "system resources. Dropping the test database will reduce the attack "
12 | "surface of the MySQL server."
13 | remediation:
14 | "Execute the following SQL statement to drop the test database: `DROP "
15 | "DATABASE 'test';`"
16 | cis_benchmark: {
17 | profile_level: 1
18 | severity: HIGH
19 | }
20 | scan_instructions:
21 | "check_alternatives:{"
22 | " sql_checks:{"
23 | " target_database: DB_MYSQL"
24 | " query: \"SHOW DATABASES LIKE 'test';\""
25 | " expect_results: false"
26 | " }"
27 | "}"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/configs/genfullconfig/gen_full_config.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // The gen_full_config command creates full per-OS scan config files by
16 | // combining the config definition and the reduced config files.
17 | package main
18 |
19 | import (
20 | "flag"
21 | "log"
22 | "strings"
23 |
24 | "github.com/google/localtoast/configs/genfullconfig/genfullconfiglib"
25 | )
26 |
27 | func main() {
28 | // Example: configs/reduced/cos_93/instance_scanning.textproto,configs/reduced/cos_93/vm_image_scanning.textproto,configs/defs/cos.textproto
29 | in := flag.String("in", "", "Comma-separated list of the reduced per-OS configs, followed by a list of the config definition paths")
30 | // Example: configs/full/cos_93_instance_scanning.textproto,configs/full/cos_93_vm_image_scanning.textproto
31 | out := flag.String("out", "", "Comma-separated list of the output paths for the produced full configs")
32 | omitDescriptions := flag.Bool("omit-descriptions", false, "Whether to omit the description fields from the generated config files to save space.")
33 | flag.Parse()
34 |
35 | inPaths := []string{}
36 | if *in != "" {
37 | inPaths = strings.Split(*in, ",")
38 | // Remove trailing commas.
39 | if inPaths[len(inPaths)-1] == "" {
40 | inPaths = inPaths[:len(inPaths)-1]
41 | }
42 | }
43 | outPaths := []string{}
44 | if *out != "" {
45 | outPaths = strings.Split(*out, ",")
46 | // Remove trailing commas.
47 | if outPaths[len(outPaths)-1] == "" {
48 | outPaths = outPaths[:len(outPaths)-1]
49 | }
50 | }
51 |
52 | if err := genfullconfiglib.Generate(inPaths, outPaths, *omitDescriptions); err != nil {
53 | log.Fatal(err)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/configs/reduced/cassandra/container_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/a:apache:cassandra:3.11" version: "1.0.0" benchmark_document: "CIS Apache Cassandra 3.11" }
2 | benchmark_id: "cassandra-usergroup"
3 | benchmark_id: "cassandra-authentication"
4 | benchmark_id: "cassandra-authorization"
5 | benchmark_id: "cassandra-internodeencryption"
6 | benchmark_id: "cassandra-logginglevel"
7 | benchmark_id: "cassandra-networkinterfaces"
8 | benchmark_id: "cassandra-auditing"
9 | benchmark_id: "cassandra-clientencryption"
10 |
--------------------------------------------------------------------------------
/configs/reduced/cassandra/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/a:apache:cassandra:3.11" version: "1.0.0" benchmark_document: "CIS Apache Cassandra 3.11" }
2 | benchmark_id: "cassandra-default-superuser"
3 | benchmark_id: "cassandra-usergroup"
4 | benchmark_id: "cassandra-clocksync"
5 | benchmark_id: "cassandra-authentication"
6 | benchmark_id: "cassandra-authorization"
7 | benchmark_id: "cassandra-internodeencryption"
8 | benchmark_id: "cassandra-logginglevel"
9 | benchmark_id: "cassandra-networkinterfaces"
10 | benchmark_id: "cassandra-runasroot"
11 | benchmark_id: "cassandra-auditing"
12 | benchmark_id: "cassandra-clientencryption"
13 |
--------------------------------------------------------------------------------
/configs/reduced/cassandra/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/a:apache:cassandra:3.11" version: "1.0.0" benchmark_document: "CIS Apache Cassandra 3.11" }
2 | benchmark_id: "cassandra-usergroup"
3 | benchmark_id: "cassandra-authentication"
4 | benchmark_id: "cassandra-authorization"
5 | benchmark_id: "cassandra-internodeencryption"
6 | benchmark_id: "cassandra-logginglevel"
7 | benchmark_id: "cassandra-networkinterfaces"
8 | benchmark_id: "cassandra-auditing"
9 | benchmark_id: "cassandra-clientencryption"
10 |
--------------------------------------------------------------------------------
/configs/reduced/centos_7/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:centos:centos:7.%02" version: "4.0.0" benchmark_document: "CIS Centos Linux 7.x" }
2 | benchmark_id: "cramfs-mounting-disabled"
3 | benchmark_id: "squashfs-mounting-disabled"
4 | benchmark_id: "udf-mounting-disabled"
5 | benchmark_id: "tmp-configured"
6 | benchmark_id: "tmp-noexec"
7 | benchmark_id: "tmp-nodev"
8 | benchmark_id: "tmp-nosuid"
9 | benchmark_id: "shm-configured"
10 | benchmark_id: "shm-noexec"
11 | benchmark_id: "shm-nodev"
12 | benchmark_id: "shm-nosuid"
13 | benchmark_id: "home-nodev"
14 | benchmark_id: "world-writable-dirs-sticky"
15 | benchmark_id: "gpgcheck-activated"
16 | benchmark_id: "aide-installed"
17 | benchmark_id: "filesystem-integrity-checked"
18 | benchmark_id: "bootloader-password-set"
19 | benchmark_id: "bootloader-config-permissions"
20 | benchmark_id: "auth-for-single-user-required"
21 | benchmark_id: "core-dumps-restricted"
22 | benchmark_id: "nx-enabled"
23 | benchmark_id: "aslr-enabled"
24 | benchmark_id: "prelink-disabled"
25 | benchmark_id: "selinux-installed"
26 | benchmark_id: "selinux-not-disabled-in-bootloader"
27 | benchmark_id: "selinux-policy-configured"
28 | benchmark_id: "selinux-mode-enforcing-or-permissive"
29 | benchmark_id: "setroubleshoot-not-installed"
30 | benchmark_id: "mcstrans-not-installed"
31 | benchmark_id: "motd-configured"
32 | benchmark_id: "local-login-warning-configured"
33 | benchmark_id: "remote-login-warning-configured"
34 | benchmark_id: "motd-permissions"
35 | benchmark_id: "etc-issue-permissions"
36 | benchmark_id: "etc-issue-net-permissions"
37 | benchmark_id: "gdm-login-banner-configured"
38 | benchmark_id: "last-logged-user-display-disabled"
39 | benchmark_id: "xdcmp-not-enabled"
40 | benchmark_id: "xinetd-not-installed"
41 | benchmark_id: "time-synchronization-in-use"
42 | benchmark_id: "chrony-configured"
43 | benchmark_id: "ntp-configured"
44 | benchmark_id: "x11-server-components-not-installed"
45 | benchmark_id: "cups-disabled"
46 | benchmark_id: "dhcp-server-disabled"
47 | benchmark_id: "ldap-server-disabled"
48 | benchmark_id: "dns-server-disabled"
49 | benchmark_id: "ftp-server-disabled"
50 | benchmark_id: "http-server-disabled"
51 | benchmark_id: "imap-pop3-server-disabled"
52 | benchmark_id: "samba-disabled"
53 | benchmark_id: "http-proxy-server-disabled"
54 | benchmark_id: "snmp-server-disabled"
55 | benchmark_id: "nis-server-disabled"
56 | benchmark_id: "telnet-server-disabled"
57 | benchmark_id: "nfs-rpc-disabled"
58 | benchmark_id: "rsync-disabled"
59 | benchmark_id: "rsh-client-not-installed"
60 | benchmark_id: "talk-client-not-installed"
61 | benchmark_id: "telnet-client-not-installed"
62 | benchmark_id: "ldap-client-not-installed"
63 | benchmark_id: "ip-forwarding-disabled"
64 | benchmark_id: "packet-redirect-sending-disabled"
65 | benchmark_id: "source-routed-packets-not-accepted"
66 | benchmark_id: "icmp-redirects-not-accepted"
67 | benchmark_id: "secure-icmp-redirects-not-accepted"
68 | benchmark_id: "suspicious-packets-logged"
69 | benchmark_id: "broadcast-icmp-requests-ignored"
70 | benchmark_id: "bogus-icmp-responses-ignored"
71 | benchmark_id: "reverse-path-filtering-enabled"
72 | benchmark_id: "tcp-syn-cookies-enabled"
73 | benchmark_id: "ipv6-router-advertisements-not-accepted"
74 | benchmark_id: "firewalld-is-installed"
75 | benchmark_id: "iptables-services-not-installed-with-firewalld"
76 | benchmark_id: "nftables-not-enabled-with-firewalld"
77 | benchmark_id: "nftables-is-installed"
78 | benchmark_id: "firewalld-not-enabled-with-nftables"
79 | benchmark_id: "iptables-services-not-installed-with-nftables"
80 | benchmark_id: "nftables-rules-are-permanent"
81 | benchmark_id: "iptables-packages-are-installed"
82 | benchmark_id: "nftables-not-installed-with-iptables"
83 | benchmark_id: "firewalld-not-enabled-with-iptables"
84 | benchmark_id: "iptables-rules-are-saved"
85 | benchmark_id: "ip6tables-rules-are-saved"
86 | benchmark_id: "rsyslog-installed"
87 | benchmark_id: "rsyslog-service-enabled"
88 | benchmark_id: "rsyslog-default-file-permissions-configured"
89 | benchmark_id: "rsyslog-configured-to-send-logs-to-remote-host"
90 | benchmark_id: "journald-is-configured-to-send-logs-to-rsyslog"
91 | benchmark_id: "journald-is-configured-to-compress-large-log-files"
92 | benchmark_id: "journald-write-to-persistent-disk"
93 | benchmark_id: "logfile-permissions"
94 | benchmark_id: "logrotate-configured"
95 | benchmark_id: "cron-daemon-enabled"
96 | benchmark_id: "crontab-permissions"
97 | benchmark_id: "cron-hourly-permissions"
98 | benchmark_id: "cron-daily-permissions"
99 | benchmark_id: "cron-weekly-permissions"
100 | benchmark_id: "cron-monthly-permissions"
101 | benchmark_id: "cron-d-permissions"
102 | benchmark_id: "at-cron-restricted-to-authorized-users"
103 | benchmark_id: "sudo-is-installed"
104 | benchmark_id: "sudo-commands-use-pty"
105 | benchmark_id: "sudo-log-file-exists"
106 | benchmark_id: "sshd-config-permissions"
107 | benchmark_id: "sshd-private-host-key-permissions"
108 | benchmark_id: "sshd-public-host-key-permissions"
109 | benchmark_id: "ssh-access-limited"
110 | benchmark_id: "ssh-loglevel-appropriate"
111 | benchmark_id: "ssh-maxauthtries-4-or-less"
112 | benchmark_id: "ssh-ignorerhosts-enabled"
113 | benchmark_id: "ssh-hostbasedauthentication-disabled"
114 | benchmark_id: "ssh-root-login-disabled"
115 | benchmark_id: "ssh-permitemptypasswords-disabled"
116 | benchmark_id: "ssh-permituserenvironments-disabled"
117 | benchmark_id: "strong-ciphers-used"
118 | benchmark_id: "strong-mac-algorithms-used"
119 | benchmark_id: "strong-key-exchange-algos-used"
120 | benchmark_id: "ssh-idle-timeout-interval-configured"
121 | benchmark_id: "ssh-logingrace-one-minute-or-less"
122 | benchmark_id: "ssh-warning-banner-configured"
123 | benchmark_id: "ssh-pam-enabled"
124 | benchmark_id: "ssh-maxstartups-configured"
125 | benchmark_id: "ssh-maxsessions-4-or-less"
126 | benchmark_id: "password-creation-reqs-configured"
127 | benchmark_id: "failed-password-lockout-configured"
128 | benchmark_id: "password-hashing-algorithm-sha-512"
129 | benchmark_id: "password-reuse-limited"
130 | benchmark_id: "password-expiration-365-days-or-less"
131 | benchmark_id: "minimum-days-between-password-changes-7-or-more"
132 | benchmark_id: "password-expiration-warning-days-7-or-more"
133 | benchmark_id: "inactive-password-lock-30-days-or-less"
134 | benchmark_id: "last-password-change-date-in-past"
135 | benchmark_id: "system-accounts-secured"
136 | benchmark_id: "default-group-for-root-account-is-gid-0"
137 | benchmark_id: "default-user-shell-timeout-900-or-less"
138 | benchmark_id: "default-user-umask-027-or-more-restrictive"
139 | benchmark_id: "root-login-restricted-to-system-console"
140 | benchmark_id: "access-to-su-restricted"
141 | benchmark_id: "etc-passwd-permissions"
142 | benchmark_id: "etc-shadow-permissions"
143 | benchmark_id: "etc-shadow-dash-permissions"
144 | benchmark_id: "etc-gshadow-dash-permissions"
145 | benchmark_id: "etc-gshadow-permissions"
146 | benchmark_id: "etc-group-permissions"
147 | benchmark_id: "no-world-writable-files"
148 | benchmark_id: "no-unowned-files-or-dirs"
149 | benchmark_id: "no-ungrouped-files-or-dirs"
150 | benchmark_id: "audit-suid-execs"
151 | benchmark_id: "audit-sgid-execs"
152 | benchmark_id: "accounts-in-etc-passwd-use-shadowed-passwords"
153 | benchmark_id: "password-fields-not-empty"
154 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
155 | benchmark_id: "shadow-group-empty"
156 | benchmark_id: "no-duplicate-user-names"
157 | benchmark_id: "no-duplicate-group-names"
158 | benchmark_id: "no-duplicate-uids"
159 | benchmark_id: "no-duplicate-gids"
160 | benchmark_id: "root-is-only-uid-0-account"
161 | benchmark_id: "root-path-integrity"
162 | benchmark_id: "home-dirs-exist"
163 | benchmark_id: "users-own-home-dirs"
164 | benchmark_id: "home-dirs-750-or-more-restrictive"
165 | benchmark_id: "dot-files-not-group-world-writable"
166 | benchmark_id: "no-forward-files"
167 | benchmark_id: "no-netrc-files"
168 | benchmark_id: "no-rhost-files"
169 |
--------------------------------------------------------------------------------
/configs/reduced/cos_101/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:101" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_101/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:101" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_105/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:105" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_105/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:105" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_109/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:109" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_109/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:109" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_113/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:113" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_113/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:113" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_117/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:117" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_117/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:117" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_89/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:89" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "tmp-configured"
3 | benchmark_id: "tmp-nodev"
4 | benchmark_id: "tmp-nosuid"
5 | benchmark_id: "tmp-noexec"
6 | benchmark_id: "home-nodev"
7 | benchmark_id: "shm-nodev"
8 | benchmark_id: "shm-nosuid"
9 | benchmark_id: "shm-noexec"
10 | benchmark_id: "automounting-disabled"
11 | benchmark_id: "dm-verity-installed-cos"
12 | benchmark_id: "auth-for-single-user-required-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "local-login-warning-configured"
17 | benchmark_id: "remote-login-warning-configured"
18 | benchmark_id: "etc-issue-permissions"
19 | benchmark_id: "chrony-installed-cos"
20 | benchmark_id: "chrony-configured-cos-89"
21 | benchmark_id: "x-window-system-not-installed-cos"
22 | benchmark_id: "nfs-rpc-disabled"
23 | benchmark_id: "rsync-disabled-cos"
24 | benchmark_id: "packet-redirect-sending-disabled"
25 | benchmark_id: "source-routed-packets-not-accepted-cos-89"
26 | benchmark_id: "icmp-redirects-not-accepted-cos-89"
27 | benchmark_id: "broadcast-icmp-requests-ignored"
28 | benchmark_id: "bogus-icmp-responses-ignored"
29 | benchmark_id: "reverse-path-filtering-enabled"
30 | benchmark_id: "tcp-syn-cookies-enabled"
31 | benchmark_id: "iptables-installed-cos"
32 | benchmark_id: "journald-write-to-persistent-disk"
33 | benchmark_id: "sshd-config-permissions"
34 | benchmark_id: "sshd-private-host-key-permissions"
35 | benchmark_id: "sshd-public-host-key-permissions"
36 | benchmark_id: "ssh-protocol-set-to-2"
37 | benchmark_id: "ssh-loglevel-appropriate"
38 | benchmark_id: "ssh-x11-forwarding-disabled"
39 | benchmark_id: "ssh-ignorerhosts-enabled"
40 | benchmark_id: "ssh-hostbasedauthentication-disabled"
41 | benchmark_id: "ssh-root-login-disabled"
42 | benchmark_id: "ssh-permitemptypasswords-disabled"
43 | benchmark_id: "ssh-permituserenvironments-disabled"
44 | benchmark_id: "strong-ciphers-used"
45 | benchmark_id: "strong-key-exchange-algos-used"
46 | benchmark_id: "ssh-pam-enabled"
47 | benchmark_id: "password-expiration-warning-days-7-or-more"
48 | benchmark_id: "last-password-change-date-in-past"
49 | benchmark_id: "default-group-for-root-account-is-gid-0"
50 | benchmark_id: "root-login-restricted-to-system-console"
51 | benchmark_id: "access-to-su-restricted"
52 | benchmark_id: "etc-passwd-permissions"
53 | benchmark_id: "etc-shadow-permissions"
54 | benchmark_id: "etc-group-permissions"
55 | benchmark_id: "etc-gshadow-permissions"
56 | benchmark_id: "etc-group-dash-permissions"
57 | benchmark_id: "password-fields-not-empty"
58 | benchmark_id: "passwd-no-legacy-plus-entries"
59 | benchmark_id: "shadow-no-legacy-plus-entries"
60 | benchmark_id: "group-no-legacy-plus-entries"
61 | benchmark_id: "root-is-only-uid-0-account"
62 | benchmark_id: "no-duplicate-uids"
63 | benchmark_id: "no-duplicate-gids"
64 | benchmark_id: "no-duplicate-user-names"
65 | benchmark_id: "no-duplicate-group-names"
66 | benchmark_id: "shadow-group-empty"
67 |
68 | # Generic linux checks that should be L2 in COS.
69 | profile_level_override: {
70 | level: 2
71 | benchmark_id: "password-expiration-warning-days-7-or-more"
72 | }
73 |
--------------------------------------------------------------------------------
/configs/reduced/cos_89/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:89" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "tmp-configured"
3 | benchmark_id: "tmp-nodev"
4 | benchmark_id: "tmp-nosuid"
5 | benchmark_id: "tmp-noexec"
6 | benchmark_id: "shm-noexec"
7 | benchmark_id: "automounting-disabled"
8 | benchmark_id: "auth-for-single-user-required-cos"
9 | benchmark_id: "nx-enabled"
10 | benchmark_id: "aslr-enabled"
11 | benchmark_id: "apparmor-installed"
12 | benchmark_id: "local-login-warning-configured"
13 | benchmark_id: "remote-login-warning-configured"
14 | benchmark_id: "etc-issue-permissions"
15 | benchmark_id: "chrony-installed-cos"
16 | benchmark_id: "chrony-configured-cos-89"
17 | benchmark_id: "x-window-system-not-installed-cos"
18 | benchmark_id: "nfs-rpc-disabled"
19 | benchmark_id: "rsync-disabled-cos"
20 | benchmark_id: "packet-redirect-sending-disabled"
21 | benchmark_id: "source-routed-packets-not-accepted"
22 | benchmark_id: "broadcast-icmp-requests-ignored"
23 | benchmark_id: "bogus-icmp-responses-ignored"
24 | benchmark_id: "reverse-path-filtering-enabled"
25 | benchmark_id: "tcp-syn-cookies-enabled"
26 | benchmark_id: "iptables-installed-cos"
27 | benchmark_id: "journald-write-to-persistent-disk"
28 | benchmark_id: "sshd-config-permissions"
29 | benchmark_id: "sshd-private-host-key-permissions"
30 | benchmark_id: "sshd-public-host-key-permissions"
31 | benchmark_id: "ssh-protocol-set-to-2"
32 | benchmark_id: "ssh-loglevel-appropriate"
33 | benchmark_id: "ssh-x11-forwarding-disabled"
34 | benchmark_id: "ssh-ignorerhosts-enabled"
35 | benchmark_id: "ssh-hostbasedauthentication-disabled"
36 | benchmark_id: "ssh-root-login-disabled"
37 | benchmark_id: "ssh-permitemptypasswords-disabled"
38 | benchmark_id: "ssh-permituserenvironments-disabled"
39 | benchmark_id: "strong-ciphers-used"
40 | benchmark_id: "strong-key-exchange-algos-used"
41 | benchmark_id: "ssh-pam-enabled"
42 | benchmark_id: "password-expiration-warning-days-7-or-more"
43 | benchmark_id: "last-password-change-date-in-past"
44 | benchmark_id: "default-group-for-root-account-is-gid-0"
45 | benchmark_id: "root-login-restricted-to-system-console"
46 | benchmark_id: "access-to-su-restricted"
47 | benchmark_id: "etc-passwd-permissions"
48 | benchmark_id: "etc-shadow-permissions"
49 | benchmark_id: "etc-group-permissions"
50 | benchmark_id: "etc-gshadow-permissions"
51 | benchmark_id: "etc-group-dash-permissions"
52 | benchmark_id: "password-fields-not-empty"
53 | benchmark_id: "passwd-no-legacy-plus-entries"
54 | benchmark_id: "shadow-no-legacy-plus-entries"
55 | benchmark_id: "group-no-legacy-plus-entries"
56 | benchmark_id: "root-is-only-uid-0-account"
57 | benchmark_id: "no-duplicate-uids"
58 | benchmark_id: "no-duplicate-gids"
59 | benchmark_id: "no-duplicate-user-names"
60 | benchmark_id: "no-duplicate-group-names"
61 | benchmark_id: "shadow-group-empty"
62 |
63 | # Generic linux checks that should be L2 in COS.
64 | profile_level_override: {
65 | level: 2
66 | benchmark_id: "password-expiration-warning-days-7-or-more"
67 | }
68 |
--------------------------------------------------------------------------------
/configs/reduced/cos_93/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:93" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_93/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:93" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/cos_97/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:97" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "var-nodev-cos"
5 | benchmark_id: "var-nosuid-cos"
6 | benchmark_id: "var-noexec-cos"
7 | benchmark_id: "tmp-nodev-cos"
8 | benchmark_id: "tmp-nosuid-cos"
9 | benchmark_id: "tmp-noexec-cos"
10 | benchmark_id: "home-nodev-cos"
11 | benchmark_id: "shm-nodev-cos"
12 | benchmark_id: "shm-nosuid-cos"
13 | benchmark_id: "shm-noexec-cos"
14 | benchmark_id: "automounting-disabled"
15 | benchmark_id: "dm-verity-installed-cos-93"
16 | benchmark_id: "bootloader-permissions-cos"
17 | benchmark_id: "auth-for-single-user-required-cos"
18 | benchmark_id: "core-dumps-restricted-cos"
19 | benchmark_id: "nx-enabled"
20 | benchmark_id: "aslr-enabled"
21 | benchmark_id: "apparmor-installed"
22 | benchmark_id: "motd-configured-cos"
23 | benchmark_id: "local-login-warning-configured-cos"
24 | benchmark_id: "remote-login-warning-configured-cos"
25 | benchmark_id: "motd-permissions-cos"
26 | benchmark_id: "etc-issue-permissions-cos"
27 | benchmark_id: "etc-issue-net-permissions-cos"
28 | benchmark_id: "chrony-installed-cos"
29 | benchmark_id: "chrony-configured-cos"
30 | benchmark_id: "x-window-system-not-installed-cos"
31 | benchmark_id: "nfs-rpc-disabled-cos"
32 | benchmark_id: "rsync-disabled-cos"
33 | benchmark_id: "packet-redirect-sending-disabled-cos"
34 | benchmark_id: "source-routed-packets-not-accepted-cos"
35 | benchmark_id: "icmp-redirects-not-accepted-cos"
36 | benchmark_id: "secure-icmp-redirects-not-accepted-cos"
37 | benchmark_id: "suspicious-packets-logged-cos"
38 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
39 | benchmark_id: "bogus-icmp-responses-ignored-cos"
40 | benchmark_id: "reverse-path-filtering-enabled-cos"
41 | benchmark_id: "tcp-syn-cookies-enabled-cos"
42 | benchmark_id: "ipv6-router-advertisements-not-accepted-cos"
43 | benchmark_id: "iptables-installed-cos"
44 | benchmark_id: "stackdriver-correct-container"
45 | benchmark_id: "logging-service-running"
46 | benchmark_id: "logging-configured"
47 | benchmark_id: "journald-compress-large-log-files-cos"
48 | benchmark_id: "journald-write-to-persistent-disk-cos"
49 | benchmark_id: "logfile-permissions-cos"
50 | benchmark_id: "logrotate-configured-cos"
51 | benchmark_id: "sshd-config-permissions"
52 | benchmark_id: "sshd-private-host-key-permissions"
53 | benchmark_id: "sshd-public-host-key-permissions"
54 | benchmark_id: "ssh-protocol-set-to-2"
55 | benchmark_id: "ssh-loglevel-appropriate"
56 | benchmark_id: "ssh-x11-forwarding-disabled"
57 | benchmark_id: "ssh-maxauthtries-4-or-less"
58 | benchmark_id: "ssh-ignorerhosts-enabled"
59 | benchmark_id: "ssh-hostbasedauthentication-disabled"
60 | benchmark_id: "ssh-root-login-disabled"
61 | benchmark_id: "ssh-permitemptypasswords-disabled"
62 | benchmark_id: "ssh-permituserenvironments-disabled"
63 | benchmark_id: "strong-ciphers-used"
64 | benchmark_id: "strong-mac-algorithms-used-cos"
65 | benchmark_id: "strong-key-exchange-algos-used"
66 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
67 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
68 | benchmark_id: "ssh-warning-banner-configured-cos"
69 | benchmark_id: "ssh-pam-enabled"
70 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
71 | benchmark_id: "ssh-maxstartups-configured-cos"
72 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
73 | benchmark_id: "password-creation-reqs-configured-cos"
74 | benchmark_id: "password-reuse-limited-cos"
75 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
76 | benchmark_id: "password-expiration-365-days-or-less-cos"
77 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
78 | benchmark_id: "password-expiration-warning-days-7-or-more"
79 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
80 | benchmark_id: "last-password-change-date-in-past"
81 | benchmark_id: "system-accounts-secured-cos"
82 | benchmark_id: "default-group-for-root-account-is-gid-0"
83 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
84 | benchmark_id: "default-user-shell-timeout-900-or-less"
85 | benchmark_id: "root-login-restricted-to-system-console"
86 | benchmark_id: "access-to-su-restricted-cos"
87 | benchmark_id: "etc-passwd-permissions"
88 | benchmark_id: "etc-shadow-permissions"
89 | benchmark_id: "etc-group-permissions"
90 | benchmark_id: "etc-gshadow-permissions"
91 | benchmark_id: "etc-passwd-dash-permissions-cos"
92 | benchmark_id: "etc-shadow-dash-permissions"
93 | benchmark_id: "etc-group-dash-permissions"
94 | benchmark_id: "etc-gshadow-dash-permissions"
95 | benchmark_id: "password-fields-not-empty"
96 | benchmark_id: "passwd-no-legacy-plus-entries"
97 | benchmark_id: "shadow-no-legacy-plus-entries"
98 | benchmark_id: "group-no-legacy-plus-entries"
99 | benchmark_id: "root-is-only-uid-0-account"
100 | benchmark_id: "root-path-integrity-cos"
101 | benchmark_id: "home-dirs-exist"
102 | benchmark_id: "home-dirs-750-or-more-restrictive"
103 | benchmark_id: "users-own-home-dirs"
104 | benchmark_id: "dot-files-not-group-world-writable"
105 | benchmark_id: "no-forward-files"
106 | benchmark_id: "no-netrc-files"
107 | benchmark_id: "netrc-files-not-group-world-accessible"
108 | benchmark_id: "no-rhost-files"
109 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
110 | benchmark_id: "no-duplicate-uids"
111 | benchmark_id: "no-duplicate-gids"
112 | benchmark_id: "no-duplicate-user-names"
113 | benchmark_id: "no-duplicate-group-names"
114 | benchmark_id: "shadow-group-empty"
115 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
116 | benchmark_id: "configure-ipv6-loopback-cos"
117 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
118 | benchmark_id: "default-deny-firewall-policy-cos"
119 | benchmark_id: "configure-loopback-cos"
120 | benchmark_id: "outbound-established-connections-configured-cos"
121 |
122 | # Generic linux checks that should be L2 in COS.
123 | profile_level_override: {
124 | level: 2
125 | benchmark_id: "udf-mounting-disabled-cos"
126 | benchmark_id: "stackdriver-correct-container"
127 | benchmark_id: "logging-configured"
128 | benchmark_id: "ssh-maxauthtries-4-or-less"
129 | benchmark_id: "strong-mac-algorithms-used-cos"
130 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
131 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
132 | benchmark_id: "ssh-warning-banner-configured-cos"
133 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
134 | benchmark_id: "ssh-maxstartups-configured-cos"
135 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
136 | benchmark_id: "password-reuse-limited-cos"
137 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
138 | benchmark_id: "password-expiration-365-days-or-less-cos"
139 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
140 | benchmark_id: "password-expiration-warning-days-7-or-more"
141 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
142 | benchmark_id: "etc-shadow-dash-permissions"
143 | benchmark_id: "etc-gshadow-dash-permissions"
144 | benchmark_id: "home-dirs-exist"
145 | benchmark_id: "home-dirs-750-or-more-restrictive"
146 | benchmark_id: "users-own-home-dirs"
147 | benchmark_id: "dot-files-not-group-world-writable"
148 | benchmark_id: "no-forward-files"
149 | benchmark_id: "no-netrc-files"
150 | benchmark_id: "netrc-files-not-group-world-accessible"
151 | benchmark_id: "no-rhost-files"
152 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
153 | }
154 |
--------------------------------------------------------------------------------
/configs/reduced/cos_97/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:cos:cos_linux:97" version: "1.0.0" benchmark_document: "CIS Container-Optimized OS" }
2 | benchmark_id: "udf-mounting-disabled-cos"
3 | benchmark_id: "tmp-configured-cos"
4 | benchmark_id: "tmp-nodev-cos"
5 | benchmark_id: "tmp-nosuid-cos"
6 | benchmark_id: "tmp-noexec-cos"
7 | benchmark_id: "shm-noexec-cos"
8 | benchmark_id: "automounting-disabled"
9 | benchmark_id: "dm-verity-installed-cos-93"
10 | benchmark_id: "bootloader-permissions-cos"
11 | benchmark_id: "auth-for-single-user-required-cos"
12 | benchmark_id: "core-dumps-restricted-cos"
13 | benchmark_id: "nx-enabled"
14 | benchmark_id: "aslr-enabled"
15 | benchmark_id: "apparmor-installed"
16 | benchmark_id: "motd-configured-cos"
17 | benchmark_id: "local-login-warning-configured-cos"
18 | benchmark_id: "remote-login-warning-configured-cos"
19 | benchmark_id: "motd-permissions-cos"
20 | benchmark_id: "etc-issue-permissions-cos"
21 | benchmark_id: "etc-issue-net-permissions-cos"
22 | benchmark_id: "chrony-installed-cos"
23 | benchmark_id: "chrony-configured-cos"
24 | benchmark_id: "x-window-system-not-installed-cos"
25 | benchmark_id: "nfs-rpc-disabled-cos"
26 | benchmark_id: "rsync-disabled-cos"
27 | benchmark_id: "packet-redirect-sending-disabled-cos"
28 | benchmark_id: "source-routed-packets-not-accepted-cos"
29 | benchmark_id: "broadcast-icmp-requests-ignored-cos"
30 | benchmark_id: "bogus-icmp-responses-ignored-cos"
31 | benchmark_id: "reverse-path-filtering-enabled-cos"
32 | benchmark_id: "tcp-syn-cookies-enabled-cos"
33 | benchmark_id: "iptables-installed-cos"
34 | benchmark_id: "stackdriver-correct-container"
35 | benchmark_id: "logging-service-running"
36 | benchmark_id: "logging-configured"
37 | benchmark_id: "journald-compress-large-log-files-cos"
38 | benchmark_id: "journald-write-to-persistent-disk-cos"
39 | benchmark_id: "logfile-permissions-cos"
40 | benchmark_id: "logrotate-configured-cos"
41 | benchmark_id: "sshd-config-permissions"
42 | benchmark_id: "sshd-private-host-key-permissions"
43 | benchmark_id: "sshd-public-host-key-permissions"
44 | benchmark_id: "ssh-protocol-set-to-2"
45 | benchmark_id: "ssh-loglevel-appropriate"
46 | benchmark_id: "ssh-x11-forwarding-disabled"
47 | benchmark_id: "ssh-maxauthtries-4-or-less"
48 | benchmark_id: "ssh-ignorerhosts-enabled"
49 | benchmark_id: "ssh-hostbasedauthentication-disabled"
50 | benchmark_id: "ssh-root-login-disabled"
51 | benchmark_id: "ssh-permitemptypasswords-disabled"
52 | benchmark_id: "ssh-permituserenvironments-disabled"
53 | benchmark_id: "strong-ciphers-used"
54 | benchmark_id: "strong-mac-algorithms-used-cos"
55 | benchmark_id: "strong-key-exchange-algos-used"
56 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
57 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
58 | benchmark_id: "ssh-warning-banner-configured-cos"
59 | benchmark_id: "ssh-pam-enabled"
60 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
61 | benchmark_id: "ssh-maxstartups-configured-cos"
62 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
63 | benchmark_id: "password-creation-reqs-configured-cos"
64 | benchmark_id: "password-reuse-limited-cos"
65 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
66 | benchmark_id: "password-expiration-365-days-or-less-cos"
67 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
68 | benchmark_id: "password-expiration-warning-days-7-or-more"
69 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
70 | benchmark_id: "last-password-change-date-in-past"
71 | benchmark_id: "system-accounts-secured-cos"
72 | benchmark_id: "default-group-for-root-account-is-gid-0"
73 | benchmark_id: "default-user-umask-027-or-more-restrictive-cos"
74 | benchmark_id: "default-user-shell-timeout-900-or-less"
75 | benchmark_id: "root-login-restricted-to-system-console"
76 | benchmark_id: "access-to-su-restricted-cos"
77 | benchmark_id: "etc-passwd-permissions"
78 | benchmark_id: "etc-shadow-permissions"
79 | benchmark_id: "etc-group-permissions"
80 | benchmark_id: "etc-gshadow-permissions"
81 | benchmark_id: "etc-passwd-dash-permissions-cos"
82 | benchmark_id: "etc-shadow-dash-permissions"
83 | benchmark_id: "etc-group-dash-permissions"
84 | benchmark_id: "etc-gshadow-dash-permissions"
85 | benchmark_id: "password-fields-not-empty"
86 | benchmark_id: "passwd-no-legacy-plus-entries"
87 | benchmark_id: "shadow-no-legacy-plus-entries"
88 | benchmark_id: "group-no-legacy-plus-entries"
89 | benchmark_id: "root-is-only-uid-0-account"
90 | benchmark_id: "home-dirs-exist"
91 | benchmark_id: "home-dirs-750-or-more-restrictive"
92 | benchmark_id: "users-own-home-dirs"
93 | benchmark_id: "dot-files-not-group-world-writable"
94 | benchmark_id: "no-forward-files"
95 | benchmark_id: "no-netrc-files"
96 | benchmark_id: "netrc-files-not-group-world-accessible"
97 | benchmark_id: "no-rhost-files"
98 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
99 | benchmark_id: "no-duplicate-uids"
100 | benchmark_id: "no-duplicate-gids"
101 | benchmark_id: "no-duplicate-user-names"
102 | benchmark_id: "no-duplicate-group-names"
103 | benchmark_id: "shadow-group-empty"
104 | benchmark_id: "ipv6-default-deny-firewall-policy-cos"
105 | benchmark_id: "configure-ipv6-loopback-cos"
106 | benchmark_id: "ipv6-outbound-established-connections-configured-cos"
107 | benchmark_id: "default-deny-firewall-policy-cos"
108 | benchmark_id: "configure-loopback-cos"
109 | benchmark_id: "outbound-established-connections-configured-cos"
110 |
111 | # Generic linux checks that should be L2 in COS.
112 | profile_level_override: {
113 | level: 2
114 | benchmark_id: "udf-mounting-disabled-cos"
115 | benchmark_id: "stackdriver-correct-container"
116 | benchmark_id: "logging-configured"
117 | benchmark_id: "ssh-maxauthtries-4-or-less"
118 | benchmark_id: "strong-mac-algorithms-used-cos"
119 | benchmark_id: "ssh-idle-timeout-interval-configured-cos"
120 | benchmark_id: "ssh-logingrace-one-minute-or-less-cos"
121 | benchmark_id: "ssh-warning-banner-configured-cos"
122 | benchmark_id: "ssh-allowtcpforwarding-disabled-cos"
123 | benchmark_id: "ssh-maxstartups-configured-cos"
124 | benchmark_id: "ssh-maxsessions-4-or-less-cos"
125 | benchmark_id: "password-reuse-limited-cos"
126 | benchmark_id: "password-hashing-algorithm-sha-512-cos"
127 | benchmark_id: "password-expiration-365-days-or-less-cos"
128 | benchmark_id: "minimum-days-between-password-changes-7-or-more-cos"
129 | benchmark_id: "password-expiration-warning-days-7-or-more"
130 | benchmark_id: "inactive-password-lock-30-days-or-less-cos"
131 | benchmark_id: "etc-shadow-dash-permissions"
132 | benchmark_id: "etc-gshadow-dash-permissions"
133 | benchmark_id: "home-dirs-exist"
134 | benchmark_id: "home-dirs-750-or-more-restrictive"
135 | benchmark_id: "users-own-home-dirs"
136 | benchmark_id: "dot-files-not-group-world-writable"
137 | benchmark_id: "no-forward-files"
138 | benchmark_id: "no-netrc-files"
139 | benchmark_id: "netrc-files-not-group-world-accessible"
140 | benchmark_id: "no-rhost-files"
141 | benchmark_id: "groups-from-etc-passwd-in-etc-group"
142 | }
143 |
--------------------------------------------------------------------------------
/configs/reduced/debian_10/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:debian:debian_linux:10" version: "1.0.0" benchmark_document: "CIS Debian Linux 10" }
2 | benchmark_id: "aslr-enabled"
3 | benchmark_id: "etc-issue-permissions"
4 | benchmark_id: "packet-redirect-sending-disabled"
5 | benchmark_id: "source-routed-packets-not-accepted"
6 | benchmark_id: "broadcast-icmp-requests-ignored"
7 | benchmark_id: "bogus-icmp-responses-ignored"
8 | benchmark_id: "reverse-path-filtering-enabled"
9 | benchmark_id: "tcp-syn-cookies-enabled"
10 | benchmark_id: "etc-passwd-permissions"
11 | benchmark_id: "etc-group-permissions"
12 | benchmark_id: "etc-group-dash-permissions"
13 | benchmark_id: "password-fields-not-empty"
14 | benchmark_id: "passwd-no-legacy-plus-entries"
15 | benchmark_id: "shadow-no-legacy-plus-entries"
16 | benchmark_id: "group-no-legacy-plus-entries"
17 | benchmark_id: "root-is-only-uid-0-account"
18 | benchmark_id: "no-duplicate-uids"
19 | benchmark_id: "no-duplicate-gids"
20 | benchmark_id: "no-duplicate-user-names"
21 | benchmark_id: "no-duplicate-group-names"
22 | benchmark_id: "shadow-group-empty"
23 |
--------------------------------------------------------------------------------
/configs/reduced/debian_9/vm_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/o:debian:debian_linux:9" version: "1.0.0" benchmark_document: "CIS Debian Linux 9" }
2 | benchmark_id: "aslr-enabled"
3 | benchmark_id: "etc-issue-permissions"
4 | benchmark_id: "packet-redirect-sending-disabled"
5 | benchmark_id: "source-routed-packets-not-accepted"
6 | benchmark_id: "broadcast-icmp-requests-ignored"
7 | benchmark_id: "bogus-icmp-responses-ignored"
8 | benchmark_id: "reverse-path-filtering-enabled"
9 | benchmark_id: "tcp-syn-cookies-enabled"
10 | benchmark_id: "etc-passwd-permissions"
11 | benchmark_id: "etc-group-permissions"
12 | benchmark_id: "etc-group-dash-permissions"
13 | benchmark_id: "password-fields-not-empty"
14 | benchmark_id: "passwd-no-legacy-plus-entries"
15 | benchmark_id: "shadow-no-legacy-plus-entries"
16 | benchmark_id: "group-no-legacy-plus-entries"
17 | benchmark_id: "root-is-only-uid-0-account"
18 | benchmark_id: "no-duplicate-uids"
19 | benchmark_id: "no-duplicate-gids"
20 | benchmark_id: "no-duplicate-user-names"
21 | benchmark_id: "no-duplicate-group-names"
22 | benchmark_id: "shadow-group-empty"
23 |
--------------------------------------------------------------------------------
/configs/reduced/elasticsearch/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/a:elastic:elasticsearch" version: "1.0.0" benchmark_document: "Google-developed benchmark for ElasticSearch" }
2 | benchmark_id: "elasticsearch-xpack"
3 | benchmark_id: "elasticsearch-homefolder-owner"
4 | benchmark_id: "elasticsearch-configuration-permissions"
5 | benchmark_id: "elasticsearch-usergroup"
6 | benchmark_id: "elasticsearch-clocksync"
7 | benchmark_id: "elasticsearch-runasroot"
8 | benchmark_id: "elasticsearch-logs-permissions"
9 | benchmark_id: "elasticsearch-networkinterfaces"
10 | benchmark_id: "elasticsearch-http-ssl"
11 | benchmark_id: "elasticsearch-transport-ssl"
12 | benchmark_id: "elasticsearch-auditing"
13 | benchmark_id: "elasticsearch-httpfilter"
14 | benchmark_id: "elasticsearch-no-anonymous-access"
15 |
--------------------------------------------------------------------------------
/configs/reduced/fallback/container_image_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "fallback" version: "2.0.0" benchmark_document: "CIS Distribution Independent Linux" }
2 | benchmark_id: "world-writable-dirs-sticky-fallback"
3 | benchmark_id: "motd-permissions-fallback"
4 | benchmark_id: "etc-issue-permissions-fallback"
5 | benchmark_id: "etc-issue-net-permissions-fallback"
6 | benchmark_id: "chargen-services-disabled-fallback"
7 | benchmark_id: "daytime-services-disabled-fallback"
8 | benchmark_id: "discard-services-disabled-fallback"
9 | benchmark_id: "echo-services-disabled-fallback"
10 | benchmark_id: "time-services-disabled-fallback"
11 | benchmark_id: "rsh-server-disabled-fallback"
12 | benchmark_id: "talk-server-disabled-fallback"
13 | benchmark_id: "telnet-server-disabled-fallback"
14 | benchmark_id: "tftp-server-disabled-fallback"
15 | benchmark_id: "nis-client-not-installed-fallback"
16 | benchmark_id: "rsh-client-not-installed-fallback"
17 | benchmark_id: "talk-client-not-installed-fallback"
18 | benchmark_id: "telnet-client-not-installed-fallback"
19 | benchmark_id: "ldap-client-not-installed-fallback"
20 | benchmark_id: "logfile-permissions-fallback"
21 | benchmark_id: "system-accounts-secured-fallback"
22 | benchmark_id: "default-group-for-root-account-is-gid-0-fallback"
23 | benchmark_id: "default-user-umask-027-or-more-restrictive-fallback"
24 | benchmark_id: "etc-passwd-permissions-fallback"
25 | benchmark_id: "etc-shadow-permissions-fallback"
26 | benchmark_id: "etc-group-permissions-fallback"
27 | benchmark_id: "etc-gshadow-permissions-fallback"
28 | benchmark_id: "etc-passwd-dash-permissions-fallback"
29 | benchmark_id: "etc-shadow-dash-permissions-fallback"
30 | benchmark_id: "etc-group-dash-permissions-fallback"
31 | benchmark_id: "etc-gshadow-dash-permissions-fallback"
32 | benchmark_id: "no-world-writable-files-fallback"
33 | benchmark_id: "no-unowned-files-or-dirs-fallback"
34 | benchmark_id: "no-ungrouped-files-or-dirs-fallback"
35 | benchmark_id: "audit-suid-execs-fallback"
36 | benchmark_id: "audit-sgid-execs-fallback"
37 | benchmark_id: "password-fields-not-empty-fallback"
38 | benchmark_id: "passwd-no-legacy-plus-entries-fallback"
39 | benchmark_id: "shadow-no-legacy-plus-entries-fallback"
40 | benchmark_id: "group-no-legacy-plus-entries-fallback"
41 | benchmark_id: "root-is-only-uid-0-account-fallback"
42 | benchmark_id: "home-dirs-exist-fallback"
43 | benchmark_id: "home-dirs-750-or-more-restrictive-fallback"
44 | benchmark_id: "users-own-home-dirs-fallback"
45 | benchmark_id: "dot-files-not-group-world-writable-fallback"
46 | benchmark_id: "no-forward-files-fallback"
47 | benchmark_id: "no-netrc-files-fallback"
48 | benchmark_id: "netrc-files-not-group-world-accessible-fallback"
49 | benchmark_id: "no-rhost-files-fallback"
50 | benchmark_id: "groups-from-etc-passwd-in-etc-group-fallback"
51 | benchmark_id: "no-duplicate-uids-fallback"
52 | benchmark_id: "no-duplicate-gids-fallback"
53 | benchmark_id: "no-duplicate-user-names-fallback"
54 | benchmark_id: "no-duplicate-group-names-fallback"
55 | benchmark_id: "shadow-group-empty-fallback"
56 |
--------------------------------------------------------------------------------
/configs/reduced/mariadb/instance_scanning.textproto:
--------------------------------------------------------------------------------
1 | version: { cpe_uri: "cpe:/a:mariadb:mariadb:5.5.60" version: "1.1.0" benchmark_document: "CIS Oracle MySQL Community Server 5.6" }
2 | benchmark_id: "mysql-daemon-least-privilege"
3 | benchmark_id: "mysql-pwd-not-in-environ"
4 | benchmark_id: "mysql-pwd-not-in-profiles"
5 | benchmark_id: "mysql-datadir-permissions"
6 | benchmark_id: "mysql-log-bin-basename-permissions"
7 | benchmark_id: "mysql-log-error-permissions"
8 | benchmark_id: "mysql-slow-query-log-permissions"
9 | benchmark_id: "mysql-slowquerylog-error-permissions"
10 | benchmark_id: "mysql-relay-log-basename-permissions"
11 | benchmark_id: "mysql-general-query-log-permissions"
12 | benchmark_id: "mysql-ssl-keys-permissions"
13 | benchmark_id: "mysql-plugin-dir-permissions"
14 | benchmark_id: "mysql-no-test-database"
15 | benchmark_id: "mysql-local-infile-disabled"
16 | benchmark_id: "mysql-no-skip-grant-tables"
17 | benchmark_id: "mysql-skip-symbolic-links-enabled"
18 | benchmark_id: "mysql-daemon-memcached-disabled"
19 | benchmark_id: "mysql-secure-file-priv-not-empty"
20 | benchmark_id: "mysql-only-admins-have-full-access"
21 | benchmark_id: "mysql-only-admins-have-file-priv"
22 | benchmark_id: "mysql-only-admins-have-super-priv"
23 | benchmark_id: "mysql-only-admins-have-shutdown-priv"
24 | benchmark_id: "mysql-only-admins-have-create-user-priv"
25 | benchmark_id: "mysql-only-admins-have-grant-priv"
26 | benchmark_id: "mysql-only-non-slave-have-repl-slave-priv"
27 | benchmark_id: "mysql-limited-dml-ddl-grants"
28 | benchmark_id: "mysql-log-error-not-empty"
29 | benchmark_id: "mysql-log-raw-disabled"
30 | benchmark_id: "mysql-old-passwords-disabled"
31 | benchmark_id: "mysql-secure-auth-enabled"
32 | benchmark_id: "mysql-no-passwords-in-config"
33 | benchmark_id: "mysql-no-auto-create-user"
34 | benchmark_id: "mysql-no-blank-passwords"
35 | benchmark_id: "mysql-password-policy-enabled"
36 | benchmark_id: "mysql-no-wildcard-hostnames"
37 | benchmark_id: "mysql-no-anonymous-accounts"
38 |
39 |
--------------------------------------------------------------------------------
/cqlquerier/cql_querier.go:
--------------------------------------------------------------------------------
1 | // Package cqlquerier provides an utility function for running CQL queries.
2 | package cqlquerier
3 |
4 | import (
5 | "context"
6 | "errors"
7 |
8 | "github.com/gocql/gocql"
9 | )
10 |
11 | // Query executes a CQL query and returns the first row in the result.
12 | func Query(ctx context.Context, db *gocql.Session, query string) (string, error) {
13 | if db == nil {
14 | return "", errors.New("no cassandra database specified. Please provide one using the --cassandra flag")
15 | }
16 | scanner := db.Query(query).Iter().Scanner()
17 | result := ""
18 | if scanner.Next() {
19 | if err := scanner.Scan(&result); err != nil {
20 | return "", err
21 | }
22 | if err := scanner.Err(); err != nil {
23 | return "", err
24 | }
25 | }
26 | return result, nil
27 | }
28 |
--------------------------------------------------------------------------------
/elsquerier/els_querier.go:
--------------------------------------------------------------------------------
1 | // Package elsquerier provides an utility function for running ElasticSearch queries.
2 | package elsquerier
3 |
4 | import (
5 | "context"
6 | "io"
7 | "net/http"
8 | "strings"
9 |
10 | els "github.com/elastic/go-elasticsearch/v8"
11 | )
12 |
13 | // Query executes a ELS request and returns the JSON response as string
14 | func Query(ctx context.Context, db *els.Client, endpoint string) (string, error) {
15 | req, err := http.NewRequest("GET", endpoint, nil)
16 | if err != nil {
17 | return "", err
18 | }
19 |
20 | res, err := db.Perform(req)
21 | if err != nil {
22 | return "", err
23 | }
24 | defer res.Body.Close()
25 |
26 | body := new(strings.Builder)
27 | _, err = io.Copy(body, res.Body)
28 | if err != nil {
29 | return "", err
30 | }
31 |
32 | return body.String(), nil
33 | }
34 |
--------------------------------------------------------------------------------
/fakedb/fakedb.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package fakedb provides a minimal fake implementation for a database/sql database,
16 | // to be used in tests.
17 | package fakedb
18 |
19 | import (
20 | "database/sql"
21 | "database/sql/driver"
22 | "errors"
23 | "fmt"
24 | "io"
25 | )
26 |
27 | // Queries supported by the fake database. Each query will return a different number
28 | // of rows, but no actual content.
29 | const (
30 | QueryNoRows = "SELECT 1 WHERE FALSE"
31 | QueryOneRow = "SELECT 1"
32 | QueryError = "INVALID QUERY"
33 | ErrorMsg = "invalid query"
34 | )
35 |
36 | func init() {
37 | sql.Register("fakedb", &fakeDriver{})
38 | }
39 |
40 | // FakeDB is a fake implementation of sql.DB.
41 | type FakeDB struct{}
42 |
43 | // Open creates a new sql.DB object that supports the queries defined in fakedb.
44 | func Open(*FakeDB) (*sql.DB, error) {
45 | return sql.Open("fakedb", "fakedsn")
46 | }
47 |
48 | // fakeDriver is a fake implementation of sql.Driver.
49 | type fakeDriver struct{}
50 |
51 | // Open is a fake implementation for the sql.Driver interface.
52 | func (d *fakeDriver) Open(name string) (driver.Conn, error) {
53 | return &fakeConn{&FakeDB{}}, nil
54 | }
55 |
56 | // fakeConn is a fake implementation of sql.Conn.
57 | type fakeConn struct {
58 | db *FakeDB
59 | }
60 |
61 | // Close is a fake implementation for the sql.Conn interface.
62 | func (*fakeConn) Close() error { return nil }
63 |
64 | // Begin is a fake implementation for the sql.Conn interface.
65 | func (*fakeConn) Begin() (driver.Tx, error) { return nil, nil }
66 |
67 | // Prepare is a fake implementation for the sql.Conn interface.
68 | func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
69 | return &fakeStmt{db: c.db, query: query}, nil
70 | }
71 |
72 | // fakeStmt is a fake implementation of driver.Stmt.
73 | type fakeStmt struct {
74 | db *FakeDB
75 | query string
76 | }
77 |
78 | // Close is a fake implementation for the driver.Stmt interface.
79 | func (*fakeStmt) Close() error { return nil }
80 |
81 | // Exec is a fake implementation for the driver.Stmt interface.
82 | func (*fakeStmt) Exec(args []driver.Value) (driver.Result, error) { return nil, nil }
83 |
84 | // NumInput is a fake implementation for the driver.Stmt interface.
85 | func (*fakeStmt) NumInput() int { return 0 }
86 |
87 | // Query supports a few selected queries defined in the fakedb package.
88 | func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) {
89 | switch s.query {
90 | case QueryNoRows:
91 | return &fakeRows{rowsLeft: 0}, nil
92 | case QueryOneRow:
93 | return &fakeRows{rowsLeft: 1, columns: []string{"fakeColumn"}}, nil
94 | case QueryError:
95 | return nil, errors.New(ErrorMsg)
96 | default:
97 | return nil, fmt.Errorf("the query %q is not supported by fakeStmt", s.query)
98 | }
99 | }
100 |
101 | // fakeRows is a fake implementation of driver.Rows.
102 | // We only care about the number of returned rows, so we don't model their content.
103 | type fakeRows struct {
104 | rowsLeft int
105 | columns []string
106 | }
107 |
108 | // Close is a fake implementation for the driver.Rows interface.
109 | func (*fakeRows) Close() error { return nil }
110 |
111 | // Columns is a fake implementation for the driver.Rows interface.
112 | func (r *fakeRows) Columns() []string { return r.columns }
113 |
114 | // Next is a fake implementation for the driver.Rows interface.
115 | // The function iterates through the number of known rows, but returns no values.
116 | func (r *fakeRows) Next(dst []driver.Value) error {
117 | if r.rowsLeft > 0 {
118 | r.rowsLeft--
119 | dst[0] = "fakeValue"
120 | return nil
121 | }
122 | return io.EOF
123 | }
124 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/google/localtoast
2 |
3 | go 1.17
4 |
5 | require (
6 | bitbucket.org/creachadair/stringset v0.0.10
7 | github.com/go-sql-driver/mysql v1.6.0
8 | github.com/golang/protobuf v1.5.0
9 | github.com/google/go-cmp v0.5.6
10 | google.golang.org/protobuf v1.27.1
11 | )
12 |
13 | require (
14 | github.com/elastic/elastic-transport-go/v8 v8.2.0 // indirect
15 | github.com/elastic/go-elasticsearch/v8 v8.7.1 // indirect
16 | github.com/gocql/gocql v1.4.0 // indirect
17 | github.com/golang/snappy v0.0.3 // indirect
18 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
19 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
20 | gopkg.in/inf.v0 v0.9.1 // indirect
21 | )
22 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | bitbucket.org/creachadair/stringset v0.0.10 h1:DZjkR57sJGMycZNVVbl+26bK7vW1kwLQE6qWICWLteI=
2 | bitbucket.org/creachadair/stringset v0.0.10/go.mod h1:6G0fsnHFxynEdWpihfZf44lnBPpTW6nkrcxITVTBHus=
3 | github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
4 | github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
5 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7 | github.com/elastic/elastic-transport-go/v8 v8.2.0 h1:hkK5IIs/15mpSXzd5THWVlWTKJyMw6cbCWM3T/B2S5E=
8 | github.com/elastic/elastic-transport-go/v8 v8.2.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI=
9 | github.com/elastic/go-elasticsearch/v8 v8.7.1 h1:UxK46XnlVANUjEAR8WdPSZwk5KacFTtO0xt2CGa+H6Y=
10 | github.com/elastic/go-elasticsearch/v8 v8.7.1/go.mod h1:lVb8SvJV8McVkdswpL8YR5QKIkhlWaoSq60YpHilOLI=
11 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
12 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
13 | github.com/gocql/gocql v1.4.0 h1:NIlXAJXsjzjGvVn36njh9OLYWzS3D7FdvsifLj4eDEY=
14 | github.com/gocql/gocql v1.4.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
15 | github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
16 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
17 | github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
18 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
19 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
20 | github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
21 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
22 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
23 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
24 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
25 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
26 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
27 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
28 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
29 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
30 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
31 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
32 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
33 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
34 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
35 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
36 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
37 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
38 |
--------------------------------------------------------------------------------
/localfilereader/local_file_reader.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package localfilereader provides utility functions for reading files and permissions from the local filesystem.
16 | package localfilereader
17 |
18 | import (
19 | "context"
20 | "io"
21 | "io/fs"
22 | "os"
23 | "os/user"
24 | "strconv"
25 | "strings"
26 | "syscall"
27 |
28 | "github.com/google/localtoast/scanapi"
29 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
30 | )
31 |
32 | // Flags for special UNIX permission bits.
33 | const (
34 | SetuidFlag = 04000
35 | SetgidFlag = 02000
36 | StickyFlag = 01000
37 | )
38 |
39 | var (
40 | userIDLookup = newCachedIDLookup(func(id int) (string, error) {
41 | usr, err := user.LookupId(strconv.Itoa(id))
42 | if err != nil {
43 | return "", err
44 | }
45 | return usr.Username, nil
46 | })
47 | groupIDLookup = newCachedIDLookup(func(id int) (string, error) {
48 | grp, err := user.LookupGroupId(strconv.Itoa(id))
49 | if err != nil {
50 | return "", err
51 | }
52 | return grp.Name, nil
53 | })
54 | )
55 |
56 | type cachedIDLookup struct {
57 | lookupFunc func(int) (string, error)
58 | valueCache map[int]string
59 | errorCache map[int]error
60 | }
61 |
62 | func (l *cachedIDLookup) Lookup(id int) (string, error) {
63 | if val, ok := l.valueCache[id]; ok {
64 | return val, nil
65 | }
66 | if err, ok := l.errorCache[id]; ok {
67 | return "", err
68 | }
69 | val, err := l.lookupFunc(id)
70 | if err == nil {
71 | l.valueCache[id] = val
72 | } else {
73 | l.errorCache[id] = err
74 | }
75 | return val, err
76 | }
77 |
78 | func newCachedIDLookup(lookupFunc func(int) (string, error)) cachedIDLookup {
79 | return cachedIDLookup{
80 | lookupFunc: lookupFunc,
81 | valueCache: make(map[int]string),
82 | errorCache: make(map[int]error),
83 | }
84 | }
85 |
86 | // OpenFile opens the specified file for reading.
87 | func OpenFile(ctx context.Context, path string) (io.ReadCloser, error) {
88 | return os.Open(path)
89 | }
90 |
91 | // FilePermissions returns unix permission-related data for the specified file or directory.
92 | func FilePermissions(ctx context.Context, path string) (*apb.PosixPermissions, error) {
93 | fi, err := os.Lstat(path)
94 | if err != nil {
95 | return nil, err
96 | }
97 | sys := fi.Sys()
98 | uid := int(sys.(*syscall.Stat_t).Uid)
99 | gid := int(sys.(*syscall.Stat_t).Gid)
100 |
101 | username, err := userIDLookup.Lookup(uid)
102 | if err != nil {
103 | // "unknown userid" means the file is unowned (uid not found
104 | // in /etc/group, possibly because the user got deleted). Leave
105 | // the username empty to signal this.
106 | if !strings.Contains(err.Error(), "unknown userid") {
107 | return nil, err
108 | }
109 | }
110 |
111 | groupname, err := groupIDLookup.Lookup(gid)
112 | if err != nil {
113 | // "unknown groupid" means the file is ungrouped (gid not found
114 | // in /etc/group, possibly because the group got deleted). Leave
115 | // the groupname empty to signal this.
116 | if !strings.Contains(err.Error(), "unknown groupid") {
117 | return nil, err
118 | }
119 | }
120 |
121 | perms := int32(fi.Mode().Perm())
122 | // Mode().Perm() only contains the regular permission bits, so add the
123 | // special flag bits separately.
124 | if fi.Mode()&fs.ModeSetuid != 0 {
125 | perms |= SetuidFlag
126 | }
127 | if fi.Mode()&fs.ModeSetgid != 0 {
128 | perms |= SetgidFlag
129 | }
130 | if fi.Mode()&fs.ModeSticky != 0 {
131 | perms |= StickyFlag
132 | }
133 | return &apb.PosixPermissions{
134 | PermissionNum: perms,
135 | Uid: int32(uid),
136 | User: username,
137 | Gid: int32(gid),
138 | Group: groupname,
139 | }, nil
140 | }
141 |
142 | // OpenDir opens the specified directory to list its content.
143 | func OpenDir(ctx context.Context, dirPath string) (scanapi.DirReader, error) {
144 | f, err := os.Open(dirPath)
145 | if err != nil {
146 | return nil, err
147 | }
148 | return &localDirReader{file: f, currErr: scanapi.ErrEntryBeforeNext}, nil
149 | }
150 |
151 | type localDirReader struct {
152 | file *os.File
153 | currEntry *apb.DirContent
154 | currErr error
155 | }
156 |
157 | func (d *localDirReader) nextEntry() (*apb.DirContent, error) {
158 | // Read the next entry until the EOF is reached, there was an error,
159 | // or a valid entry is found (either a dir, a regular file or a symlink).
160 | for {
161 | entries, err := d.file.ReadDir(1)
162 | if err != nil {
163 | return nil, err
164 | }
165 | e := entries[0]
166 | if e.IsDir() || e.Type().IsRegular() || e.Type()&fs.ModeSymlink == fs.ModeSymlink {
167 | return &apb.DirContent{
168 | Name: e.Name(),
169 | IsDir: e.IsDir(),
170 | IsSymlink: e.Type()&fs.ModeSymlink == fs.ModeSymlink,
171 | }, nil
172 | }
173 | }
174 | }
175 |
176 | func (d *localDirReader) Next() bool {
177 | d.currEntry, d.currErr = d.nextEntry()
178 | return d.currErr != io.EOF
179 | }
180 |
181 | func (d *localDirReader) Entry() (*apb.DirContent, error) {
182 | return d.currEntry, d.currErr
183 | }
184 |
185 | func (d *localDirReader) Close() error {
186 | return d.file.Close()
187 | }
188 |
--------------------------------------------------------------------------------
/localtoast.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // The localtoast command wraps around the scanner library to create a standalone
16 | // CLI for the config scanner with direct access to the local machine's filesystem.
17 | package main
18 |
19 | import (
20 | "context"
21 | "errors"
22 | "io"
23 | "os"
24 | "path"
25 | "runtime/debug"
26 |
27 | "github.com/google/localtoast/localfilereader"
28 | "github.com/google/localtoast/scanapi"
29 | "github.com/google/localtoast/scannercommon"
30 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
31 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
32 | )
33 |
34 | // localScanAPIProvider provides access to the local filesystem.
35 | type localScanAPIProvider struct {
36 | chrootPath string
37 | }
38 |
39 | func (a *localScanAPIProvider) fullPath(entryPath string) string {
40 | if a.chrootPath == "" {
41 | return entryPath
42 | }
43 | return path.Join(a.chrootPath, entryPath)
44 | }
45 |
46 | func (a *localScanAPIProvider) OpenFile(ctx context.Context, filePath string) (io.ReadCloser, error) {
47 | return localfilereader.OpenFile(ctx, a.fullPath(filePath))
48 | }
49 |
50 | func (a *localScanAPIProvider) OpenDir(ctx context.Context, path string) (scanapi.DirReader, error) {
51 | return localfilereader.OpenDir(ctx, a.fullPath(path))
52 | }
53 |
54 | func (a *localScanAPIProvider) FilePermissions(ctx context.Context, filePath string) (*apb.PosixPermissions, error) {
55 | return localfilereader.FilePermissions(ctx, a.fullPath(filePath))
56 | }
57 |
58 | func (localScanAPIProvider) SQLQuery(ctx context.Context, query string) (string, error) {
59 | // This is intentionally not implemented for the scanner version without SQL.
60 | return "", errors.New("not implemented")
61 | }
62 |
63 | func (localScanAPIProvider) SupportedDatabase() (ipb.SQLCheck_SQLDatabase, error) {
64 | // This is intentionally not implemented for the scanner version without SQL.
65 | return ipb.SQLCheck_DB_UNSPECIFIED, errors.New("not implemented")
66 | }
67 |
68 | func main() {
69 | // Change GCPercent to lower the peak memory usage.
70 | // Make sure we are not overwriting a custom value. We only want to change the default.
71 | if os.Getenv("GOGC") == "" {
72 | debug.SetGCPercent(1)
73 | }
74 | flags := scannercommon.ParseFlags()
75 | provider := &localScanAPIProvider{chrootPath: flags.ChrootPath}
76 | os.Exit(scannercommon.RunScan(flags, provider))
77 | }
78 |
--------------------------------------------------------------------------------
/localtoast_sql/localtoast_sql.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // The cis_scanner command wraps around the scanner library to create a standalone
16 | // CLI for the scanner with direct access to the local machine's filesystem.
17 | package main
18 |
19 | import (
20 | "context"
21 | "crypto/tls"
22 | "database/sql"
23 | "errors"
24 | "io"
25 | "log"
26 | "net/http"
27 | "os"
28 | "path"
29 |
30 | "github.com/google/localtoast/cqlquerier"
31 | "github.com/google/localtoast/elsquerier"
32 | "github.com/google/localtoast/localfilereader"
33 | "github.com/google/localtoast/scanapi"
34 | "github.com/google/localtoast/scannercommon"
35 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
36 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
37 | "github.com/google/localtoast/sqlquerier"
38 |
39 | // Import Cassandra connector
40 | "github.com/gocql/gocql"
41 |
42 | // Import ElasticSearch connector
43 | els "github.com/elastic/go-elasticsearch/v8"
44 |
45 | // We need this import to call sql.Open with the "mysql" driver.
46 | _ "github.com/go-sql-driver/mysql"
47 | )
48 |
49 | // localScanAPIProvider provides access to the local filesystem and to the
50 | // local SQL database for the scanning library.
51 | type localScanAPIProvider struct {
52 | chrootPath string
53 | sqldb *sql.DB
54 | cqldb *gocql.Session
55 | elsdb *els.Client
56 |
57 | dbtype ipb.SQLCheck_SQLDatabase
58 | }
59 |
60 | func (a *localScanAPIProvider) fullPath(entryPath string) string {
61 | if a.chrootPath == "" {
62 | return entryPath
63 | }
64 | return path.Join(a.chrootPath, entryPath)
65 | }
66 |
67 | func (a *localScanAPIProvider) OpenFile(ctx context.Context, filePath string) (io.ReadCloser, error) {
68 | return localfilereader.OpenFile(ctx, a.fullPath(filePath))
69 | }
70 |
71 | func (a *localScanAPIProvider) OpenDir(ctx context.Context, path string) (scanapi.DirReader, error) {
72 | return localfilereader.OpenDir(ctx, a.fullPath(path))
73 | }
74 |
75 | func (a *localScanAPIProvider) FilePermissions(ctx context.Context, filePath string) (*apb.PosixPermissions, error) {
76 | return localfilereader.FilePermissions(ctx, a.fullPath(filePath))
77 | }
78 |
79 | func (a *localScanAPIProvider) SupportedDatabase() (ipb.SQLCheck_SQLDatabase, error) {
80 | if a.dbtype == ipb.SQLCheck_DB_UNSPECIFIED {
81 | return a.dbtype, errors.New("no database specified")
82 | }
83 | return a.dbtype, nil
84 | }
85 |
86 | func (a *localScanAPIProvider) SQLQuery(ctx context.Context, query string) (string, error) {
87 | dbtype, err := a.SupportedDatabase()
88 | if err != nil {
89 | return "", err
90 | }
91 | if dbtype == ipb.SQLCheck_DB_MYSQL {
92 | return sqlquerier.Query(ctx, a.sqldb, query)
93 | }
94 | if dbtype == ipb.SQLCheck_DB_CASSANDRA {
95 | return cqlquerier.Query(ctx, a.cqldb, query)
96 | }
97 | if dbtype == ipb.SQLCheck_DB_ELASTICSEARCH {
98 | return elsquerier.Query(ctx, a.elsdb, query)
99 | }
100 | return "", errors.New("no database specified. Please provide one using --mysql-database, --cassandra-database or --elasticsearch-database flags")
101 | }
102 |
103 | func main() {
104 | flags := scannercommon.ParseFlags()
105 |
106 | var sqldb *sql.DB
107 | var cqldb *gocql.Session
108 | var elsdb *els.Client
109 | var err error
110 |
111 | dbtype := ipb.SQLCheck_DB_UNSPECIFIED
112 |
113 | if flags.MySQLDatabase != "" {
114 | // We assume that the database is MySQL-compatible.
115 | sqldb, err = sql.Open("mysql", flags.MySQLDatabase)
116 | if err != nil {
117 | log.Fatalf("Error connecting to the database: %v\n", err)
118 | }
119 | defer sqldb.Close()
120 |
121 | dbtype = ipb.SQLCheck_DB_MYSQL
122 | } else if flags.CassandraDatabase != "" {
123 | cluster := gocql.NewCluster(flags.CassandraDatabase)
124 |
125 | // connect to the cluster
126 | cqldb, err = cluster.CreateSession()
127 | if err != nil {
128 | log.Fatalf("Error connecting to Cassandra: %v\n", err)
129 | }
130 | defer cqldb.Close()
131 |
132 | dbtype = ipb.SQLCheck_DB_CASSANDRA
133 | } else if flags.ElasticSearchDatabase != "" {
134 | cfg := els.Config{
135 | Addresses: []string{
136 | flags.ElasticSearchDatabase,
137 | },
138 | Transport: &http.Transport{
139 | TLSClientConfig: &tls.Config{
140 | InsecureSkipVerify: flags.ElasticSearchSkipVerify,
141 | },
142 | },
143 | }
144 |
145 | elsdb, err = els.NewClient(cfg)
146 | if err != nil {
147 | log.Fatalf("Error connecting to ElasticSearch: %v\n", err)
148 | }
149 |
150 | dbtype = ipb.SQLCheck_DB_ELASTICSEARCH
151 | }
152 | provider := &localScanAPIProvider{
153 | chrootPath: flags.ChrootPath,
154 | sqldb: sqldb,
155 | cqldb: cqldb,
156 | elsdb: elsdb,
157 | dbtype: dbtype,
158 | }
159 | os.Exit(scannercommon.RunScan(flags, provider))
160 | }
161 |
--------------------------------------------------------------------------------
/protofilehandler/proto_file_handler.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package protofilehandler provides a utility for reading and writing protos
16 | // into zipped or unzipped textproto or binproto files.
17 | package protofilehandler
18 |
19 | import (
20 | "compress/gzip"
21 | "errors"
22 | "io"
23 | "io/ioutil"
24 | "os"
25 | "path"
26 | "strings"
27 |
28 | "google.golang.org/protobuf/encoding/prototext"
29 | "google.golang.org/protobuf/proto"
30 | )
31 |
32 | type fileType struct {
33 | isGZipped bool
34 | isBinProto bool
35 | }
36 |
37 | func fileTypeForPath(filePath string) (*fileType, error) {
38 | parts := strings.Split(path.Base(filePath), ".")
39 | if len(parts) < 2 { // No extension
40 | return nil, errors.New("invalid filename: Doesn't have an extension")
41 | }
42 | isGZipped := false
43 | extension := parts[len(parts)-1]
44 | if extension == "gz" {
45 | isGZipped = true
46 | if len(parts) < 3 {
47 | return nil, errors.New("invalid filename: Gzipped file doesn't have an extension")
48 | }
49 | extension = parts[len(parts)-2]
50 | }
51 | isBinProto := false
52 | switch extension {
53 | case "binproto":
54 | isBinProto = true
55 | case "textproto":
56 | isBinProto = false
57 | default:
58 | return nil, errors.New("invalid filename: not a .textproto or .binproto")
59 | }
60 | return &fileType{isGZipped: isGZipped, isBinProto: isBinProto}, nil
61 | }
62 |
63 | // ReadProtoFromFile reads a proto message from a .textproto or .binproto file.
64 | // If the file is gzipped, it's unzipped first.
65 | func ReadProtoFromFile(filePath string, inputProto proto.Message) error {
66 | ft, err := fileTypeForPath(filePath)
67 | if err != nil {
68 | return err
69 | }
70 |
71 | var protoTxt []byte
72 | f, err := os.Open(filePath)
73 | if err != nil {
74 | return err
75 | }
76 | defer f.Close()
77 | if ft.isGZipped {
78 | reader, err := gzip.NewReader(f)
79 | if err != nil {
80 | return err
81 | }
82 | defer reader.Close()
83 | if protoTxt, err = ioutil.ReadAll(reader); err != nil {
84 | return err
85 | }
86 | } else if protoTxt, err = ioutil.ReadAll(f); err != nil {
87 | return err
88 | }
89 |
90 | if ft.isBinProto {
91 | if err := proto.Unmarshal(protoTxt, inputProto); err != nil {
92 | return err
93 | }
94 | } else if err := prototext.Unmarshal(protoTxt, inputProto); err != nil {
95 | return err
96 | }
97 | return nil
98 | }
99 |
100 | // WriteProtoToFile writes a proto message from a .textproto or .binproto file.
101 | // If the file name additionally has the .gz suffix, it's zipped before writing.
102 | func WriteProtoToFile(filePath string, outputProto proto.Message) error {
103 | ft, err := fileTypeForPath(filePath)
104 | if err != nil {
105 | return err
106 | }
107 | var protoTxt []byte
108 | if ft.isBinProto {
109 | if protoTxt, err = proto.Marshal(outputProto); err != nil {
110 | return err
111 | }
112 | } else {
113 | if protoTxt, err = (prototext.MarshalOptions{Multiline: true}.Marshal(outputProto)); err != nil {
114 | return err
115 | }
116 | }
117 |
118 | f, err := os.Create(filePath)
119 | if err != nil {
120 | return err
121 | }
122 | defer f.Close()
123 | if ft.isGZipped {
124 | writer := gzip.NewWriter(f)
125 | if _, err := writer.Write(protoTxt); err != nil {
126 | return err
127 | }
128 | if err := writer.Close(); err != nil {
129 | return err
130 | }
131 | } else if _, err := io.WriteString(f, string(protoTxt)); err != nil {
132 | return err
133 | }
134 | return nil
135 | }
136 |
--------------------------------------------------------------------------------
/protofilehandler/proto_file_handler_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package protofilehandler_test
16 |
17 | import (
18 | "io/ioutil"
19 | "path/filepath"
20 | "strings"
21 | "testing"
22 |
23 | "github.com/google/go-cmp/cmp"
24 | "google.golang.org/protobuf/testing/protocmp"
25 | "github.com/google/localtoast/protofilehandler"
26 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
27 | )
28 |
29 | func TestReadProtoFromFile(t *testing.T) {
30 | testDirPath := t.TempDir()
31 | var expectedConfig = &apb.ScanConfig{
32 | BenchmarkConfigs: []*apb.BenchmarkConfig{
33 | &apb.BenchmarkConfig{Id: "test-benchmark"},
34 | },
35 | }
36 | testPaths := []string{"config.textproto", "config.binproto", "config.textproto.gz"}
37 |
38 | for _, path := range testPaths {
39 | fullPath := filepath.Join(testDirPath, path)
40 | if err := protofilehandler.WriteProtoToFile(fullPath, expectedConfig); err != nil {
41 | t.Fatalf("protofilehandler.WriteProtoToFile(%s, %v) returned an error: %v", fullPath, expectedConfig, err)
42 | }
43 |
44 | config := &apb.ScanConfig{}
45 | if err := protofilehandler.ReadProtoFromFile(fullPath, config); err != nil {
46 | t.Fatalf("protofilehandler.ReadProtoFromFile(%s) returned an error: %v", fullPath, err)
47 | }
48 | if diff := cmp.Diff(expectedConfig, config, protocmp.Transform()); diff != "" {
49 | t.Errorf("protofilehandler.ReadProtoFromFile(%s) returned unexpected diff (-want +got):\n%s",
50 | fullPath, diff)
51 | }
52 | }
53 | }
54 |
55 | func TestReadProtoFromFileInvalidData(t *testing.T) {
56 | testDirPath := t.TempDir()
57 | testCases := []struct {
58 | desc string
59 | path string
60 | content string
61 | }{
62 | {
63 | desc: "textproto",
64 | path: "config.textproto",
65 | content: "invalid textproto",
66 | },
67 | {
68 | desc: "binproto",
69 | path: "config.binproto",
70 | content: "invalid binproto",
71 | },
72 | {
73 | desc: "gzipped file",
74 | path: "config.textproto.gz",
75 | content: "invalid gzip",
76 | },
77 | }
78 |
79 | for _, tc := range testCases {
80 | t.Run(tc.desc, func(t *testing.T) {
81 | fullPath := filepath.Join(testDirPath, tc.path)
82 | if err := ioutil.WriteFile(fullPath, []byte(tc.content), 0644); err != nil {
83 | t.Fatalf("failed to create config file %s: %v", fullPath, err)
84 | }
85 | config := &apb.ScanConfig{}
86 | if err := protofilehandler.ReadProtoFromFile(fullPath, config); err == nil {
87 | t.Errorf("protofilehandler.ReadProtoFromFile(%s) didn't return an error", fullPath)
88 | }
89 | })
90 | }
91 | }
92 |
93 | func TestWriteResultToFile(t *testing.T) {
94 | testDirPath := t.TempDir()
95 | var result = &apb.ScanResults{ScannerVersion: "1.0.0"}
96 | testCases := []struct {
97 | desc string
98 | path string
99 | expectedPrefix string
100 | }{
101 | {
102 | desc: "textproto",
103 | path: "output.textproto",
104 | expectedPrefix: "scanner_version:",
105 | },
106 | {
107 | desc: "binproto",
108 | path: "output.binproto",
109 | expectedPrefix: "\x1a\x051.0.0",
110 | },
111 | {
112 | desc: "gzipped file",
113 | path: "output.textproto.gz",
114 | expectedPrefix: "\x1f\x8b",
115 | },
116 | }
117 |
118 | for _, tc := range testCases {
119 | t.Run(tc.desc, func(t *testing.T) {
120 | fullPath := filepath.Join(testDirPath, tc.path)
121 | err := protofilehandler.WriteProtoToFile(fullPath, result)
122 | if err != nil {
123 | t.Fatalf("protofilehandler.WriteProtoToFile(%s, %v) returned an error: %v", fullPath, result, err)
124 | }
125 |
126 | content, err := ioutil.ReadFile(fullPath)
127 | if err != nil {
128 | t.Fatalf("error while reading %s: %v", fullPath, err)
129 | }
130 | prefix := content[:len(tc.expectedPrefix)]
131 | if diff := cmp.Diff(tc.expectedPrefix, string(prefix)); diff != "" {
132 | t.Errorf("%s contains unexpected prefix, diff (-want +got):\n%s", fullPath, diff)
133 | }
134 | })
135 | }
136 | }
137 |
138 | func TestInvalidProtoFileName(t *testing.T) {
139 | testDirPath := t.TempDir()
140 | testPaths := []string{
141 | "config.invalid-extension",
142 | "config.invalid-extension.gz",
143 | "no-extension",
144 | "no-extension.gz",
145 | }
146 | for _, p := range testPaths {
147 | fullPath := filepath.Join(testDirPath, p)
148 | config := &apb.ScanConfig{}
149 | if err := protofilehandler.ReadProtoFromFile(fullPath, config); err == nil || !strings.HasPrefix(err.Error(), "invalid filename") {
150 | t.Errorf("protofilehandler.ReadProtoFromFile(%s) didn't return an invalid file error: %v", fullPath, err)
151 | }
152 | if err := protofilehandler.WriteProtoToFile(fullPath, &apb.ScanResults{}); err == nil ||
153 | !strings.HasPrefix(err.Error(), "invalid filename") {
154 | t.Errorf("protofilehandler.WriteProtoToFile(%s) didn't return an invalid file error: %v", fullPath, err)
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/scanapi/scan_api.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package scanapi defines the Localtoast scan API
16 | // used to provide access to a local or remote filesystem and database to perform scans.
17 | package scanapi
18 |
19 | import (
20 | "context"
21 | "errors"
22 | "io"
23 |
24 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
25 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
26 | )
27 |
28 | var (
29 | // ErrEntryBeforeNext is the error returned if Entry() is called
30 | // and Next() was never called for a DirReader.
31 | ErrEntryBeforeNext = errors.New("Entry called before Next")
32 | // ErrNoMoreEntries is the error returned if Entry() is called
33 | // after Next() returned false for a DirReader.
34 | ErrNoMoreEntries = errors.New("Entry called with no more entries")
35 | )
36 |
37 | // Filesystem is an interface that gives read access to the filesystem of the machine to scan.
38 | type Filesystem interface {
39 | // OpenFile opens the specified file for reading.
40 | // It should return an os.IsNotExist error if the file doesn't exist.
41 | OpenFile(ctx context.Context, path string) (io.ReadCloser, error)
42 | // FilePermissions returns unix permission-related data for the specified file or directory.
43 | FilePermissions(ctx context.Context, path string) (*apb.PosixPermissions, error)
44 | // OpenDir opens the specified directory to list its content.
45 | OpenDir(ctx context.Context, path string) (DirReader, error)
46 | }
47 |
48 | // SQLQuerier is an interface that supports SQL queries to a target SQL database.
49 | type SQLQuerier interface {
50 | // SQLQuery executes SQL queries to a target SQL database and returns first result
51 | // row as a string.
52 | SQLQuery(ctx context.Context, query string) (string, error)
53 | // Returns the supported database type
54 | SupportedDatabase() (ipb.SQLCheck_SQLDatabase, error)
55 | }
56 |
57 | // ScanAPI is an interface that gives read access to the filesystem of
58 | // the machine to scan and can execute SQL queries on a single database.
59 | type ScanAPI interface {
60 | Filesystem
61 | SQLQuerier
62 | }
63 |
64 | // DirReader is an interface to iterate the entries inside a directory.
65 | type DirReader interface {
66 | // Next reads the next entry in the directory which can then be accessed using Entry.
67 | // It must be called at least once before calling Entry.
68 | // Returns false if there are no more entries in the directory.
69 | Next() bool
70 | // Entry returns the last entry read using Next or an error if it failed.
71 | Entry() (*apb.DirContent, error)
72 | // Close must be called to correctly dispose of the underlying reader.
73 | Close() error
74 | }
75 |
76 | type sliceDirReader struct {
77 | entries []*apb.DirContent
78 | idx int
79 | }
80 |
81 | func (s *sliceDirReader) Next() bool {
82 | s.idx++
83 | return s.idx < len(s.entries)
84 | }
85 |
86 | func (s *sliceDirReader) Entry() (*apb.DirContent, error) {
87 | if s.idx == -1 {
88 | return nil, ErrEntryBeforeNext
89 | }
90 | if s.idx >= len(s.entries) {
91 | return nil, ErrNoMoreEntries
92 | }
93 | return s.entries[s.idx], nil
94 | }
95 |
96 | func (s *sliceDirReader) Close() error {
97 | s.idx = len(s.entries)
98 | return nil
99 | }
100 |
101 | // SliceToDirReader returns a DirReader given a slice of entries.
102 | func SliceToDirReader(entries []*apb.DirContent) DirReader {
103 | return &sliceDirReader{entries: entries, idx: -1}
104 | }
105 |
106 | // DirReaderToSlice returns a slice of all the entries left in the given DirReader.
107 | // The DirReader is automatically disposed of by calling Close() at the end.
108 | func DirReaderToSlice(d DirReader) ([]*apb.DirContent, error) {
109 | defer d.Close()
110 | entries := make([]*apb.DirContent, 0)
111 | for d.Next() {
112 | e, err := d.Entry()
113 | if err != nil {
114 | return nil, err
115 | }
116 | entries = append(entries, e)
117 | }
118 | return entries, nil
119 | }
120 |
--------------------------------------------------------------------------------
/scanapi/scan_api_test.go:
--------------------------------------------------------------------------------
1 | package scanapi_test
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | "github.com/google/go-cmp/cmp"
8 | "google.golang.org/protobuf/testing/protocmp"
9 | "github.com/google/localtoast/scanapi"
10 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
11 | )
12 |
13 | var (
14 | testEntries = []*apb.DirContent{{Name: "e1"}, {Name: "e2"}}
15 | )
16 |
17 | func TestSliceToDirReader(t *testing.T) {
18 | d := scanapi.SliceToDirReader(testEntries)
19 | defer d.Close()
20 |
21 | dirReaderEntries := []*apb.DirContent{}
22 | for d.Next() {
23 | e, err := d.Entry()
24 | if err != nil {
25 | t.Fatalf("DirReader.Entry() had unexpected error: %v", err)
26 | }
27 | dirReaderEntries = append(dirReaderEntries, e)
28 | }
29 | if diff := cmp.Diff(testEntries, dirReaderEntries, protocmp.Transform()); diff != "" {
30 | t.Errorf("DirReader returned unexpected entries (-want +got):\n%s", diff)
31 | }
32 | }
33 |
34 | func TestSliceToDirReaderEmptySlice(t *testing.T) {
35 | d := scanapi.SliceToDirReader([]*apb.DirContent{})
36 | defer d.Close()
37 | if got := d.Next(); got {
38 | t.Errorf("DirReader.Next() got: %v, want: false", got)
39 | }
40 | }
41 |
42 | func TestSliceToDirReaderErrEntryBeforeNext(t *testing.T) {
43 | d := scanapi.SliceToDirReader(testEntries)
44 | defer d.Close()
45 | if _, err := d.Entry(); err == nil {
46 | t.Errorf("DirReader.Entry() err got: %v, want: error", err)
47 | }
48 | }
49 |
50 | func TestSliceToDirReaderErrNoMoreEntries(t *testing.T) {
51 | d := scanapi.SliceToDirReader([]*apb.DirContent{})
52 | defer d.Close()
53 | if got := d.Next(); got {
54 | t.Fatalf("DirReader.Next() got: %v, want: false", got)
55 | }
56 | if _, err := d.Entry(); err == nil {
57 | t.Errorf("DirReader.Entry() err got: %v, want: error", err)
58 | }
59 | }
60 |
61 | func TestSliceToDirReaderErrAfterClose(t *testing.T) {
62 | d := scanapi.SliceToDirReader(testEntries)
63 | d.Close()
64 | if got := d.Next(); got {
65 | t.Fatalf("DirReader.Next() got: %v, want: false", got)
66 | }
67 | if _, err := d.Entry(); err == nil {
68 | t.Errorf("DirReader.Entry() err got: %v, want: error", err)
69 | }
70 | }
71 |
72 | func TestSliceToDirReaderToSlice(t *testing.T) {
73 | d := scanapi.SliceToDirReader(testEntries)
74 | gotEntries, err := scanapi.DirReaderToSlice(d)
75 | if err != nil {
76 | t.Fatalf("DirReaderToSlice() had unexpected error: %v", err)
77 | }
78 | if diff := cmp.Diff(testEntries, gotEntries, protocmp.Transform()); diff != "" {
79 | t.Errorf("DirReaderToSlice() returned unexpected entries (-want +got):\n%s", diff)
80 | }
81 | }
82 |
83 | type errorDirReader struct{}
84 |
85 | func (errorDirReader) Next() bool {
86 | return true
87 | }
88 |
89 | func (errorDirReader) Entry() (*apb.DirContent, error) {
90 | return nil, errors.New("error")
91 | }
92 |
93 | func (errorDirReader) Close() error {
94 | return nil
95 | }
96 |
97 | func TestDirReaderToSliceError(t *testing.T) {
98 | if _, err := scanapi.DirReaderToSlice(errorDirReader{}); err == nil {
99 | t.Errorf("DirReaderToSlice() err got: %v, want: error", err)
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/scannerlib/api_error_wrapper.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package scannerlib
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | "io"
21 |
22 | "github.com/google/localtoast/scanapi"
23 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
24 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
25 | )
26 |
27 | // apiErrorWrapper is a wrapper around the scanner's scan API that makes the error
28 | // messages more verbose.
29 | type apiErrorWrapper struct {
30 | api scanapi.ScanAPI
31 | }
32 |
33 | func (w *apiErrorWrapper) OpenFile(ctx context.Context, path string) (io.ReadCloser, error) {
34 | rc, err := w.api.OpenFile(ctx, path)
35 | if err != nil {
36 | err = fmt.Errorf("api.OpenFile(%q): %w", path, err)
37 | }
38 | return rc, err
39 | }
40 |
41 | func (w *apiErrorWrapper) OpenDir(ctx context.Context, path string) (scanapi.DirReader, error) {
42 | d, err := w.api.OpenDir(ctx, path)
43 | if err != nil {
44 | err = fmt.Errorf("api.OpenDir(%q): %w", path, err)
45 | }
46 | return d, err
47 | }
48 |
49 | func (w *apiErrorWrapper) FilePermissions(ctx context.Context, path string) (*apb.PosixPermissions, error) {
50 | p, err := w.api.FilePermissions(ctx, path)
51 | if err != nil {
52 | err = fmt.Errorf("api.FilePermissions(%q): %w", path, err)
53 | }
54 | return p, err
55 | }
56 |
57 | func (w *apiErrorWrapper) SQLQuery(ctx context.Context, query string) (string, error) {
58 | res, err := w.api.SQLQuery(ctx, query)
59 | if err != nil {
60 | err = fmt.Errorf("api.SQLQuery(%q): %w", query, err)
61 | }
62 | return res, err
63 | }
64 |
65 | func (w *apiErrorWrapper) SupportedDatabase() (ipb.SQLCheck_SQLDatabase, error) {
66 | l, err := w.api.SupportedDatabase()
67 | if err != nil {
68 | err = fmt.Errorf("api.SupportedDatabase(): %w", err)
69 | }
70 | return l, err
71 | }
72 |
--------------------------------------------------------------------------------
/scannerlib/configchecks/check_common.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package configchecks
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | "time"
21 |
22 | "google.golang.org/protobuf/encoding/prototext"
23 | "google.golang.org/protobuf/proto"
24 | cpb "github.com/google/localtoast/scannerlib/proto/compliance_go_proto"
25 | "github.com/google/localtoast/scanapi"
26 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
27 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
28 | )
29 |
30 | // BenchmarkCheck is an interface representing a check to perform for one or more benchmarks
31 | // (e.g. checking for the existence of a given file).
32 | type BenchmarkCheck interface {
33 | // Exec executes the checks defined by the interface implementation.
34 | // The second parameter of the Exec() is the result propagated from the previous check, if any
35 | // The returned value of the Exec() is the check result to be propagated, if any (e.g. the output of a SQL Query)
36 | Exec(string) (ComplianceMap, string, error)
37 | // BenchmarkIDs returns the IDs of the benchmarks associated with this check.
38 | BenchmarkIDs() []string
39 | String() string
40 | }
41 |
42 | // ComplianceMap is returned by the checks to aggregate the results of benchmark configchecks.
43 | // It maps a CheckAlternative ID to a compliance result associated with that alternative.
44 | type ComplianceMap map[int]*apb.ComplianceResult
45 |
46 | // benchmark represents a single benchmark whose compliance the scanner should check.
47 | type benchmark struct {
48 | id string // The benchmark ID as seen in the benchmark config file.
49 | alts []*checkAlternative
50 | }
51 |
52 | // checkAlternative describes a series of compliance checks to execute. A
53 | // given benchmark is compliant if it satisfies one if its check alternatives.
54 | type checkAlternative struct {
55 | id int // Generated using a running counter, used to connect checks to their alternatives.
56 | proto *ipb.CheckAlternative
57 | }
58 |
59 | // timeoutOptions is used by each individual benchmark check to calculate its timeout.
60 | type timeoutOptions struct {
61 | globalTimeout time.Time
62 | benchmarkCheckDuration time.Duration
63 | }
64 |
65 | // benchmarkCheckTimeoutNow calculates the timeout of a benchmark if it was to start now.
66 | // Returns the minimum between globalTimeout and time.Now() + benchmarkCheckDuration.
67 | func (t *timeoutOptions) benchmarkCheckTimeoutNow() time.Time {
68 | if t.benchmarkCheckDuration == 0 {
69 | return t.globalTimeout
70 | }
71 | benchmarkTimeout := time.Now().Add(t.benchmarkCheckDuration)
72 | if t.globalTimeout.IsZero() || benchmarkTimeout.Before(t.globalTimeout) {
73 | return benchmarkTimeout
74 | }
75 | return t.globalTimeout
76 | }
77 |
78 | // parseCheckAlternatives deserializes the check alternatives from the benchmark config.
79 | func parseCheckAlternatives(config *apb.BenchmarkConfig, prevAlternativeID int) ([]*checkAlternative, error) {
80 | serialized := config.GetComplianceNote().GetScanInstructions()
81 | instruction := &ipb.BenchmarkScanInstruction{}
82 | // The scan instructions in the Grafeas Note are serialized since they're
83 | // implementation-specific, so we have to deserialize them first. The
84 | // instructions are either in the textproto or binproto format.
85 | bo := proto.UnmarshalOptions{DiscardUnknown: true}
86 | if err := bo.Unmarshal(serialized, instruction); err != nil {
87 | to := &prototext.UnmarshalOptions{DiscardUnknown: true}
88 | if err := to.Unmarshal(serialized, instruction); err != nil {
89 | return nil, err
90 | }
91 | }
92 | if len(instruction.GetCheckAlternatives()) == 0 {
93 | return nil, fmt.Errorf("scan instruction %v doesn't define any checks", instruction)
94 | }
95 | result := make([]*checkAlternative, 0, len(instruction.GetCheckAlternatives()))
96 | for _, alt := range instruction.GetCheckAlternatives() {
97 | prevAlternativeID++
98 | result = append(result, &checkAlternative{id: prevAlternativeID, proto: alt})
99 | }
100 | return result, nil
101 | }
102 |
103 | // CreateChecksFromConfig parses the scan config and creates the benchmark checks defined by it.
104 | func CreateChecksFromConfig(ctx context.Context, scanConfig *apb.ScanConfig, api scanapi.ScanAPI) ([]BenchmarkCheck, error) {
105 | prevAlternativeID := 0
106 | benchmarks := make([]*benchmark, 0, len(scanConfig.GetBenchmarkConfigs()))
107 | for _, b := range scanConfig.GetBenchmarkConfigs() {
108 | alts, err := parseCheckAlternatives(b, prevAlternativeID)
109 | if err != nil {
110 | return nil, err
111 | }
112 | benchmarks = append(benchmarks, &benchmark{id: b.GetId(), alts: alts})
113 | prevAlternativeID = alts[len(alts)-1].id
114 | }
115 |
116 | globalTimeout := time.Time{}
117 | if scanConfig.GetScanTimeout().AsDuration() > 0 {
118 | globalTimeout = time.Now().Add(scanConfig.GetScanTimeout().AsDuration())
119 | }
120 | timeout := &timeoutOptions{
121 | globalTimeout: globalTimeout,
122 | benchmarkCheckDuration: scanConfig.GetBenchmarkCheckTimeout().AsDuration(),
123 | }
124 |
125 | fileCheckBatches, err := createFileCheckBatchesFromConfig(ctx, benchmarks, scanConfig.GetOptOutConfig(), scanConfig.GetReplacementConfig(), timeout, api)
126 | if err != nil {
127 | return nil, err
128 | }
129 | sqlChecks, err := createSQLChecksFromConfig(ctx, benchmarks, timeout, api)
130 | if err != nil {
131 | return nil, err
132 | }
133 |
134 | checks := make([]BenchmarkCheck, 0, len(fileCheckBatches)+len(sqlChecks))
135 | for _, c := range sqlChecks {
136 | checks = append(checks, c)
137 | }
138 | for _, b := range fileCheckBatches {
139 | checks = append(checks, b)
140 | }
141 | return checks, nil
142 | }
143 |
144 | // ValidateScanInstructions validates the scan instructions in the given benchmark config and
145 | // returns an error if they're invalid.
146 | func ValidateScanInstructions(config *apb.BenchmarkConfig) error {
147 | alts, err := parseCheckAlternatives(config, 0)
148 | if err != nil {
149 | return err
150 | }
151 | for i, alt := range alts {
152 | if len(alt.proto.GetFileChecks()) == 0 && len(alt.proto.GetSqlChecks()) == 0 {
153 | return fmt.Errorf("alternative #%d in benchmark %s doesn't have any checks", i, config.GetId())
154 | }
155 | }
156 | return nil
157 | }
158 |
159 | // AddBenchmarkVersionToResults fills out the compliance_occurrence.version field of the
160 | // given compliance results based on the original benchmark config.
161 | func AddBenchmarkVersionToResults(results []*apb.ComplianceResult, configs []*apb.BenchmarkConfig) error {
162 | idToVersion := make(map[string]*cpb.ComplianceVersion)
163 | for _, c := range configs {
164 | if len(c.GetComplianceNote().GetVersion()) != 1 {
165 | return fmt.Errorf("benchmark config has multiple versions set: %v", c)
166 | }
167 | idToVersion[c.GetId()] = c.GetComplianceNote().GetVersion()[0]
168 | }
169 | for _, r := range results {
170 | version, ok := idToVersion[r.GetId()]
171 | if !ok {
172 | return fmt.Errorf("got compliance result with ID not in original benchmark config: %q", r.GetId())
173 | }
174 | r.GetComplianceOccurrence().Version = version
175 | }
176 | return nil
177 | }
178 |
--------------------------------------------------------------------------------
/scannerlib/configchecks/configchecks_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package configchecks_tests contains helper functions and tests for the configchecks package.
16 | package configchecks_test
17 |
18 | import (
19 | "bytes"
20 | "context"
21 | "errors"
22 | "fmt"
23 | "io"
24 | "os"
25 | "path"
26 | "time"
27 |
28 | "github.com/google/localtoast/scanapi"
29 | "github.com/google/localtoast/scannerlib/configchecks"
30 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
31 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
32 | )
33 |
34 | const (
35 | testDirPath = "/dir"
36 | testFilePath = "/dir/file"
37 | pipelineFileToken = "%%pipeline%%"
38 | testFileContent = "File content"
39 | emptyTestFilePath = "/dir/empty_file"
40 | unreadableFilePath = "/path/to/unreadable/file"
41 | nonExistentFilePath = "/path/to/non/existent/file"
42 | fakeQueryNoRows = "SELECT 1 WHERE FALSE"
43 | fakeQueryOneRow = "SELECT 1"
44 | fakeQueryError = "INVALID QUERY"
45 | queryErrorMsg = "invalid query"
46 | )
47 |
48 | var (
49 | today = int32(time.Now().Sub(time.Unix(0, 0)).Hours() / 24)
50 | )
51 |
52 | type fakeAPI struct {
53 | fileContent string
54 | openFileFunc func(ctx context.Context, filePath string) (io.ReadCloser, error)
55 | supportedDB ipb.SQLCheck_SQLDatabase
56 | }
57 |
58 | type fakeAPIOpt func(r *fakeAPI)
59 |
60 | func withFileContent(content string) fakeAPIOpt {
61 | return func(r *fakeAPI) {
62 | r.fileContent = content
63 | }
64 | }
65 |
66 | func withOpenFileFunc(f func(ctx context.Context, filePath string) (io.ReadCloser, error)) fakeAPIOpt {
67 | return func(r *fakeAPI) {
68 | r.openFileFunc = f
69 | }
70 | }
71 |
72 | func withSupportedDatabase(db ipb.SQLCheck_SQLDatabase) fakeAPIOpt {
73 | return func(r *fakeAPI) {
74 | r.supportedDB = db
75 | }
76 | }
77 |
78 | func newFakeAPI(opts ...fakeAPIOpt) *fakeAPI {
79 | r := &fakeAPI{
80 | fileContent: testFileContent,
81 | openFileFunc: nil,
82 | supportedDB: ipb.SQLCheck_DB_MYSQL,
83 | }
84 | for _, opt := range opts {
85 | opt(r)
86 | }
87 | return r
88 | }
89 |
90 | func (r *fakeAPI) OpenFile(ctx context.Context, filePath string) (io.ReadCloser, error) {
91 | if r.openFileFunc != nil {
92 | return r.openFileFunc(ctx, filePath)
93 | }
94 | switch filePath {
95 | case emptyTestFilePath:
96 | return io.NopCloser(bytes.NewReader([]byte{})), nil
97 | case unreadableFilePath:
98 | return nil, errors.New("io error")
99 | case nonExistentFilePath:
100 | return nil, os.ErrNotExist
101 | default:
102 | return io.NopCloser(bytes.NewReader([]byte(r.fileContent))), nil
103 | }
104 | }
105 |
106 | func (fakeAPI) OpenDir(ctx context.Context, filePath string) (scanapi.DirReader, error) {
107 | switch filePath {
108 | case testDirPath:
109 | return scanapi.SliceToDirReader([]*apb.DirContent{
110 | {Name: path.Base(emptyTestFilePath), IsDir: false},
111 | {Name: path.Base(testFilePath), IsDir: false},
112 | }), nil
113 | case nonExistentFilePath:
114 | return nil, os.ErrNotExist
115 | default:
116 | return nil, errors.New("not a directory")
117 | }
118 | }
119 |
120 | func (fakeAPI) FilePermissions(ctx context.Context, filePath string) (*apb.PosixPermissions, error) {
121 | switch filePath {
122 | case nonExistentFilePath:
123 | return nil, os.ErrNotExist
124 | default:
125 | return &apb.PosixPermissions{
126 | PermissionNum: 0644,
127 | Uid: 0,
128 | User: "root",
129 | Gid: 0,
130 | Group: "root",
131 | }, nil
132 | }
133 | }
134 |
135 | func (fakeAPI) SQLQuery(ctx context.Context, query string) (string, error) {
136 | switch query {
137 | case fakeQueryNoRows:
138 | return "", nil
139 | case fakeQueryOneRow:
140 | return "testValue", nil
141 | case fakeQueryError:
142 | return "", errors.New(queryErrorMsg)
143 | default:
144 | return "", fmt.Errorf("the query %q is not supported by fakeAPI", query)
145 | }
146 | }
147 |
148 | func (r *fakeAPI) SupportedDatabase() (ipb.SQLCheck_SQLDatabase, error) {
149 | return r.supportedDB, nil
150 | }
151 |
152 | func singleComplianceResult(m configchecks.ComplianceMap) (result *apb.ComplianceResult, gotSingleton bool) {
153 | results := []*apb.ComplianceResult{}
154 | for _, v := range m {
155 | results = append(results, v)
156 | }
157 | if len(results) != 1 {
158 | return nil, false
159 | }
160 | return results[0], true
161 | }
162 |
--------------------------------------------------------------------------------
/scannerlib/configchecks/group_criteria.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package configchecks
16 |
17 | import (
18 | "errors"
19 | "fmt"
20 | "log"
21 | "regexp"
22 | "strconv"
23 | "strings"
24 | "time"
25 |
26 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
27 | )
28 |
29 | var (
30 | umaskRe = regexp.MustCompile("^0?[0-7][0-7][0-7]$")
31 | )
32 |
33 | type groupCriteria struct {
34 | regex string
35 | criteria []groupCriterion
36 | }
37 |
38 | func newGroupCriteria(regex string, numSubexp int, gcs []*ipb.GroupCriterion, matchType ipb.ContentEntryCheck_MatchType) (*groupCriteria, error) {
39 | criteria := make([]groupCriterion, 0, len(gcs))
40 | for _, gc := range gcs {
41 | i := int(gc.GetGroupIndex())
42 | if i <= 0 || i > numSubexp {
43 | return nil, fmt.Errorf("group criteria index %d out of bounds", i)
44 | }
45 |
46 | var m groupCriterionMatcher
47 | switch t := gc.GetType(); t {
48 | case ipb.GroupCriterion_LESS_THAN:
49 | m = &lessThanMatcher{cmp: getCmp(gc), cmpStr: getCmpStr(gc)}
50 | case ipb.GroupCriterion_GREATER_THAN:
51 | m = &greaterThanMatcher{cmp: getCmp(gc), cmpStr: getCmpStr(gc)}
52 | case ipb.GroupCriterion_NO_LESS_RESTRICTIVE_UMASK:
53 | if gc.GetToday() != nil { // today set instead of const
54 | return nil, errors.New("GroupCriterion_NO_LESS_RESTRICTIVE_UMASK requires a constant to compare to")
55 | }
56 | m = &umaskMatcher{wantMask: gc.GetConst(), cmpStr: getCmpStr(gc)}
57 | case ipb.GroupCriterion_UNIQUE:
58 | if matchType == ipb.ContentEntryCheck_NONE_MATCH {
59 | return nil, errors.New("GroupCriterion_UNIQUE and ContentEntryCheck_NONE_MATCH are incompatible")
60 | }
61 | m = &uniqueMatcher{seen: make(map[string]bool)}
62 | default:
63 | return nil, fmt.Errorf("unrecognized group criterion type %v", t)
64 | }
65 |
66 | criteria = append(criteria, groupCriterion{
67 | index: i,
68 | matcher: m,
69 | })
70 | }
71 |
72 | return &groupCriteria{
73 | regex: regex,
74 | criteria: criteria,
75 | }, nil
76 | }
77 |
78 | // check returns whether all of the group criteria are met by the entry.
79 | // The check assumes that entry matches gc.re so groups can safely be extracted.
80 | // Also it assumes that all indices of the contained groupCriterion objects have
81 | // been bounds checked before.
82 | func (gc *groupCriteria) check(entry string) bool {
83 | if len(gc.criteria) == 0 {
84 | return true
85 | }
86 | groups := compiledRegex(gc.regex).FindStringSubmatch(entry)
87 | for _, c := range gc.criteria {
88 | g := groups[c.index]
89 | if !c.matcher.match(g) {
90 | return false
91 | }
92 | }
93 | return true
94 | }
95 |
96 | func (gc *groupCriteria) String() string {
97 | if len(gc.criteria) == 0 {
98 | return ""
99 | }
100 | strs := make([]string, 0, len(gc.criteria))
101 | for _, crit := range gc.criteria {
102 | strs = append(strs, crit.String())
103 | }
104 | return "{" + strings.Join(strs, ", ") + "}"
105 | }
106 |
107 | type groupCriterion struct {
108 | index int
109 | matcher groupCriterionMatcher
110 | }
111 |
112 | func (gc *groupCriterion) String() string {
113 | return fmt.Sprintf("[group#%d %s]", gc.index, gc.matcher)
114 | }
115 |
116 | type groupCriterionMatcher interface {
117 | match(group string) bool
118 | String() string
119 | }
120 |
121 | type lessThanMatcher struct {
122 | cmp int32
123 | cmpStr string
124 | }
125 |
126 | func (m *lessThanMatcher) match(group string) bool {
127 | parsed, err := strconv.ParseInt(group, 10, 32)
128 | if err != nil {
129 | log.Printf("unable to parse %q as int32: %v", group, err)
130 | return false
131 | }
132 | val := int32(parsed)
133 | return val < m.cmp
134 | }
135 |
136 | func (m *lessThanMatcher) String() string {
137 | return "< " + m.cmpStr
138 | }
139 |
140 | type greaterThanMatcher struct {
141 | cmp int32
142 | cmpStr string
143 | }
144 |
145 | func (m *greaterThanMatcher) match(group string) bool {
146 | parsed, err := strconv.ParseInt(group, 10, 32)
147 | if err != nil {
148 | log.Printf("unable to parse %q as int32: %v", group, err)
149 | return false
150 | }
151 | val := int32(parsed)
152 | return val > m.cmp
153 | }
154 |
155 | func (m *greaterThanMatcher) String() string {
156 | return "> " + m.cmpStr
157 | }
158 |
159 | type umaskMatcher struct {
160 | wantMask int32
161 | cmpStr string
162 | }
163 |
164 | func (m *umaskMatcher) match(group string) bool {
165 | if !umaskRe.MatchString(group) {
166 | log.Printf("unable to parse %q as a umask", group)
167 | return false
168 | }
169 | parsed, err := strconv.ParseInt(group, 8, 32)
170 | if err != nil {
171 | log.Printf("unable to parse %q as a umask: %v", group, err)
172 | return false
173 | }
174 | mask := int32(parsed)
175 | // At least all bits that are set in the expected mask have to be set in the actual mask.
176 | // More set bits would mean more restrictive permissions.
177 | return (m.wantMask & mask) == m.wantMask
178 | }
179 |
180 | func (m *umaskMatcher) String() string {
181 | return "not less restrictive than " + m.cmpStr
182 | }
183 |
184 | type uniqueMatcher struct {
185 | seen map[string]bool
186 | }
187 |
188 | func (m *uniqueMatcher) match(group string) bool {
189 | if m.seen[group] {
190 | return false
191 | }
192 | m.seen[group] = true
193 | return true
194 | }
195 |
196 | func (m *uniqueMatcher) String() string {
197 | return "is unique"
198 | }
199 |
200 | // getCmp returns the value to compare the group against for a given LESS_THAN or GREATER_THAN group criterion.
201 | // In case the today field is set on the proto, the number of days since the epoch for the current time is returned.
202 | func getCmp(gc *ipb.GroupCriterion) int32 {
203 | if gc.GetToday() != nil {
204 | now := time.Now()
205 | epoch := time.Unix(0, 0)
206 | days := now.Sub(epoch).Hours() / 24
207 | return int32(days)
208 | }
209 | return gc.GetConst()
210 | }
211 |
212 | func getCmpStr(gc *ipb.GroupCriterion) string {
213 | if gc.GetToday() != nil {
214 | return "today"
215 | }
216 | return strconv.Itoa(int(gc.GetConst()))
217 | }
218 |
--------------------------------------------------------------------------------
/scannerlib/configchecks/sql_check.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package configchecks
16 |
17 | import (
18 | "context"
19 | "errors"
20 | "fmt"
21 | "regexp"
22 |
23 | cpb "github.com/google/localtoast/scannerlib/proto/compliance_go_proto"
24 | "github.com/google/localtoast/scanapi"
25 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
26 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
27 | )
28 |
29 | // SQLCheck is an implementation of configchecks.BenchmarkCheck
30 | // It runs queries on the database specified by the check.
31 | type SQLCheck struct {
32 | ctx context.Context
33 | benchmarkID string
34 | alternativeID int
35 | checkInstruction *ipb.SQLCheck
36 | querier scanapi.SQLQuerier
37 | }
38 |
39 | // Exec executes the SQL checks and returns the compliance status.
40 | func (c *SQLCheck) Exec(prvRes string) (ComplianceMap, string, error) {
41 | query := c.checkInstruction.GetQuery()
42 | var resVal string = ""
43 |
44 | var reason string
45 | if c.checkInstruction.TargetDatabase == ipb.SQLCheck_DB_MYSQL || c.checkInstruction.TargetDatabase == ipb.SQLCheck_DB_CASSANDRA {
46 | // Check number of returned rows for MySQL and Cassandra
47 | resVal, err := c.querier.SQLQuery(c.ctx, query)
48 | if err != nil {
49 | return nil, "", err
50 | }
51 | if len(resVal) > 0 && !c.checkInstruction.GetExpectResults() {
52 | reason = fmt.Sprintf("Expected no results for query %q, but got some.", query)
53 | } else if len(resVal) == 0 && c.checkInstruction.GetExpectResults() {
54 | reason = fmt.Sprintf("Expected results for query %q, but got none.", query)
55 | }
56 |
57 | } else if c.checkInstruction.TargetDatabase == ipb.SQLCheck_DB_ELASTICSEARCH {
58 | // Perform regex match on result string for ElasticSearch
59 | filterRegex, err := regexp.Compile("^" + c.checkInstruction.FilterRegex + "$")
60 | if err != nil {
61 | return nil, "", err
62 | }
63 | // Execute ElasticSearch query
64 | resVal, err = c.querier.SQLQuery(c.ctx, query)
65 | if err != nil {
66 | return nil, "", err
67 | }
68 | // Check if regex obtains results and compare with expected result
69 | if !filterRegex.MatchString(resVal) && c.checkInstruction.GetExpectResults() {
70 | reason = fmt.Sprintf("ElasticSearch response %q does not match the Filter Regex %q and it should.", resVal, c.checkInstruction.FilterRegex)
71 | } else if filterRegex.MatchString(resVal) && !c.checkInstruction.GetExpectResults() {
72 | reason = fmt.Sprintf("ElasticSearch response %q matches the Filter Regex %q and it should not.", resVal, c.checkInstruction.FilterRegex)
73 | }
74 | } else {
75 | // Return error for unsupported database
76 | return nil, "", errors.New("unsupported database for SQLCheck")
77 | }
78 |
79 | if reason != "" && c.checkInstruction.GetNonComplianceMsg() != "" {
80 | reason = c.checkInstruction.GetNonComplianceMsg()
81 | }
82 | r := &apb.ComplianceResult{
83 | Id: c.benchmarkID,
84 | ComplianceOccurrence: &cpb.ComplianceOccurrence{
85 | NonComplianceReason: reason,
86 | },
87 | }
88 | return ComplianceMap{c.alternativeID: r}, resVal, nil
89 | }
90 |
91 | // BenchmarkIDs returns the IDs of the benchmarks associated with this check.
92 | func (c *SQLCheck) BenchmarkIDs() []string {
93 | // We don't do batching for SQL checks, so we will always have exactly one ID.
94 | return []string{c.benchmarkID}
95 | }
96 |
97 | func (c *SQLCheck) String() string {
98 | return fmt.Sprintf("[SQL check with id %q]", c.benchmarkID)
99 | }
100 |
101 | // createSQLChecksFromConfig parses the benchmark config and creates the executable
102 | // SQL checks that it defines.
103 | func createSQLChecksFromConfig(ctx context.Context, benchmarks []*benchmark, timeout *timeoutOptions, sq scanapi.SQLQuerier) ([]*SQLCheck, error) {
104 | // TODO(b/235991635): Use timeout.
105 | checks := []*SQLCheck{}
106 | for _, b := range benchmarks {
107 | for _, alt := range b.alts {
108 | for _, sqlCheckInstruction := range alt.proto.GetSqlChecks() {
109 | dbtype, err := sq.SupportedDatabase()
110 | if err != nil {
111 | return nil, err
112 | }
113 | if dbtype != sqlCheckInstruction.GetTargetDatabase() {
114 | return nil, fmt.Errorf("sql check %v does not match the connected database type %v", sqlCheckInstruction.GetTargetDatabase(), dbtype)
115 | }
116 | if sqlCheckInstruction.GetTargetDatabase() == ipb.SQLCheck_DB_ELASTICSEARCH && sqlCheckInstruction.GetFilterRegex() == "" {
117 | return nil, errors.New("no regex provided for ElasticSearch database SQLCheck")
118 | }
119 | checks = append(checks, &SQLCheck{
120 | ctx: ctx,
121 | benchmarkID: b.id,
122 | alternativeID: alt.id,
123 | checkInstruction: sqlCheckInstruction,
124 | querier: sq,
125 | })
126 | }
127 | }
128 | }
129 | return checks, nil
130 | }
131 |
--------------------------------------------------------------------------------
/scannerlib/proto/api.proto:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | syntax = "proto3";
18 |
19 | package localtoast;
20 |
21 | import "google/protobuf/duration.proto";
22 | import "google/protobuf/timestamp.proto";
23 | import "proto/v1/compliance.proto";
24 |
25 | option go_package = "github.com/google/localtoast/scannerlib/proto/api_go_proto";
26 |
27 | message ScanConfig {
28 | // The maximum amount of time the entire scan can run for.
29 | google.protobuf.Duration scan_timeout = 1;
30 | // The maximum amout of time each individual benchmark check can run for.
31 | google.protobuf.Duration benchmark_check_timeout = 2;
32 | // A list of files to opt out of being displayed in the scan results.
33 | OptOutConfig opt_out_config = 3;
34 | // A list of replacements to apply to the benchmark config used.
35 | ReplacementConfig replacement_config = 5;
36 | repeated BenchmarkConfig benchmark_configs = 4;
37 | }
38 |
39 | message OptOutConfig {
40 | // Don't display the file content / filename of the files whose path matches
41 | // a regex in the list.
42 | repeated string content_optout_regexes = 1;
43 | repeated string filename_optout_regexes = 2;
44 | // Skip the files/directories when traversing the filesystem recursively if
45 | // they match a regex in the list.
46 | repeated string traversal_optout_regexes = 3;
47 | }
48 |
49 | message ReplacementConfig {
50 | // Replace paths starting with the specified prefixes.
51 | map path_prefix_replacements = 1;
52 | }
53 |
54 | message BenchmarkConfig {
55 | string id = 1;
56 | grafeas.v1.ComplianceNote compliance_note = 2;
57 | }
58 |
59 | message ScanResults {
60 | google.protobuf.Timestamp start_time = 1;
61 | google.protobuf.Timestamp end_time = 2;
62 | string scanner_version = 3;
63 | string benchmark_version = 4;
64 | string benchmark_document = 8;
65 | ScanStatus status = 5;
66 | repeated ComplianceResult compliant_benchmarks = 6;
67 | repeated ComplianceResult non_compliant_benchmarks = 7;
68 | }
69 |
70 | message ScanStatus {
71 | ScanStatusEnum status = 1;
72 | string failure_reason = 2;
73 | enum ScanStatusEnum {
74 | UNSPECIFIED = 0;
75 | FAILED = 1;
76 | SUCCEEDED = 2;
77 | }
78 | }
79 |
80 | message ComplianceResult {
81 | reserved 2;
82 | // ID of the Compliance Note associated with the Compliance Occurrence.
83 | // This is used to identify which benchmark failed.
84 | string id = 1;
85 | grafeas.v1.ComplianceOccurrence compliance_occurrence = 3;
86 | }
87 |
88 | // Messages used by the ScanApiProvider to interact with the file system.
89 | message DirContent {
90 | string name = 1;
91 | bool is_dir = 2;
92 | bool is_symlink = 3;
93 | }
94 | message PosixPermissions {
95 | // File permissions represented by 4 octal digits
96 | // (flags, owner, group, other), e.g. 1744
97 | int32 permission_num = 1;
98 | int32 uid = 2;
99 | string user = 3; // "" if unowned
100 | int32 gid = 4;
101 | string group = 5; // "" if unowned
102 | }
103 |
104 | // Per-OS benchmark configs are stored in .textproto files using this format.
105 | message PerOsBenchmarkConfig {
106 | // The OS and config versions the benchmarks applies to.
107 | grafeas.v1.ComplianceVersion version = 1;
108 | // The benchmark IDs that apply to this OS. The referenced benchmarks are
109 | // defined in separate benchmark definition files.
110 | repeated string benchmark_id = 2;
111 | // Overrides the default profile level for specific benchmarks.
112 | repeated ProfileLevelOverride profile_level_override = 3;
113 | }
114 |
115 | message ProfileLevelOverride {
116 | int32 level = 1;
117 | repeated string benchmark_id = 2;
118 | }
119 |
--------------------------------------------------------------------------------
/scannerlib/testconfigcreator/test_config_creator.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package testconfigcreator provides util functions for creating benchmark configs for testing.
16 | package testconfigcreator
17 |
18 | import (
19 | "testing"
20 |
21 | "google.golang.org/protobuf/encoding/prototext"
22 | cpb "github.com/google/localtoast/scannerlib/proto/compliance_go_proto"
23 | apb "github.com/google/localtoast/scannerlib/proto/api_go_proto"
24 | ipb "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto"
25 | )
26 |
27 | // SingleFileWithPath creates a FileSet that defines a single file with the given path.
28 | func SingleFileWithPath(path string) *ipb.FileSet {
29 | return &ipb.FileSet{
30 | FilePath: &ipb.FileSet_SingleFile_{SingleFile: &ipb.FileSet_SingleFile{Path: path}},
31 | }
32 | }
33 |
34 | // NewBenchmarkConfig creates a benchmark config with the given ID and scan instructions.
35 | func NewBenchmarkConfig(t *testing.T, id string, scanInstruction *ipb.BenchmarkScanInstruction) *apb.BenchmarkConfig {
36 | t.Helper()
37 | serializedInstruction, err := prototext.Marshal(scanInstruction)
38 | if err != nil {
39 | t.Fatalf("error while serializing scan instructions %v: %v", scanInstruction, err)
40 | }
41 | return &apb.BenchmarkConfig{
42 | Id: id,
43 | ComplianceNote: &cpb.ComplianceNote{ScanInstructions: serializedInstruction},
44 | }
45 | }
46 |
47 | // NewFileScanInstruction creates a scan instruction with a single alternative from the
48 | // given file checks.
49 | func NewFileScanInstruction(fileChecks []*ipb.FileCheck) *ipb.BenchmarkScanInstruction {
50 | return &ipb.BenchmarkScanInstruction{
51 | CheckAlternatives: []*ipb.CheckAlternative{{FileChecks: fileChecks}},
52 | }
53 | }
54 |
55 | // NewSQLScanInstruction creates a scan instruction with a single alternative from the
56 | // given SQL checks.
57 | func NewSQLScanInstruction(sqlChecks []*ipb.SQLCheck) *ipb.BenchmarkScanInstruction {
58 | return &ipb.BenchmarkScanInstruction{
59 | CheckAlternatives: []*ipb.CheckAlternative{{SqlChecks: sqlChecks}},
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/scannerlib/version.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package scannerlib
16 |
17 | // ScannerVersion is the current version of the scanner that's displayed in the scan results.
18 | const ScannerVersion = "1.1.7"
19 |
--------------------------------------------------------------------------------
/sqlquerier/sql_querier.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Package sqlquerier provides an utility function for running SQL queries.
16 | package sqlquerier
17 |
18 | import (
19 | "context"
20 | "database/sql"
21 | "errors"
22 | )
23 |
24 | // Query executes a SQL query and returns the first row in the result.
25 | func Query(ctx context.Context, db *sql.DB, query string) (string, error) {
26 | if db == nil {
27 | return "", errors.New("no database specified. Please provide one using the --database flag")
28 | }
29 | rows, err := db.Query(query)
30 | if err != nil {
31 | return "", err
32 | }
33 | defer rows.Close()
34 |
35 | result := ""
36 | if rows.Next() {
37 | rows.Scan(&result)
38 | }
39 |
40 | if rows.Err() != nil {
41 | return "", rows.Err()
42 | }
43 | return result, nil
44 | }
45 |
--------------------------------------------------------------------------------
/sqlquerier/sql_querier_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package sqlquerier_test
16 |
17 | import (
18 | "context"
19 | "strings"
20 | "testing"
21 |
22 | "github.com/google/localtoast/fakedb"
23 | "github.com/google/localtoast/sqlquerier"
24 | )
25 |
26 | func TestSQLCheckWithNoDatabaseFlag(t *testing.T) {
27 | q := "query"
28 | _, err := sqlquerier.Query(context.Background(), nil, q)
29 | if err == nil {
30 | t.Errorf("sqlquerier.Query(context.Background(), nil, %q) expected to return an error but got none", q)
31 | }
32 | }
33 |
34 | func TestSQLCheck(t *testing.T) {
35 | testCases := []struct {
36 | desc string
37 | query string
38 | want string
39 | expectError bool
40 | errorMsg string
41 | }{
42 | {
43 | desc: "SQLCheck one row returned",
44 | query: fakedb.QueryOneRow,
45 | want: "fakeValue",
46 | },
47 | {
48 | desc: "SQLCheck no rows returned",
49 | query: fakedb.QueryNoRows,
50 | want: "",
51 | },
52 | {
53 | desc: "SQLCheck propagates errors",
54 | query: fakedb.QueryError,
55 | expectError: true,
56 | errorMsg: fakedb.ErrorMsg,
57 | },
58 | }
59 | for _, tc := range testCases {
60 | t.Run(tc.desc, func(t *testing.T) {
61 | db, err := fakedb.Open(&fakedb.FakeDB{})
62 | if err != nil {
63 | t.Errorf("fakedb.Open had an unexpected error: %v", err)
64 | }
65 |
66 | got, err := sqlquerier.Query(context.Background(), db, tc.query)
67 |
68 | if err != nil {
69 | if !tc.expectError {
70 | t.Errorf("sqlquerier.Query(ctx, db, %q) had an unexpected error: %v", tc.query, err)
71 | }
72 | if !strings.Contains(err.Error(), tc.errorMsg) {
73 | t.Errorf("sqlquerier.Query(ctx, db, %q) returned the wrong error: want %q, got %v", tc.query, tc.errorMsg, err)
74 | }
75 | }
76 | if tc.want != got {
77 | t.Errorf("sqlquerier.Query(ctx, db, %q) returned wrong string value: want %q value, got %q", tc.query, tc.want, got)
78 | }
79 | })
80 | }
81 | }
82 |
--------------------------------------------------------------------------------