Skip to content

Commit

Permalink
Added tfsec as a security linter (#199)
Browse files Browse the repository at this point in the history
Added tfsec as a security linter. Includes a small fix to testing that
prevents accidentally linting the json output of trunk check.

---------

Co-authored-by: Tyler Jang <[email protected]>
  • Loading branch information
puzzler7 and TylerJang27 authored Mar 10, 2023
1 parent 34e8447 commit 8d26afc
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 23 deletions.
1 change: 1 addition & 0 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ runtimes:

lint:
enabled:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
Expand Down
20 changes: 0 additions & 20 deletions linters/terraform/test_data/terraform_v1.1.0_variables.check.shot
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,6 @@ exports[`Testing linter terraform test variables 1`] = `
"message": "Terraform 0.11 and earlier required type constraints to be given in quotes, but that form is now deprecated and will be removed in a future version of Terraform. Remove the quotes around "map" and write map(string) instead to explicitly indicate that the map elements are strings.",
"targetType": "terraform",
},
{
"bucket": "terraform",
"code": "Missing value",
"file": "test_data/variables.in.tf.json",
"level": "LEVEL_HIGH",
"line": "1",
"linter": "terraform",
"message": "The JSON data ends prematurely.",
"targetType": "terraform",
},
{
"bucket": "terraform",
"code": "Root value must be object",
"file": "test_data/variables.in.tf.json",
"level": "LEVEL_HIGH",
"line": "1",
"linter": "terraform",
"message": "The root value in a JSON-based configuration must be either a JSON object or a JSON array of objects.",
"targetType": "terraform",
},
],
"lintActions": [
{
Expand Down
32 changes: 32 additions & 0 deletions linters/tfsec/plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: 0.1
lint:
downloads:
- name: tfsec
version: 1.28.1
executable: true
downloads:
- os:
linux: linux
macos: darwin
cpu:
x86_64: amd64
arm_64: arm64
url: https://github.com/aquasecurity/tfsec/releases/download/v${version}/tfsec-${os}-${cpu}
definitions:
- name: tfsec
files: [terraform]
download: tfsec
known_good_version: 1.28.1
commands:
- name: lint
output: sarif
target: ${parent}
run: tfsec ${target} --format=sarif
success_codes: [0, 1]
read_output_from: stdout
environment:
- name: PATH
list: ["${linter}"]
version_command:
parse_regex: v${semver}
run: tfsec --version
3 changes: 3 additions & 0 deletions linters/tfsec/test_data/aws.in.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "foo" {
instance_type = "t1.2xlarge"
}
43 changes: 43 additions & 0 deletions linters/tfsec/test_data/tfsec_v1.28.1_aws.check.shot
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Testing linter tfsec test aws 1`] = `
{
"issues": [
{
"bucket": "tfsec",
"code": "aws-ec2-enable-at-rest-encryption",
"column": "1",
"file": "aws.in.tf",
"level": "LEVEL_HIGH",
"line": "1",
"linter": "tfsec",
"message": "Root block device is not encrypted.",
"targetType": "terraform",
},
{
"bucket": "tfsec",
"code": "aws-ec2-enforce-http-token-imds",
"column": "1",
"file": "aws.in.tf",
"level": "LEVEL_HIGH",
"line": "1",
"linter": "tfsec",
"message": "Instance does not require IMDS access to require a token",
"targetType": "terraform",
},
],
"lintActions": [
{
"command": "lint",
"fileGroupName": "terraform",
"linter": "tfsec",
"paths": [
"test_data",
],
"verb": "TRUNK_VERB_CHECK",
},
],
"taskFailures": [],
"unformattedFiles": [],
}
`;
2 changes: 2 additions & 0 deletions linters/tfsec/tfsec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { linterCheckTest } from "tests";
linterCheckTest({ linterName: "tfsec" });
5 changes: 3 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ make the discovery, management and integration of new tools as straight-forward
| Ruby | [brakeman], [rubocop], [rufo], [semgrep], [standardrb] |
| Rust | [clippy], [rustfmt] |
| Scala | [scalafmt] |
| Security | [nancy], [trivy] |
| Security | [nancy], [trivy], [tfsec] |
| SQL | [sqlfluff], [sqlfmt], [sql-formatter] |
| SVG | [svgo] |
| Swift | [stringslint], [swiftlint], [swiftformat] |
| Terraform | [terraform] (validate and fmt), [tflint]<sup><a href="#note-tflint">2</a></sup> |
| Terraform | [terraform] (validate and fmt), [tflint]<sup><a href="#note-tflint">2</a></sup>, [tfsec] |
| TOML | [taplo] |
| Typescript | [eslint], [prettier], [rome], [semgrep] |
| YAML | [prettier], [semgrep], [yamllint] |
Expand Down Expand Up @@ -140,6 +140,7 @@ make the discovery, management and integration of new tools as straight-forward
[taplo]: https://github.com/tamasfe/taplo#readme
[terraform]: https://developer.hashicorp.com/terraform/cli/code
[tflint]: https://github.com/terraform-linters/tflint#readme
[tfsec]: https://github.com/aquasecurity/tfsec
[trivy]: https://github.com/aquasecurity/trivy#readme
[yamllint]: https://github.com/adrienverge/yamllint#readme
[yapf]: https://github.com/google/yapf#readme
Expand Down
4 changes: 3 additions & 1 deletion tests/driver/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,9 @@ export class TrunkDriver {
*/
async runCheckUnit(targetRelativePath: string, linter: string): Promise<TestResult> {
const targetAbsPath = path.resolve(this.sandboxPath ?? "", targetRelativePath);
const resultJsonPath = `${targetAbsPath}.json`;
// this has been changed from ".json" to ".out.json" for linters that run on terraform files
// terraform extensions are .tf and .tf.json - this change prevents accidentally linting the trunk output
const resultJsonPath = `${targetAbsPath}.out.json`;
const args = `--upstream=false ${targetAbsPath}`;
this.debug("Running `trunk check` on %s", targetRelativePath);
return await this.runCheck({ args, linter, targetAbsPath, resultJsonPath });
Expand Down

0 comments on commit 8d26afc

Please sign in to comment.