github.com/wolfi-dev/wolfictl@v0.16.11/pkg/advisory/question/questions.go (about)

     1  package question
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/wolfi-dev/wolfictl/pkg/advisory"
     7  	v2 "github.com/wolfi-dev/wolfictl/pkg/configs/advisory/v2"
     8  	"github.com/wolfi-dev/wolfictl/pkg/question"
     9  )
    10  
    11  var (
    12  	IsFalsePositive = question.Question[advisory.Request]{
    13  		Text: "Is this a false positive?",
    14  		Answer: question.MultipleChoice[advisory.Request]{
    15  			{
    16  				Text:   "No",
    17  				Choose: question.NewChooseFunc(&IsPackageSupported),
    18  			},
    19  			{
    20  				Text: "Yes",
    21  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
    22  					e := v2.Event{
    23  						Timestamp: v2.Now(),
    24  						Type:      v2.EventTypeFalsePositiveDetermination,
    25  					}
    26  
    27  					req.Event = e
    28  					return req, &WhyFalsePositive, nil
    29  				},
    30  			},
    31  			{
    32  				Text:   "I'm not sure",
    33  				Choose: question.NewChooseFunc(&IsFalsePositiveAskForHelp),
    34  			},
    35  		},
    36  	}
    37  
    38  	IsFalsePositiveAskForHelp = question.NewTerminatingMessage[advisory.Request](
    39  		fmt.Sprintf("No problem! Please ask for help %s! You can say something like 'I could use help determining if this is a false positive...'", destinationForHelp),
    40  	)
    41  
    42  	WhyFalsePositive = question.Question[advisory.Request]{
    43  		Text: "Why is this a false positive?",
    44  		Answer: question.MultipleChoice[advisory.Request]{
    45  			{
    46  				Text: "The maintainers don't agree that this is a security problem.",
    47  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
    48  					req.Event.Data = v2.FalsePositiveDetermination{
    49  						Type: v2.FPTypeVulnerabilityRecordAnalysisContested,
    50  					}
    51  					return req, &ReferenceForMaintainersDisagree, nil
    52  				},
    53  			},
    54  			{
    55  				Text: "This is specific to another distro, not ours.",
    56  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
    57  					req.Event.Data = v2.FalsePositiveDetermination{
    58  						Type: v2.FPTypeComponentVulnerabilityMismatch,
    59  					}
    60  					return req, &WhichOtherDistro, nil
    61  				},
    62  			},
    63  			{
    64  				Text: "This seems to refer to a past version of the software, not the version we have now.",
    65  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
    66  					req.Event.Data = v2.FalsePositiveDetermination{
    67  						Type: v2.FPTypeVulnerableCodeVersionNotUsed,
    68  					}
    69  					return req, &ProvidePastVersionReferencedByVulnerability, nil
    70  				},
    71  			},
    72  			{
    73  				// TODO: Make this show only for Go vulnerability matches?
    74  				// TODO: Automate this scan?
    75  				Text: "Govulncheck shows that the affected code is not present in our build.",
    76  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
    77  					req.Event.Data = v2.FalsePositiveDetermination{
    78  						Type: v2.FPTypeVulnerableCodeNotIncludedInPackage,
    79  						Note: "Govulncheck shows that the affected code is not present in our build.",
    80  					}
    81  					return req, nil, nil
    82  				},
    83  			},
    84  		},
    85  	}
    86  
    87  	ProvidePastVersionReferencedByVulnerability = question.Question[advisory.Request]{
    88  		Text: "Please provide the past version of the software referenced by the vulnerability to show that this doesn't affect our version.",
    89  		Answer: question.AcceptText[advisory.Request](func(req advisory.Request, text string) (advisory.Request, *question.Question[advisory.Request], error) {
    90  			req.Event.Data = v2.FalsePositiveDetermination{
    91  				Type: v2.FPTypeVulnerableCodeVersionNotUsed,
    92  				Note: fmt.Sprintf("This seems to refer to a past version of the software, not the version we have now. Past version: %s", text),
    93  			}
    94  
    95  			return req, nil, nil
    96  		}),
    97  	}
    98  
    99  	ReferenceForMaintainersDisagree = question.Question[advisory.Request]{
   100  		Text: "Please provide a web URL to a source that shows the maintainers don't agree that this is a security problem.",
   101  		Answer: question.AcceptText[advisory.Request](func(req advisory.Request, text string) (advisory.Request, *question.Question[advisory.Request], error) {
   102  			req.Event.Data = v2.FalsePositiveDetermination{
   103  				Type: v2.FPTypeVulnerabilityRecordAnalysisContested,
   104  				Note: fmt.Sprintf("The maintainers don't agree that this is a security problem. Source: %s", text),
   105  			}
   106  
   107  			return req, nil, nil
   108  		}),
   109  	}
   110  
   111  	WhichOtherDistro = question.Question[advisory.Request]{
   112  		Text: "Which other distro is this specific to?",
   113  		Answer: question.MultipleChoice[advisory.Request]{
   114  			{
   115  				Text: "Alpine", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   116  					req.Event.Data = v2.FalsePositiveDetermination{
   117  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   118  						Note: "This vulnerability is specific to Alpine.",
   119  					}
   120  					return req, nil, nil
   121  				}),
   122  			},
   123  			{
   124  				Text: "Amazon", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   125  					req.Event.Data = v2.FalsePositiveDetermination{
   126  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   127  						Note: "This vulnerability is specific to Amazon.",
   128  					}
   129  					return req, nil, nil
   130  				}),
   131  			},
   132  			{
   133  				Text: "Debian", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   134  					req.Event.Data = v2.FalsePositiveDetermination{
   135  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   136  						Note: "This vulnerability is specific to Debian.",
   137  					}
   138  					return req, nil, nil
   139  				}),
   140  			},
   141  			{
   142  				Text: "Fedora", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   143  					req.Event.Data = v2.FalsePositiveDetermination{
   144  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   145  						Note: "This vulnerability is specific to Fedora.",
   146  					}
   147  					return req, nil, nil
   148  				}),
   149  			},
   150  			{
   151  				Text: "RHEL", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   152  					req.Event.Data = v2.FalsePositiveDetermination{
   153  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   154  						Note: "This vulnerability is specific to RHEL.",
   155  					}
   156  					return req, nil, nil
   157  				}),
   158  			},
   159  			{
   160  				Text: "SUSE/SLES", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   161  					req.Event.Data = v2.FalsePositiveDetermination{
   162  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   163  						Note: "This vulnerability is specific to SUSE/SLES.",
   164  					}
   165  					return req, nil, nil
   166  				}),
   167  			},
   168  			{
   169  				Text: "Ubuntu", Choose: question.ChooseFunc[advisory.Request](func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   170  					req.Event.Data = v2.FalsePositiveDetermination{
   171  						Type: v2.FPTypeComponentVulnerabilityMismatch,
   172  						Note: "This vulnerability is specific to Ubuntu.",
   173  					}
   174  					return req, nil, nil
   175  				}),
   176  			},
   177  		},
   178  	}
   179  
   180  	IsPackageSupported = question.Question[advisory.Request]{
   181  		Text: "Is this package still supported upstream?", // TODO: automate this lookup!
   182  		Answer: question.MultipleChoice[advisory.Request]{
   183  			{
   184  				Text: "Yes",
   185  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   186  					return req, &HasFixBeenAttempted, nil
   187  				},
   188  			},
   189  			{
   190  				Text: "No",
   191  				Choose: func(req advisory.Request) (advisory.Request, *question.Question[advisory.Request], error) {
   192  					return req, &ReferenceForNotSupportedUpstream, nil
   193  				},
   194  			},
   195  			{
   196  				Text:   "I'm not sure",
   197  				Choose: question.NewChooseFunc[advisory.Request](&IsPackageSupportedAskForHelp),
   198  			},
   199  		},
   200  	}
   201  
   202  	IsPackageSupportedAskForHelp = question.NewTerminatingMessage[advisory.Request](
   203  		fmt.Sprintf("No problem! Please ask for help %s! You can say something like 'I could use help determining if this package is still supported upstream...'", destinationForHelp),
   204  	)
   205  
   206  	ReferenceForNotSupportedUpstream = question.Question[advisory.Request]{
   207  		Text: "Please provide a web URL to a source that shows the package is no longer supported upstream.",
   208  		Answer: question.AcceptText[advisory.Request](func(req advisory.Request, text string) (advisory.Request, *question.Question[advisory.Request], error) {
   209  			req.Event.Type = v2.EventTypeFixNotPlanned
   210  			req.Event.Data = v2.FixNotPlanned{
   211  				Note: fmt.Sprintf("Package is no longer supported upstream. Source: %s", text),
   212  			}
   213  
   214  			return req, nil, nil
   215  		}),
   216  	}
   217  
   218  	HasFixBeenAttempted = question.Question[advisory.Request]{
   219  		Text: "Have you tried to fix the vulnerability yet?",
   220  		Answer: question.MultipleChoice[advisory.Request]{
   221  			{
   222  				Text: "Yes, but I need help.", Choose: question.NewChooseFunc[advisory.Request](&HasFixBeenAttemptedAskForHelp),
   223  			},
   224  			{
   225  				Text: "Yes, and I'm surprised this is still showing up in a scan.", Choose: question.NewChooseFunc[advisory.Request](&HasFixBeenAttemptedAskForHelp),
   226  			},
   227  			{
   228  				Text: "No, I need help.", Choose: question.NewChooseFunc[advisory.Request](&HasFixBeenAttemptedAskForHelp),
   229  			},
   230  			{
   231  				Text: "No, I'll try to fix this and then come back to the advisory data entry later.", Choose: question.NewChooseFunc[advisory.Request](&MovingOnForNow),
   232  			},
   233  		},
   234  	}
   235  
   236  	HasFixBeenAttemptedAskForHelp = question.NewTerminatingMessage[advisory.Request](
   237  		fmt.Sprintf("No problem! Please ask for help %s! You can say something like 'I could use help fixing this vulnerability...'", destinationForHelp),
   238  	)
   239  
   240  	MovingOnForNow = question.NewTerminatingMessage[advisory.Request](
   241  		"Sounds good! Let's move on for now. If you need help later, just ask!",
   242  	)
   243  )
   244  
   245  const (
   246  	destinationForHelp = "in the #cve Slack channel"
   247  )