github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/report/table/misconfig_test.go (about)

     1  package table_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  
     9  	dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
    10  	ftypes "github.com/devseccon/trivy/pkg/fanal/types"
    11  	"github.com/devseccon/trivy/pkg/report/table"
    12  	"github.com/devseccon/trivy/pkg/types"
    13  )
    14  
    15  func TestMisconfigRenderer(t *testing.T) {
    16  
    17  	tests := []struct {
    18  		name               string
    19  		input              types.Result
    20  		includeNonFailures bool
    21  		want               string
    22  	}{
    23  		{
    24  			name: "single result",
    25  			input: types.Result{
    26  				Target:         "my-file",
    27  				MisconfSummary: &types.MisconfSummary{Successes: 0, Failures: 1, Exceptions: 0},
    28  				Misconfigurations: []types.DetectedMisconfiguration{
    29  					{
    30  						ID:          "AVD-XYZ-0123",
    31  						Title:       "Config file is bad",
    32  						Description: "Your config file is not good.",
    33  						Message:     "Oh no, a bad config.",
    34  						Severity:    "HIGH",
    35  						PrimaryURL:  "https://google.com/search?q=bad%20config",
    36  						Status:      "FAIL",
    37  					},
    38  				},
    39  			},
    40  			includeNonFailures: false,
    41  			want: `
    42  my-file ()
    43  ==========
    44  Tests: 1 (SUCCESSES: 0, FAILURES: 1, EXCEPTIONS: 0)
    45  Failures: 1 (LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
    46  
    47  HIGH: Oh no, a bad config.
    48  ════════════════════════════════════════
    49  Your config file is not good.
    50  
    51  See https://google.com/search?q=bad%20config
    52  ────────────────────────────────────────
    53  
    54  
    55  `,
    56  		},
    57  		{
    58  			name: "single result with code",
    59  			input: types.Result{
    60  				Target:         "my-file",
    61  				MisconfSummary: &types.MisconfSummary{Successes: 0, Failures: 1, Exceptions: 0},
    62  				Misconfigurations: []types.DetectedMisconfiguration{
    63  					{
    64  						ID:          "AVD-XYZ-0123",
    65  						Title:       "Config file is bad",
    66  						Description: "Your config file is not good.",
    67  						Message:     "Oh no, a bad config.",
    68  						Severity:    "HIGH",
    69  						PrimaryURL:  "https://google.com/search?q=bad%20config",
    70  						Status:      "FAIL",
    71  						CauseMetadata: ftypes.CauseMetadata{
    72  							Resource:  "",
    73  							Provider:  "",
    74  							Service:   "",
    75  							StartLine: 0,
    76  							EndLine:   0,
    77  							Code: ftypes.Code{
    78  								Lines: []ftypes.Line{
    79  									{
    80  										Number: 1,
    81  									},
    82  									{
    83  										Number:      2,
    84  										Content:     "bad: true",
    85  										Highlighted: "\x1b[37mbad:\x1b[0m true",
    86  										IsCause:     true,
    87  										FirstCause:  true,
    88  										LastCause:   true,
    89  									},
    90  									{
    91  										Number: 3,
    92  									},
    93  								},
    94  							},
    95  						},
    96  					},
    97  				},
    98  			},
    99  			includeNonFailures: false,
   100  			want: `
   101  my-file ()
   102  ==========
   103  Tests: 1 (SUCCESSES: 0, FAILURES: 1, EXCEPTIONS: 0)
   104  Failures: 1 (LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
   105  
   106  HIGH: Oh no, a bad config.
   107  ════════════════════════════════════════
   108  Your config file is not good.
   109  
   110  See https://google.com/search?q=bad%20config
   111  ────────────────────────────────────────
   112   my-file
   113  ────────────────────────────────────────
   114     1   
   115     2 [ bad: true
   116     3   
   117  ────────────────────────────────────────
   118  
   119  
   120  `,
   121  		},
   122  		{
   123  			name: "multiple results",
   124  			input: types.Result{
   125  				Target:         "my-file",
   126  				MisconfSummary: &types.MisconfSummary{Successes: 1, Failures: 1, Exceptions: 0},
   127  				Misconfigurations: []types.DetectedMisconfiguration{
   128  					{
   129  						ID:          "AVD-XYZ-0123",
   130  						Title:       "Config file is bad",
   131  						Description: "Your config file is not good.",
   132  						Message:     "Oh no, a bad config.",
   133  						Severity:    "HIGH",
   134  						PrimaryURL:  "https://google.com/search?q=bad%20config",
   135  						Status:      "FAIL",
   136  						CauseMetadata: ftypes.CauseMetadata{
   137  							StartLine: 2,
   138  							EndLine:   2,
   139  							Code: ftypes.Code{
   140  								Lines: []ftypes.Line{
   141  									{
   142  										Number: 1,
   143  									},
   144  									{
   145  										Number:      2,
   146  										Content:     "bad: true",
   147  										Highlighted: "\x1b[37mbad:\x1b[0m true",
   148  										IsCause:     true,
   149  										FirstCause:  true,
   150  										LastCause:   true,
   151  									},
   152  									{
   153  										Number: 3,
   154  									},
   155  								},
   156  							},
   157  						},
   158  					},
   159  					{
   160  						ID:          "AVD-XYZ-0456",
   161  						Title:       "Config file is bad again",
   162  						Description: "Your config file is still not good.",
   163  						Message:     "Oh no, a bad config AGAIN.",
   164  						Severity:    "MEDIUM",
   165  						PrimaryURL:  "https://google.com/search?q=bad%20config",
   166  						Status:      "PASS",
   167  					},
   168  				},
   169  			},
   170  			includeNonFailures: true,
   171  			want: `
   172  my-file ()
   173  ==========
   174  Tests: 2 (SUCCESSES: 1, FAILURES: 1, EXCEPTIONS: 0)
   175  Failures: 1 (LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
   176  
   177  FAIL: HIGH: Oh no, a bad config.
   178  ════════════════════════════════════════
   179  Your config file is not good.
   180  
   181  See https://google.com/search?q=bad%20config
   182  ────────────────────────────────────────
   183   my-file:2
   184  ────────────────────────────────────────
   185     1   
   186     2 [ bad: true
   187     3   
   188  ────────────────────────────────────────
   189  
   190  
   191  PASS: MEDIUM: Oh no, a bad config AGAIN.
   192  ════════════════════════════════════════
   193  Your config file is still not good.
   194  
   195  See https://google.com/search?q=bad%20config
   196  ────────────────────────────────────────
   197  
   198  
   199  `,
   200  		},
   201  		{
   202  			name: "resource name in report",
   203  			input: types.Result{
   204  				Target: "terraform-aws-modules/security-group/aws/main.tf",
   205  				Class:  types.ClassConfig,
   206  				Type:   "terraform",
   207  				MisconfSummary: &types.MisconfSummary{
   208  					Successes:  5,
   209  					Failures:   1,
   210  					Exceptions: 0,
   211  				},
   212  				Misconfigurations: []types.DetectedMisconfiguration{
   213  					{
   214  						Type:        "Terraform Security Check",
   215  						ID:          "AVD-AWS-0107",
   216  						AVDID:       "AVS-AWS-0107",
   217  						Title:       "An ingress security group rule allows traffic from /0",
   218  						Description: "Opening up ports to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that explicitly require it where possible.",
   219  						Message:     "Security group rule allows ingress from public internet.",
   220  						Query:       "data..",
   221  						Resolution:  "Set a more restrictive cidr range",
   222  						Severity:    "CRITICAL",
   223  						PrimaryURL:  "https://avd.aquasec.com/misconfig/avd-aws-0107",
   224  						References: []string{
   225  							"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html",
   226  							"https://avd.aquasec.com/misconfig/avd-aws-0107",
   227  						},
   228  						Status: "FAIL",
   229  						CauseMetadata: ftypes.CauseMetadata{
   230  							Resource:  "module.aws-security-groups[\"db1\"]",
   231  							Provider:  "AWS",
   232  							Service:   "ec2",
   233  							StartLine: 197,
   234  							EndLine:   204,
   235  							Code: ftypes.Code{
   236  								Lines: []ftypes.Line{
   237  									{
   238  										Number:  191,
   239  										Content: "resource \"aws_security_group_rule\" \"ingress_with_cidr_blocks\" {",
   240  										IsCause: false,
   241  									},
   242  									{
   243  										Number:    192,
   244  										Truncated: true,
   245  									},
   246  									{
   247  										Number:    197,
   248  										Truncated: true,
   249  									},
   250  									{
   251  										Number:  198,
   252  										Content: "    \",\",",
   253  										IsCause: true,
   254  									},
   255  									{
   256  										Number:  199,
   257  										Content: "    lookup(",
   258  										IsCause: true,
   259  									},
   260  									{
   261  										Number:  200,
   262  										Content: "      var.ingress_with_cidr_blocks[count.index],",
   263  										IsCause: true,
   264  									},
   265  									{
   266  										Number:  201,
   267  										Content: "      \"cidr_blocks\",",
   268  										IsCause: true,
   269  									},
   270  									{
   271  										Number:  202,
   272  										Content: "      join(\",\", var.ingress_cidr_blocks),",
   273  										IsCause: true,
   274  									},
   275  									{
   276  										Number:    203,
   277  										Content:   "    ),",
   278  										IsCause:   true,
   279  										LastCause: true,
   280  									},
   281  									{
   282  										Number:    204,
   283  										Truncated: true,
   284  									},
   285  								},
   286  							},
   287  							Occurrences: []ftypes.Occurrence{
   288  								{
   289  									Resource: "aws_security_group_rule.ingress_with_cidr_blocks[0]",
   290  									Filename: "terraform-aws-modules/security-group/aws/main.tf",
   291  									Location: ftypes.Location{
   292  										StartLine: 191,
   293  										EndLine:   227,
   294  									},
   295  								},
   296  								{
   297  									Resource: "module.aws-security-groups[\"db1\"]",
   298  									Filename: "sg.tf",
   299  									Location: ftypes.Location{
   300  										StartLine: 1,
   301  										EndLine:   13,
   302  									},
   303  								},
   304  							},
   305  						},
   306  					},
   307  				},
   308  			},
   309  			want: `
   310  terraform-aws-modules/security-group/aws/main.tf (terraform)
   311  ============================================================
   312  Tests: 6 (SUCCESSES: 5, FAILURES: 1, EXCEPTIONS: 0)
   313  Failures: 1 (LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
   314  
   315  CRITICAL: Security group rule allows ingress from public internet.
   316  ════════════════════════════════════════
   317  Opening up ports to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that explicitly require it where possible.
   318  
   319  See https://avd.aquasec.com/misconfig/avd-aws-0107
   320  ────────────────────────────────────────
   321   terraform-aws-modules/security-group/aws/main.tf:197-204
   322     via terraform-aws-modules/security-group/aws/main.tf:191-227 (aws_security_group_rule.ingress_with_cidr_blocks[0])
   323      via sg.tf:1-13 (module.aws-security-groups["db1"])
   324  ────────────────────────────────────────
   325   191   resource "aws_security_group_rule" "ingress_with_cidr_blocks" {
   326   ...   
   327   ...   
   328   198 │     ",",
   329   199 │     lookup(
   330   200 │       var.ingress_with_cidr_blocks[count.index],
   331   201 │       "cidr_blocks",
   332   202 │       join(",", var.ingress_cidr_blocks),
   333   203 └     ),
   334   ...   
   335  ────────────────────────────────────────
   336  
   337  
   338  `,
   339  		},
   340  	}
   341  
   342  	for _, test := range tests {
   343  		t.Run(test.name, func(t *testing.T) {
   344  			severities := []dbTypes.Severity{dbTypes.SeverityLow, dbTypes.SeverityMedium, dbTypes.SeverityHigh,
   345  				dbTypes.SeverityCritical}
   346  			renderer := table.NewMisconfigRenderer(test.input, severities, false, test.includeNonFailures, false)
   347  			assert.Equal(t, test.want, strings.ReplaceAll(renderer.Render(), "\r\n", "\n"))
   348  		})
   349  	}
   350  }