├── .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 | --------------------------------------------------------------------------------