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 )