1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.maven;
19
20 import com.github.packageurl.MalformedPackageURLException;
21 import com.github.packageurl.PackageURL.StandardTypes;
22 import com.github.packageurl.PackageURL;
23 import io.github.jeremylong.jcs3.slf4j.Slf4jAdapter;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
26
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.artifact.DefaultArtifact;
30 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
31 import org.apache.maven.artifact.versioning.ArtifactVersion;
32 import org.apache.maven.doxia.sink.Sink;
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.model.License;
35 import org.apache.maven.plugin.AbstractMojo;
36 import org.apache.maven.plugin.MojoExecutionException;
37 import org.apache.maven.plugin.MojoFailureException;
38 import org.apache.maven.plugins.annotations.Component;
39 import org.apache.maven.plugins.annotations.Parameter;
40 import org.apache.maven.project.DefaultProjectBuildingRequest;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.maven.project.ProjectBuildingRequest;
43 import org.apache.maven.reporting.MavenReport;
44 import org.apache.maven.reporting.MavenReportException;
45 import org.apache.maven.settings.Proxy;
46 import org.apache.maven.settings.Server;
47 import org.apache.maven.settings.building.SettingsProblem;
48 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
49 import org.apache.maven.settings.crypto.SettingsDecrypter;
50 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
51 import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
52 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
53 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
54 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
55 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
56 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
57 import org.eclipse.aether.artifact.ArtifactType;
58 import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
59 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
60 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
61 import org.apache.maven.shared.dependency.graph.DependencyNode;
62 import org.apache.maven.shared.dependency.graph.filter.ArtifactDependencyNodeFilter;
63 import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
64 import org.apache.maven.shared.model.fileset.FileSet;
65 import org.apache.maven.shared.model.fileset.util.FileSetManager;
66 import org.owasp.dependencycheck.Engine;
67 import org.owasp.dependencycheck.analyzer.JarAnalyzer;
68 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
69 import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
70 import org.owasp.dependencycheck.dependency.Confidence;
71 import org.owasp.dependencycheck.dependency.Dependency;
72 import org.owasp.dependencycheck.dependency.EvidenceType;
73 import org.owasp.dependencycheck.dependency.Vulnerability;
74 import org.owasp.dependencycheck.exception.DependencyNotFoundException;
75 import org.owasp.dependencycheck.exception.ExceptionCollection;
76 import org.owasp.dependencycheck.exception.InitializationException;
77 import org.owasp.dependencycheck.exception.ReportException;
78 import org.owasp.dependencycheck.utils.Checksum;
79 import org.owasp.dependencycheck.utils.Filter;
80 import org.owasp.dependencycheck.utils.Downloader;
81 import org.owasp.dependencycheck.utils.InvalidSettingException;
82 import org.owasp.dependencycheck.utils.Settings;
83
84 import java.io.File;
85 import java.io.IOException;
86 import java.io.InputStream;
87 import java.util.ArrayList;
88 import java.util.Arrays;
89 import java.util.Collections;
90 import java.util.HashSet;
91 import java.util.List;
92 import java.util.Locale;
93 import java.util.Map;
94 import java.util.Objects;
95 import java.util.Optional;
96 import java.util.Set;
97 import org.apache.maven.artifact.repository.ArtifactRepository;
98
99 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
100 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
101 import org.apache.maven.artifact.versioning.Restriction;
102 import org.apache.maven.artifact.versioning.VersionRange;
103
104 import org.owasp.dependencycheck.agent.DependencyCheckScanAgent;
105 import org.owasp.dependencycheck.dependency.naming.GenericIdentifier;
106 import org.owasp.dependencycheck.dependency.naming.Identifier;
107 import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
108 import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
109 import org.apache.maven.shared.dependency.graph.traversal.FilteringDependencyNodeVisitor;
110 import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
111 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
112 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
113 import org.owasp.dependencycheck.reporting.ReportGenerator;
114 import org.owasp.dependencycheck.utils.SeverityUtil;
115 import org.owasp.dependencycheck.xml.pom.Model;
116 import org.owasp.dependencycheck.xml.pom.PomUtils;
117
118
119
120
121
122 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport {
123
124
125
126
127
128 private static final String PROPERTIES_FILE = "mojo.properties";
129
130
131
132 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
133
134
135
136 private static final String INCLUDE_ALL = "**/*";
137
138
139
140 public static final String PROTOCOL_HTTPS = "https";
141
142
143
144 public static final String PROTOCOL_HTTP = "http";
145
146
147
148 private boolean generatingSite = false;
149
150
151
152 private Settings settings = null;
153
154
155
156 private final List<File> scannedFiles = new ArrayList<>();
157
158
159
160
161
162 @SuppressWarnings("CanBeFinal")
163 @Parameter(property = "failOnError", defaultValue = "true", required = true)
164 private boolean failOnError;
165
166
167
168
169 @SuppressWarnings("CanBeFinal")
170 @Parameter(property = "project", required = true, readonly = true)
171 private MavenProject project;
172
173
174
175 @SuppressWarnings("CanBeFinal")
176 @Parameter(readonly = true, required = true, property = "reactorProjects")
177 private List<MavenProject> reactorProjects;
178
179
180
181
182
183 @SuppressWarnings("CanBeFinal")
184 @Component
185 private ArtifactResolver artifactResolver;
186
187
188
189
190
191
192
193 @SuppressWarnings("CanBeFinal")
194 @Component
195 private DependencyResolver dependencyResolver;
196
197
198
199
200 @SuppressWarnings("CanBeFinal")
201 @Parameter(defaultValue = "${session}", readonly = true, required = true)
202 private MavenSession session;
203
204
205
206
207 @Component
208 private DependencyGraphBuilder dependencyGraphBuilder;
209
210
211
212
213 @SuppressWarnings("CanBeFinal")
214 @Parameter(defaultValue = "${project.build.directory}", required = true, property = "odc.outputDirectory")
215 private File outputDirectory;
216
217
218
219
220
221 @Parameter(property = "project.reporting.outputDirectory", readonly = true)
222 private File reportOutputDirectory;
223
224
225
226
227
228 @SuppressWarnings("CanBeFinal")
229 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
230 private float failBuildOnCVSS = 11f;
231
232
233
234
235
236 @SuppressWarnings("CanBeFinal")
237 @Parameter(property = "junitFailOnCVSS", defaultValue = "0", required = true)
238 private float junitFailOnCVSS = 0;
239
240
241
242
243
244
245 @SuppressWarnings("CanBeFinal")
246 @Parameter(property = "failBuildOnAnyVulnerability", defaultValue = "false", required = true)
247 @Deprecated
248 private boolean failBuildOnAnyVulnerability = false;
249
250
251
252
253 @SuppressWarnings("CanBeFinal")
254 @Parameter(property = "autoUpdate")
255 private Boolean autoUpdate;
256
257
258
259 @SuppressWarnings("CanBeFinal")
260 @Parameter(property = "enableExperimental")
261 private Boolean enableExperimental;
262
263
264
265 @SuppressWarnings("CanBeFinal")
266 @Parameter(property = "enableRetired")
267 private Boolean enableRetired;
268
269
270
271 @SuppressWarnings("CanBeFinal")
272 @Parameter(property = "golangDepEnabled")
273 private Boolean golangDepEnabled;
274
275
276
277
278 @SuppressWarnings("CanBeFinal")
279 @Parameter(property = "golangModEnabled")
280 private Boolean golangModEnabled;
281
282
283
284 @SuppressWarnings("CanBeFinal")
285 @Parameter(property = "pathToGo")
286 private String pathToGo;
287
288
289
290
291 @SuppressWarnings("CanBeFinal")
292 @Parameter(property = "pathToYarn")
293 private String pathToYarn;
294
295
296
297 @SuppressWarnings("CanBeFinal")
298 @Parameter(property = "pathToPnpm")
299 private String pathToPnpm;
300
301
302
303
304 @Parameter(property = "dependency-check.virtualSnapshotsFromReactor", defaultValue = "true")
305 private Boolean virtualSnapshotsFromReactor;
306
307
308
309
310
311 @SuppressWarnings("CanBeFinal")
312 @Parameter(property = "format", defaultValue = "HTML", required = true)
313 private String format = "HTML";
314
315
316
317
318
319 @Parameter(property = "prettyPrint")
320 private Boolean prettyPrint;
321
322
323
324
325
326 @Parameter(property = "formats", required = true)
327 private String[] formats;
328
329
330
331 @SuppressWarnings("CanBeFinal")
332 @Parameter(property = "mavenSettings", defaultValue = "${settings}")
333 private org.apache.maven.settings.Settings mavenSettings;
334
335
336
337
338 @SuppressWarnings("CanBeFinal")
339 @Parameter(property = "mavenSettingsProxyId")
340 private String mavenSettingsProxyId;
341
342
343
344
345 @SuppressWarnings("CanBeFinal")
346 @Parameter(property = "connectionTimeout")
347 private String connectionTimeout;
348
349
350
351 @SuppressWarnings("CanBeFinal")
352 @Parameter(property = "readTimeout")
353 private String readTimeout;
354
355
356
357
358 @SuppressWarnings("CanBeFinal")
359 @Parameter(property = "versionCheckEnabled", defaultValue = "true")
360 private boolean versionCheckEnabled;
361
362
363
364
365
366
367 @SuppressWarnings("CanBeFinal")
368 @Parameter(property = "suppressionFiles")
369 private String[] suppressionFiles;
370
371
372
373
374
375
376 @SuppressWarnings("CanBeFinal")
377 @Parameter(property = "suppressionFile")
378 private String suppressionFile;
379
380
381
382 @Parameter(property = "suppressionFileUser")
383 private String suppressionFileUser;
384
385
386
387 @Parameter(property = "suppressionFilePassword")
388 private String suppressionFilePassword;
389
390
391
392 @Parameter(property = "suppressionFileBearerToken")
393 private String suppressionFileBearerToken;
394
395
396
397
398 @SuppressWarnings("CanBeFinal")
399 @Parameter(property = "suppressionFileServerId")
400 private String suppressionFileServerId;
401
402
403
404 @SuppressWarnings("CanBeFinal")
405 @Parameter(property = "hintsFile")
406 private String hintsFile;
407
408
409
410
411 @SuppressWarnings("CanBeFinal")
412 @Parameter(property = "showSummary", defaultValue = "true")
413 private boolean showSummary = true;
414
415
416
417
418 @SuppressWarnings("CanBeFinal")
419 @Parameter(property = "jarAnalyzerEnabled")
420 private Boolean jarAnalyzerEnabled;
421
422
423
424
425 @SuppressWarnings("CanBeFinal")
426 @Parameter(property = "dartAnalyzerEnabled")
427 private Boolean dartAnalyzerEnabled;
428
429
430
431
432 @SuppressWarnings("CanBeFinal")
433 @Parameter(property = "archiveAnalyzerEnabled")
434 private Boolean archiveAnalyzerEnabled;
435
436
437
438 @SuppressWarnings("CanBeFinal")
439 @Parameter(property = "knownExploitedEnabled")
440 private Boolean knownExploitedEnabled;
441
442
443
444 @SuppressWarnings("CanBeFinal")
445 @Parameter(property = "knownExploitedUrl")
446 private String knownExploitedUrl;
447
448
449
450
451
452 @SuppressWarnings("CanBeFinal")
453 @Parameter(property = "knownExploitedServerId")
454 private String knownExploitedServerId;
455
456
457
458 @SuppressWarnings("CanBeFinal")
459 @Parameter(property = "knownExploitedUser")
460 private String knownExploitedUser;
461
462
463
464 @SuppressWarnings("CanBeFinal")
465 @Parameter(property = "knownExploitedPassword")
466 private String knownExploitedPassword;
467
468
469
470 @SuppressWarnings("CanBeFinal")
471 @Parameter(property = "knownExploitedBearerToken")
472 private String knownExploitedBearerToken;
473
474
475
476 @SuppressWarnings("CanBeFinal")
477 @Parameter(property = "pyDistributionAnalyzerEnabled")
478 private Boolean pyDistributionAnalyzerEnabled;
479
480
481
482 @Parameter(property = "pyPackageAnalyzerEnabled")
483 private Boolean pyPackageAnalyzerEnabled;
484
485
486
487 @SuppressWarnings("CanBeFinal")
488 @Parameter(property = "rubygemsAnalyzerEnabled")
489 private Boolean rubygemsAnalyzerEnabled;
490
491
492
493 @SuppressWarnings("CanBeFinal")
494 @Parameter(property = "opensslAnalyzerEnabled")
495 private Boolean opensslAnalyzerEnabled;
496
497
498
499 @SuppressWarnings("CanBeFinal")
500 @Parameter(property = "cmakeAnalyzerEnabled")
501 private Boolean cmakeAnalyzerEnabled;
502
503
504
505 @SuppressWarnings("CanBeFinal")
506 @Parameter(property = "autoconfAnalyzerEnabled")
507 private Boolean autoconfAnalyzerEnabled;
508
509
510
511 @SuppressWarnings("CanBeFinal")
512 @Parameter(property = "mavenInstallAnalyzerEnabled")
513 private Boolean mavenInstallAnalyzerEnabled;
514
515
516
517 @SuppressWarnings("CanBeFinal")
518 @Parameter(property = "pipAnalyzerEnabled")
519 private Boolean pipAnalyzerEnabled;
520
521
522
523 @SuppressWarnings("CanBeFinal")
524 @Parameter(property = "pipfileAnalyzerEnabled")
525 private Boolean pipfileAnalyzerEnabled;
526
527
528
529 @SuppressWarnings("CanBeFinal")
530 @Parameter(property = "poetryAnalyzerEnabled")
531 private Boolean poetryAnalyzerEnabled;
532
533
534
535 @Parameter(property = "composerAnalyzerEnabled")
536 private Boolean composerAnalyzerEnabled;
537
538
539
540 @Parameter(property = "composerAnalyzerSkipDev")
541 private boolean composerAnalyzerSkipDev;
542
543
544
545 @Parameter(property = "cpanfileAnalyzerEnabled")
546 private Boolean cpanfileAnalyzerEnabled;
547
548
549
550 @SuppressWarnings("CanBeFinal")
551 @Parameter(property = "nodeAnalyzerEnabled")
552 private Boolean nodeAnalyzerEnabled;
553
554
555
556 @SuppressWarnings("CanBeFinal")
557 @Parameter(property = "nodeAuditAnalyzerEnabled")
558 private Boolean nodeAuditAnalyzerEnabled;
559
560
561
562
563 @SuppressWarnings("CanBeFinal")
564 @Parameter(property = "nodeAuditAnalyzerUrl")
565 private String nodeAuditAnalyzerUrl;
566
567
568
569
570 @SuppressWarnings("CanBeFinal")
571 @Parameter(property = "yarnAuditAnalyzerEnabled")
572 private Boolean yarnAuditAnalyzerEnabled;
573
574
575
576
577 @SuppressWarnings("CanBeFinal")
578 @Parameter(property = "pnpmAuditAnalyzerEnabled")
579 private Boolean pnpmAuditAnalyzerEnabled;
580
581
582
583
584 @SuppressWarnings("CanBeFinal")
585 @Parameter(property = "nodeAuditAnalyzerUseCache")
586 private Boolean nodeAuditAnalyzerUseCache;
587
588
589
590 @SuppressWarnings("CanBeFinal")
591 @Parameter(property = "nodeAuditSkipDevDependencies")
592 private Boolean nodeAuditSkipDevDependencies;
593
594
595
596 @SuppressWarnings("CanBeFinal")
597 @Parameter(property = "nodePackageSkipDevDependencies")
598 private Boolean nodePackageSkipDevDependencies;
599
600
601
602 @SuppressWarnings("CanBeFinal")
603 @Parameter(property = "retireJsAnalyzerEnabled")
604 private Boolean retireJsAnalyzerEnabled;
605
606
607
608 @SuppressWarnings("CanBeFinal")
609 @Parameter(property = "retireJsUrl")
610 private String retireJsUrl;
611
612
613
614 @Parameter(property = "retireJsUser")
615 private String retireJsUser;
616
617
618
619 @Parameter(property = "retireJsPassword")
620 private String retireJsPassword;
621
622
623
624 @Parameter(property = "retireJsBearerToken")
625 private String retireJsBearerToken;
626
627
628
629
630 @SuppressWarnings("CanBeFinal")
631 @Parameter(property = "retireJsUrlServerId")
632 private String retireJsUrlServerId;
633
634
635
636
637 @SuppressWarnings("CanBeFinal")
638 @Parameter(property = "retireJsForceUpdate")
639 private Boolean retireJsForceUpdate;
640
641
642
643 @Parameter(property = "assemblyAnalyzerEnabled")
644 private Boolean assemblyAnalyzerEnabled;
645
646
647
648 @Parameter(property = "msbuildAnalyzerEnabled")
649 private Boolean msbuildAnalyzerEnabled;
650
651
652
653 @SuppressWarnings("CanBeFinal")
654 @Parameter(property = "nuspecAnalyzerEnabled")
655 private Boolean nuspecAnalyzerEnabled;
656
657
658
659
660 @SuppressWarnings("CanBeFinal")
661 @Parameter(property = "nugetconfAnalyzerEnabled")
662 private Boolean nugetconfAnalyzerEnabled;
663
664
665
666
667 @SuppressWarnings("CanBeFinal")
668 @Parameter(property = "libmanAnalyzerEnabled")
669 private Boolean libmanAnalyzerEnabled;
670
671
672
673
674 @SuppressWarnings("CanBeFinal")
675 @Parameter(property = "centralAnalyzerEnabled")
676 private Boolean centralAnalyzerEnabled;
677
678
679
680
681 @SuppressWarnings("CanBeFinal")
682 @Parameter(property = "centralAnalyzerUseCache")
683 private Boolean centralAnalyzerUseCache;
684
685
686
687
688 @SuppressWarnings("CanBeFinal")
689 @Parameter(property = "artifactoryAnalyzerEnabled")
690 private Boolean artifactoryAnalyzerEnabled;
691
692
693
694
695 @SuppressWarnings("CanBeFinal")
696 @Parameter(property = "artifactoryAnalyzerServerId")
697 private String artifactoryAnalyzerServerId;
698
699
700
701
702 @SuppressWarnings("CanBeFinal")
703 @Parameter(property = "artifactoryAnalyzerUsername")
704 private String artifactoryAnalyzerUsername;
705
706
707
708 @SuppressWarnings("CanBeFinal")
709 @Parameter(property = "artifactoryAnalyzerApiToken")
710 private String artifactoryAnalyzerApiToken;
711
712
713
714 @SuppressWarnings("CanBeFinal")
715 @Parameter(property = "artifactoryAnalyzerBearerToken")
716 private String artifactoryAnalyzerBearerToken;
717
718
719
720 @SuppressWarnings("CanBeFinal")
721 @Parameter(property = "artifactoryAnalyzerUrl")
722 private String artifactoryAnalyzerUrl;
723
724
725
726 @SuppressWarnings("CanBeFinal")
727 @Parameter(property = "artifactoryAnalyzerUseProxy")
728 private Boolean artifactoryAnalyzerUseProxy;
729
730
731
732 @SuppressWarnings("CanBeFinal")
733 @Parameter(property = "artifactoryAnalyzerParallelAnalysis", defaultValue = "true")
734 private Boolean artifactoryAnalyzerParallelAnalysis;
735
736
737
738 @SuppressWarnings("CanBeFinal")
739 @Parameter(property = "failBuildOnUnusedSuppressionRule", defaultValue = "false")
740 private Boolean failBuildOnUnusedSuppressionRule;
741
742
743
744 @SuppressWarnings("CanBeFinal")
745 @Parameter(property = "nexusAnalyzerEnabled")
746 private Boolean nexusAnalyzerEnabled;
747
748
749
750
751 @SuppressWarnings("CanBeFinal")
752 @Parameter(property = "ossindexAnalyzerEnabled")
753 private Boolean ossindexAnalyzerEnabled;
754
755
756
757 @SuppressWarnings("CanBeFinal")
758 @Parameter(property = "ossindexAnalyzerUseCache")
759 private Boolean ossindexAnalyzerUseCache;
760
761
762
763 @SuppressWarnings("CanBeFinal")
764 @Parameter(property = "ossindexAnalyzerUrl")
765 private String ossindexAnalyzerUrl;
766
767
768
769
770
771
772 @SuppressWarnings("CanBeFinal")
773 @Parameter(property = "ossIndexServerId")
774 private String ossIndexServerId;
775
776
777
778
779
780
781
782 @SuppressWarnings("CanBeFinal")
783 @Parameter(property = "ossIndexUsername")
784 private String ossIndexUsername;
785
786
787
788
789
790
791
792 @SuppressWarnings("CanBeFinal")
793 @Parameter(property = "ossIndexPassword")
794 private String ossIndexPassword;
795
796
797
798
799
800 @SuppressWarnings("CanBeFinal")
801 @Parameter(property = "ossIndexWarnOnlyOnRemoteErrors")
802 private Boolean ossIndexWarnOnlyOnRemoteErrors;
803
804
805
806
807 @Parameter(property = "mixAuditAnalyzerEnabled")
808 private Boolean mixAuditAnalyzerEnabled;
809
810
811
812
813 @SuppressWarnings("CanBeFinal")
814 @Parameter(property = "mixAuditPath")
815 private String mixAuditPath;
816
817
818
819
820 @Parameter(property = "bundleAuditAnalyzerEnabled")
821 private Boolean bundleAuditAnalyzerEnabled;
822
823
824
825
826 @SuppressWarnings("CanBeFinal")
827 @Parameter(property = "bundleAuditPath")
828 private String bundleAuditPath;
829
830
831
832
833
834 @SuppressWarnings("CanBeFinal")
835 @Parameter(property = "bundleAuditWorkingDirectory")
836 private String bundleAuditWorkingDirectory;
837
838
839
840
841 @SuppressWarnings("CanBeFinal")
842 @Parameter(property = "cocoapodsAnalyzerEnabled")
843 private Boolean cocoapodsAnalyzerEnabled;
844
845
846
847
848 @SuppressWarnings("CanBeFinal")
849 @Parameter(property = "carthageAnalyzerEnabled")
850 private Boolean carthageAnalyzerEnabled;
851
852
853
854
855 @SuppressWarnings("CanBeFinal")
856 @Parameter(property = "swiftPackageManagerAnalyzerEnabled")
857 private Boolean swiftPackageManagerAnalyzerEnabled;
858
859
860
861 @SuppressWarnings("CanBeFinal")
862 @Parameter(property = "swiftPackageResolvedAnalyzerEnabled")
863 private Boolean swiftPackageResolvedAnalyzerEnabled;
864
865
866
867
868 @SuppressWarnings("CanBeFinal")
869 @Parameter(property = "nexusUrl")
870 private String nexusUrl;
871
872
873
874
875
876
877 @SuppressWarnings("CanBeFinal")
878 @Parameter(property = "nexusServerId")
879 private String nexusServerId;
880
881
882
883 @SuppressWarnings("CanBeFinal")
884 @Parameter(property = "nexusUsesProxy")
885 private Boolean nexusUsesProxy;
886
887
888
889 @SuppressWarnings("CanBeFinal")
890 @Parameter(property = "connectionString")
891 private String connectionString;
892
893
894
895
896 @SuppressWarnings("CanBeFinal")
897 @Parameter(property = "databaseDriverName")
898 private String databaseDriverName;
899
900
901
902 @SuppressWarnings("CanBeFinal")
903 @Parameter(property = "databaseDriverPath")
904 private String databaseDriverPath;
905
906
907
908 @SuppressWarnings("CanBeFinal")
909 @Parameter(defaultValue = "${settings}", readonly = true, required = true)
910 private org.apache.maven.settings.Settings settingsXml;
911
912
913
914
915 @Component
916 private SettingsDecrypter settingsDecrypter;
917
918
919
920
921 @Parameter(property = "databaseUser")
922 private String databaseUser;
923
924
925
926 @Parameter(property = "databasePassword")
927 private String databasePassword;
928
929
930
931
932 @SuppressWarnings("CanBeFinal")
933 @Parameter(property = "zipExtensions")
934 private String zipExtensions;
935
936
937
938 @SuppressWarnings("CanBeFinal")
939 @Parameter(property = "dependency-check.skip", defaultValue = "false")
940 private boolean skip = false;
941
942
943
944 @SuppressWarnings("CanBeFinal")
945 @Parameter(property = "skipTestScope", defaultValue = "true")
946 private boolean skipTestScope = true;
947
948
949
950 @SuppressWarnings("CanBeFinal")
951 @Parameter(property = "skipRuntimeScope", defaultValue = "false")
952 private boolean skipRuntimeScope = false;
953
954
955
956 @SuppressWarnings("CanBeFinal")
957 @Parameter(property = "skipProvidedScope", defaultValue = "false")
958 private boolean skipProvidedScope = false;
959
960
961
962
963 @SuppressWarnings("CanBeFinal")
964 @Parameter(property = "skipSystemScope", defaultValue = "false")
965 private boolean skipSystemScope = false;
966
967
968
969
970 @SuppressWarnings("CanBeFinal")
971 @Parameter(property = "skipDependencyManagement", defaultValue = "true")
972 private boolean skipDependencyManagement = true;
973
974
975
976
977
978
979 @SuppressWarnings("CanBeFinal")
980 @Parameter(property = "skipArtifactType")
981 private String skipArtifactType;
982
983
984
985
986 @SuppressWarnings("CanBeFinal")
987 @Parameter(property = "dataDirectory")
988 private String dataDirectory;
989
990
991
992
993 @SuppressWarnings("CanBeFinal")
994 @Parameter(property = "dbFilename")
995 private String dbFilename;
996
997
998
999
1000
1001 @SuppressWarnings("CanBeFinal")
1002 @Parameter(property = "serverId")
1003 private String serverId;
1004
1005
1006
1007
1008
1009 @SuppressWarnings("CanBeFinal")
1010 @Parameter(property = "nvdApiKey")
1011 private String nvdApiKey;
1012
1013
1014
1015 @SuppressWarnings("CanBeFinal")
1016 @Parameter(property = "nvdMaxRetryCount")
1017 private Integer nvdMaxRetryCount;
1018
1019
1020
1021
1022
1023
1024 @SuppressWarnings("CanBeFinal")
1025 @Parameter(property = "nvdApiServerId")
1026 private String nvdApiServerId;
1027
1028
1029
1030
1031
1032 @SuppressWarnings("CanBeFinal")
1033 @Parameter(property = "nvdApiKeyEnvironmentVariable")
1034 private String nvdApiKeyEnvironmentVariable;
1035
1036
1037
1038 @SuppressWarnings("CanBeFinal")
1039 @Parameter(property = "nvdValidForHours")
1040 private Integer nvdValidForHours;
1041
1042
1043
1044 @SuppressWarnings("CanBeFinal")
1045 @Parameter(property = "nvdApiEndpoint")
1046 private String nvdApiEndpoint;
1047
1048
1049
1050 @SuppressWarnings("CanBeFinal")
1051 @Parameter(property = "nvdDatafeedUrl")
1052 private String nvdDatafeedUrl;
1053
1054
1055
1056
1057
1058
1059 @SuppressWarnings("CanBeFinal")
1060 @Parameter(property = "nvdDatafeedServerId")
1061 private String nvdDatafeedServerId;
1062
1063
1064
1065 @SuppressWarnings("CanBeFinal")
1066 @Parameter(property = "nvdUser")
1067 private String nvdUser;
1068
1069
1070
1071 @SuppressWarnings("CanBeFinal")
1072 @Parameter(property = "nvdPassword")
1073 private String nvdPassword;
1074
1075
1076
1077 @SuppressWarnings("CanBeFinal")
1078 @Parameter(property = "nvdBearerToken")
1079 private String nvdBearerToken;
1080
1081
1082
1083 @SuppressWarnings("CanBeFinal")
1084 @Parameter(property = "nvdApiDelay")
1085 private Integer nvdApiDelay;
1086
1087
1088
1089
1090 @SuppressWarnings("CanBeFinal")
1091 @Parameter(property = "nvdApiResultsPerPage")
1092 private Integer nvdApiResultsPerPage;
1093
1094
1095
1096
1097 @SuppressWarnings("CanBeFinal")
1098 @Parameter(property = "pathToCore")
1099 private String pathToCore;
1100
1101
1102
1103 @SuppressWarnings("CanBeFinal")
1104 @Parameter(property = "hostedSuppressionsUrl")
1105 private String hostedSuppressionsUrl;
1106
1107
1108
1109 @SuppressWarnings("CanBeFinal")
1110 @Parameter(property = "hostedSuppressionsUser")
1111 private String hostedSuppressionsUser;
1112
1113
1114
1115 @SuppressWarnings("CanBeFinal")
1116 @Parameter(property = "hostedSuppressionsPassword")
1117 private String hostedSuppressionsPassword;
1118
1119
1120
1121 @SuppressWarnings("CanBeFinal")
1122 @Parameter(property = "hostedSuppressionsBearerToken")
1123 private String hostedSuppressionsBearerToken;
1124
1125
1126
1127
1128 @SuppressWarnings("CanBeFinal")
1129 @Parameter(property = "hostedSuppressionsServerId")
1130 private String hostedSuppressionsServerId;
1131
1132
1133
1134
1135 @SuppressWarnings("CanBeFinal")
1136 @Parameter(property = "hostedSuppressionsForceUpdate")
1137 private Boolean hostedSuppressionsForceUpdate;
1138
1139
1140
1141 @SuppressWarnings("CanBeFinal")
1142 @Parameter(property = "hostedSuppressionsEnabled")
1143 private Boolean hostedSuppressionsEnabled;
1144
1145
1146
1147
1148 @SuppressWarnings("CanBeFinal")
1149 @Parameter(property = "hostedSuppressionsValidForHours")
1150 private Integer hostedSuppressionsValidForHours;
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167 @SuppressWarnings("CanBeFinal")
1168 @Parameter(property = "retirejs")
1169 private Retirejs retirejs;
1170
1171
1172
1173
1174
1175 @Parameter(property = "odc.excludes")
1176 private List<String> excludes;
1177
1178
1179
1180
1181 private Filter<String> artifactScopeExcluded;
1182
1183
1184
1185
1186 private Filter<String> artifactTypeExcluded;
1187
1188
1189
1190
1191
1192
1193
1194
1195 @Parameter
1196 private List<FileSet> scanSet;
1197
1198
1199
1200
1201
1202 @Parameter(property = "scanDirectory")
1203 private List<String> scanDirectory;
1204
1205
1206
1207
1208 @SuppressWarnings("CanBeFinal")
1209 @Parameter(property = "odc.plugins.scan", defaultValue = "false", required = false)
1210 private boolean scanPlugins = false;
1211
1212
1213
1214 @SuppressWarnings("CanBeFinal")
1215 @Parameter(property = "odc.dependencies.scan", defaultValue = "true", required = false)
1216 private boolean scanDependencies = true;
1217
1218
1219
1220 @Parameter
1221 private ProxyConfig proxy;
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233 private static boolean artifactsMatch(org.apache.maven.model.Dependency d, Artifact a) {
1234 return isEqualOrNull(a.getArtifactId(), d.getArtifactId())
1235 && isEqualOrNull(a.getGroupId(), d.getGroupId())
1236 && isEqualOrNull(a.getVersion(), d.getVersion());
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248 private static boolean isEqualOrNull(String left, String right) {
1249 return (left != null && left.equals(right)) || (left == null && right == null);
1250 }
1251
1252
1253
1254
1255
1256
1257
1258
1259 @Override
1260 public void execute() throws MojoExecutionException, MojoFailureException {
1261 generatingSite = false;
1262 final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1263 if (shouldSkip) {
1264 getLog().info("Skipping " + getName(Locale.US));
1265 } else {
1266 project.setContextValue("dependency-check-output-dir", this.outputDirectory);
1267 runCheck();
1268 }
1269 }
1270
1271
1272
1273
1274
1275
1276 protected boolean isGeneratingSite() {
1277 return generatingSite;
1278 }
1279
1280
1281
1282
1283
1284
1285 protected String getConnectionString() {
1286 return connectionString;
1287 }
1288
1289
1290
1291
1292
1293
1294 protected boolean isFailOnError() {
1295 return failOnError;
1296 }
1297
1298
1299
1300
1301
1302
1303
1304
1305 public void generate(Sink sink, Locale locale) throws MavenReportException {
1306 final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1307 if (shouldSkip) {
1308 getLog().info("Skipping report generation " + getName(Locale.US));
1309 return;
1310 }
1311
1312 generatingSite = true;
1313 project.setContextValue("dependency-check-output-dir", getReportOutputDirectory());
1314 try {
1315 runCheck();
1316 } catch (MojoExecutionException ex) {
1317 throw new MavenReportException(ex.getMessage(), ex);
1318 } catch (MojoFailureException ex) {
1319 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
1320 }
1321 }
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 protected File getCorrectOutputDirectory() throws MojoExecutionException {
1332 return getCorrectOutputDirectory(this.project);
1333 }
1334
1335
1336
1337
1338
1339
1340
1341
1342 protected File getCorrectOutputDirectory(MavenProject current) {
1343 final Object obj = current.getContextValue("dependency-check-output-dir");
1344 if (obj != null && obj instanceof File) {
1345 return (File) obj;
1346 }
1347
1348 File target = new File(current.getBuild().getDirectory());
1349 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
1350 target = target.getParentFile();
1351 }
1352 return target;
1353 }
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364 protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) {
1365 return scanArtifacts(project, engine, false);
1366 }
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) {
1379 try {
1380 final List<String> filterItems = Collections.singletonList(String.format("%s:%s", project.getGroupId(), project.getArtifactId()));
1381 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1382
1383
1384 final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null);
1385
1386 final CollectingRootDependencyGraphVisitor collectorVisitor = new CollectingRootDependencyGraphVisitor();
1387
1388
1389 final DependencyNodeVisitor transitiveFilterVisitor = new FilteringDependencyTransitiveNodeVisitor(collectorVisitor,
1390 new ArtifactDependencyNodeFilter(new PatternExcludesArtifactFilter(getExcludes())));
1391
1392
1393 final DependencyNodeVisitor artifactFilter = new FilteringDependencyNodeVisitor(transitiveFilterVisitor,
1394 new ArtifactDependencyNodeFilter(new ExcludesArtifactFilter(filterItems)));
1395 dn.accept(artifactFilter);
1396
1397
1398 final Map<DependencyNode, List<DependencyNode>> nodes = collectorVisitor.getNodes();
1399
1400 return collectDependencies(engine, project, nodes, buildingRequest, aggregate);
1401 } catch (DependencyGraphBuilderException ex) {
1402 final String msg = String.format("Unable to build dependency graph on project %s", project.getName());
1403 getLog().debug(msg, ex);
1404 return new ExceptionCollection(ex);
1405 }
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419 protected ExceptionCollection scanPlugins(MavenProject project, Engine engine, ExceptionCollection exCollection) {
1420 ExceptionCollection exCol = exCollection;
1421 final Set<Artifact> plugins = new HashSet<>();
1422 final Set<Artifact> buildPlugins = getProject().getPluginArtifacts();
1423 final Set<Artifact> reportPlugins = getProject().getReportArtifacts();
1424 final Set<Artifact> extensions = getProject().getExtensionArtifacts();
1425
1426 plugins.addAll(buildPlugins);
1427 plugins.addAll(reportPlugins);
1428 plugins.addAll(extensions);
1429
1430 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getPluginArtifactRepositories());
1431 for (Artifact plugin : plugins) {
1432 try {
1433 final Artifact resolved = artifactResolver.resolveArtifact(buildingRequest, plugin).getArtifact();
1434
1435 exCol = addPluginToDependencies(project, engine, resolved, "pom.xml (plugins)", exCol);
1436
1437 final DefaultDependableCoordinate pluginCoordinate = new DefaultDependableCoordinate();
1438 pluginCoordinate.setGroupId(resolved.getGroupId());
1439 pluginCoordinate.setArtifactId(resolved.getArtifactId());
1440 pluginCoordinate.setVersion(resolved.getVersion());
1441
1442 final String parent = buildReference(resolved.getGroupId(), resolved.getArtifactId(), resolved.getVersion());
1443 for (Artifact artifact : resolveArtifactDependencies(pluginCoordinate, project)) {
1444 exCol = addPluginToDependencies(project, engine, artifact, parent, exCol);
1445 }
1446 } catch (ArtifactResolverException ex) {
1447 throw new RuntimeException(ex);
1448 } catch (IllegalArgumentException ex) {
1449 throw new RuntimeException(ex);
1450 } catch (DependencyResolverException ex) {
1451 throw new RuntimeException(ex);
1452 }
1453 }
1454
1455 return null;
1456
1457 }
1458
1459 private ExceptionCollection addPluginToDependencies(MavenProject project, Engine engine, Artifact artifact, String parent, ExceptionCollection exCollection) {
1460 ExceptionCollection exCol = exCollection;
1461 final String groupId = artifact.getGroupId();
1462 final String artifactId = artifact.getArtifactId();
1463 final String version = artifact.getVersion();
1464 final File artifactFile = artifact.getFile();
1465 if (artifactFile.isFile()) {
1466 final List<ArtifactVersion> availableVersions = artifact.getAvailableVersions();
1467
1468 final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
1469 project.getName() + " (plugins)");
1470 if (deps != null) {
1471 Dependency d = null;
1472 if (deps.size() == 1) {
1473 d = deps.get(0);
1474 } else {
1475 for (Dependency possible : deps) {
1476 if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
1477 d = possible;
1478 break;
1479 }
1480 }
1481 for (Dependency dep : deps) {
1482 if (d != null && d != dep) {
1483 final String includedBy = buildReference(groupId, artifactId, version);
1484 dep.addIncludedBy(includedBy, "plugins");
1485 }
1486 }
1487 }
1488 if (d != null) {
1489 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
1490 d.addAsEvidence("pom", ma, Confidence.HIGHEST);
1491 if (parent != null) {
1492 d.addIncludedBy(parent, "plugins");
1493 } else {
1494 final String includedby = buildReference(
1495 project.getGroupId(),
1496 project.getArtifactId(),
1497 project.getVersion());
1498 d.addIncludedBy(includedby, "plugins");
1499 }
1500 if (availableVersions != null) {
1501 for (ArtifactVersion av : availableVersions) {
1502 d.addAvailableVersion(av.toString());
1503 }
1504 }
1505 }
1506 }
1507 } else {
1508 if (exCol == null) {
1509 exCol = new ExceptionCollection();
1510 }
1511 exCol.addException(new DependencyNotFoundException("Unable to resolve plugin: "
1512 + groupId + ":" + artifactId + ":" + version));
1513 }
1514
1515 return exCol;
1516 }
1517
1518 private String buildReference(final String groupId, final String artifactId, final String version) {
1519 String includedBy;
1520 try {
1521 final PackageURL purl = new PackageURL("maven", groupId, artifactId, version, null, null);
1522 includedBy = purl.toString();
1523 } catch (MalformedPackageURLException ex) {
1524 getLog().warn("Unable to generate build reference for " + groupId
1525 + ":" + artifactId + ":" + version, ex);
1526 includedBy = groupId + ":" + artifactId + ":" + version;
1527 }
1528 return includedBy;
1529 }
1530
1531 protected Set<Artifact> resolveArtifactDependencies(final DependableCoordinate artifact, MavenProject project)
1532 throws DependencyResolverException {
1533 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1534
1535 final Iterable<ArtifactResult> artifactResults = dependencyResolver.resolveDependencies(buildingRequest, artifact, null);
1536
1537 final Set<Artifact> artifacts = new HashSet<>();
1538
1539 for (ArtifactResult artifactResult : artifactResults) {
1540 artifacts.add(artifactResult.getArtifact());
1541 }
1542
1543 return artifacts;
1544
1545 }
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558 private DependencyNode toDependencyNode(List<DependencyNode> nodes, ProjectBuildingRequest buildingRequest,
1559 DependencyNode parent, org.apache.maven.model.Dependency dependency) throws ArtifactResolverException {
1560
1561 final DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
1562
1563 coordinate.setGroupId(dependency.getGroupId());
1564 coordinate.setArtifactId(dependency.getArtifactId());
1565 String version = null;
1566 final VersionRange vr;
1567 try {
1568 vr = VersionRange.createFromVersionSpec(dependency.getVersion());
1569 } catch (InvalidVersionSpecificationException ex) {
1570 throw new ArtifactResolverException("Invalid version specification: "
1571 + dependency.getGroupId() + ":"
1572 + dependency.getArtifactId() + ":"
1573 + dependency.getVersion(), ex);
1574 }
1575 if (vr.hasRestrictions()) {
1576 version = findVersion(nodes, dependency.getGroupId(), dependency.getArtifactId());
1577 if (version == null) {
1578
1579
1580 if (vr.getRecommendedVersion() != null) {
1581 version = vr.getRecommendedVersion().toString();
1582 } else if (vr.hasRestrictions()) {
1583 for (Restriction restriction : vr.getRestrictions()) {
1584 if (restriction.getLowerBound() != null) {
1585 version = restriction.getLowerBound().toString();
1586 }
1587 if (restriction.getUpperBound() != null) {
1588 version = restriction.getUpperBound().toString();
1589 }
1590 }
1591 } else {
1592 version = vr.toString();
1593 }
1594 }
1595 }
1596 if (version == null) {
1597 version = dependency.getVersion();
1598 }
1599 coordinate.setVersion(version);
1600
1601 final ArtifactType type = session.getRepositorySession().getArtifactTypeRegistry().get(dependency.getType());
1602 coordinate.setExtension(type.getExtension());
1603 coordinate.setClassifier((null == dependency.getClassifier() || dependency.getClassifier().isEmpty())
1604 ? type.getClassifier() : dependency.getClassifier());
1605 final Artifact artifact = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
1606 artifact.setScope(dependency.getScope());
1607 return new DefaultDependencyNode(parent, artifact, dependency.getVersion(), dependency.getScope(), null);
1608 }
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620 private String findVersion(List<DependencyNode> nodes, String groupId, String artifactId) {
1621 final Optional<DependencyNode> f = nodes.stream().filter(p
1622 -> groupId.equals(p.getArtifact().getGroupId())
1623 && artifactId.equals(p.getArtifact().getArtifactId())).findFirst();
1624 if (f.isPresent()) {
1625 return f.get().getArtifact().getVersion();
1626 }
1627 return null;
1628 }
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641 private ExceptionCollection collectDependencyManagementDependencies(Engine engine, ProjectBuildingRequest buildingRequest,
1642 MavenProject project, List<DependencyNode> nodes, boolean aggregate) {
1643 if (skipDependencyManagement || project.getDependencyManagement() == null) {
1644 return null;
1645 }
1646
1647 ExceptionCollection exCol = null;
1648 for (org.apache.maven.model.Dependency dependency : project.getDependencyManagement().getDependencies()) {
1649 try {
1650 nodes.add(toDependencyNode(nodes, buildingRequest, null, dependency));
1651 } catch (ArtifactResolverException ex) {
1652 getLog().debug(String.format("Aggregate : %s", aggregate));
1653 boolean addException = true;
1654
1655 if (!aggregate) {
1656
1657 } else if (addReactorDependency(engine,
1658 new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(),
1659 dependency.getVersion(), dependency.getScope(), dependency.getType(), dependency.getClassifier(),
1660 new DefaultArtifactHandler()), project)) {
1661 addException = false;
1662 }
1663
1664 if (addException) {
1665 if (exCol == null) {
1666 exCol = new ExceptionCollection();
1667 }
1668 exCol.addException(ex);
1669 }
1670 }
1671 }
1672 return exCol;
1673 }
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689 private ExceptionCollection collectMavenDependencies(Engine engine, MavenProject project,
1690 Map<DependencyNode, List<DependencyNode>> nodeMap, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1691
1692 final List<ArtifactResult> allResolvedDeps = new ArrayList<>();
1693
1694
1695 final List<DependencyNode> dmNodes = new ArrayList<>();
1696 ExceptionCollection exCol = collectDependencyManagementDependencies(engine, buildingRequest, project, dmNodes, aggregate);
1697 for (DependencyNode dependencyNode : dmNodes) {
1698 exCol = scanDependencyNode(dependencyNode, null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1699 }
1700
1701
1702 for (Map.Entry<DependencyNode, List<DependencyNode>> entry : nodeMap.entrySet()) {
1703 exCol = scanDependencyNode(entry.getKey(), null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1704 for (DependencyNode dependencyNode : entry.getValue()) {
1705 exCol = scanDependencyNode(dependencyNode, entry.getKey(), engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1706 }
1707 }
1708 return exCol;
1709 }
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723 private Artifact findInAllDeps(final List<ArtifactResult> allDeps, final Artifact unresolvedArtifact,
1724 final MavenProject project)
1725 throws DependencyNotFoundException {
1726 Artifact result = null;
1727 for (final ArtifactResult res : allDeps) {
1728 if (sameArtifact(res, unresolvedArtifact)) {
1729 result = res.getArtifact();
1730 break;
1731 }
1732 }
1733 if (result == null) {
1734 throw new DependencyNotFoundException(String.format("Expected dependency not found in resolved artifacts for "
1735 + "dependency %s of project-artifact %s", unresolvedArtifact, project.getArtifactId()));
1736 }
1737 return result;
1738 }
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749 private boolean sameArtifact(final ArtifactResult res, final Artifact unresolvedArtifact) {
1750 if (res == null || res.getArtifact() == null || unresolvedArtifact == null) {
1751 return false;
1752 }
1753 boolean result = Objects.equals(res.getArtifact().getGroupId(), unresolvedArtifact.getGroupId());
1754 result &= Objects.equals(res.getArtifact().getArtifactId(), unresolvedArtifact.getArtifactId());
1755
1756 if ("RELEASE".equals(unresolvedArtifact.getBaseVersion())) {
1757 result &= !res.getArtifact().isSnapshot();
1758 } else if (!"LATEST".equals(unresolvedArtifact.getBaseVersion())) {
1759 result &= Objects.equals(res.getArtifact().getBaseVersion(), unresolvedArtifact.getBaseVersion());
1760 }
1761 result &= Objects.equals(res.getArtifact().getClassifier(), unresolvedArtifact.getClassifier());
1762 result &= Objects.equals(res.getArtifact().getType(), unresolvedArtifact.getType());
1763 return result;
1764 }
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775 protected String createProjectReferenceName(MavenProject project, DependencyNode dependencyNode) {
1776 return project.getName() + ":" + dependencyNode.getArtifact().getScope();
1777 }
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792 private ExceptionCollection collectDependencies(Engine engine, MavenProject project,
1793 Map<DependencyNode, List<DependencyNode>> nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1794
1795 ExceptionCollection exCol;
1796 exCol = collectMavenDependencies(engine, project, nodes, buildingRequest, aggregate);
1797
1798 final List<FileSet> projectScan;
1799
1800 if (scanDirectory != null && !scanDirectory.isEmpty()) {
1801 if (scanSet == null) {
1802 scanSet = new ArrayList<>();
1803 }
1804 scanDirectory.forEach(d -> {
1805 final FileSet fs = new FileSet();
1806 fs.setDirectory(d);
1807 fs.addInclude(INCLUDE_ALL);
1808 scanSet.add(fs);
1809 });
1810 }
1811
1812 if (scanSet == null || scanSet.isEmpty()) {
1813
1814 final FileSet resourcesSet = new FileSet();
1815 final FileSet filtersSet = new FileSet();
1816 final FileSet webappSet = new FileSet();
1817 final FileSet mixedLangSet = new FileSet();
1818 try {
1819 resourcesSet.setDirectory(new File(project.getBasedir(), "src/main/resources").getCanonicalPath());
1820 resourcesSet.addInclude(INCLUDE_ALL);
1821 filtersSet.setDirectory(new File(project.getBasedir(), "src/main/filters").getCanonicalPath());
1822 filtersSet.addInclude(INCLUDE_ALL);
1823 webappSet.setDirectory(new File(project.getBasedir(), "src/main/webapp").getCanonicalPath());
1824 webappSet.addInclude(INCLUDE_ALL);
1825 mixedLangSet.setDirectory(project.getBasedir().getCanonicalPath());
1826 mixedLangSet.addInclude("package.json");
1827 mixedLangSet.addInclude("package-lock.json");
1828 mixedLangSet.addInclude("npm-shrinkwrap.json");
1829 mixedLangSet.addInclude("Gopkg.lock");
1830 mixedLangSet.addInclude("go.mod");
1831 mixedLangSet.addInclude("yarn.lock");
1832 mixedLangSet.addInclude("pnpm-lock.yaml");
1833 mixedLangSet.addExclude("/node_modules/");
1834 } catch (IOException ex) {
1835 if (exCol == null) {
1836 exCol = new ExceptionCollection();
1837 }
1838 exCol.addException(ex);
1839 }
1840 projectScan = new ArrayList<>();
1841 projectScan.add(resourcesSet);
1842 projectScan.add(filtersSet);
1843 projectScan.add(webappSet);
1844 projectScan.add(mixedLangSet);
1845
1846 } else if (aggregate) {
1847 projectScan = new ArrayList<>();
1848 for (FileSet copyFrom : scanSet) {
1849
1850 final FileSet fsCopy = new FileSet();
1851 final File f = new File(copyFrom.getDirectory());
1852 if (f.isAbsolute()) {
1853 fsCopy.setDirectory(copyFrom.getDirectory());
1854 } else {
1855 try {
1856 fsCopy.setDirectory(new File(project.getBasedir(), copyFrom.getDirectory()).getCanonicalPath());
1857 } catch (IOException ex) {
1858 if (exCol == null) {
1859 exCol = new ExceptionCollection();
1860 }
1861 exCol.addException(ex);
1862 fsCopy.setDirectory(copyFrom.getDirectory());
1863 }
1864 }
1865 fsCopy.setDirectoryMode(copyFrom.getDirectoryMode());
1866 fsCopy.setExcludes(copyFrom.getExcludes());
1867 fsCopy.setFileMode(copyFrom.getFileMode());
1868 fsCopy.setFollowSymlinks(copyFrom.isFollowSymlinks());
1869 fsCopy.setIncludes(copyFrom.getIncludes());
1870 fsCopy.setLineEnding(copyFrom.getLineEnding());
1871 fsCopy.setMapper(copyFrom.getMapper());
1872 fsCopy.setModelEncoding(copyFrom.getModelEncoding());
1873 fsCopy.setOutputDirectory(copyFrom.getOutputDirectory());
1874 fsCopy.setUseDefaultExcludes(copyFrom.isUseDefaultExcludes());
1875 projectScan.add(fsCopy);
1876 }
1877 } else {
1878 projectScan = scanSet;
1879 }
1880
1881
1882 final FileSetManager fileSetManager = new FileSetManager();
1883 for (FileSet fileSet : projectScan) {
1884 getLog().debug("Scanning fileSet: " + fileSet.getDirectory());
1885 final String[] includedFiles = fileSetManager.getIncludedFiles(fileSet);
1886 for (String include : includedFiles) {
1887 final File includeFile = new File(fileSet.getDirectory(), include).getAbsoluteFile();
1888 if (includeFile.exists()) {
1889 engine.scan(includeFile, project.getName());
1890 }
1891 }
1892 }
1893 return exCol;
1894 }
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907 private boolean addReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
1908 return addVirtualDependencyFromReactor(engine, artifact, depender, "Unable to resolve %s as it has not been built yet "
1909 + "- creating a virtual dependency instead.");
1910 }
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926 private boolean addVirtualDependencyFromReactor(Engine engine, Artifact artifact,
1927 final MavenProject depender, String infoLogTemplate) {
1928
1929 getLog().debug(String.format("Checking the reactor projects (%d) for %s:%s:%s",
1930 reactorProjects.size(),
1931 artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()));
1932
1933 for (MavenProject prj : reactorProjects) {
1934
1935 getLog().debug(String.format("Comparing %s:%s:%s to %s:%s:%s",
1936 artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(),
1937 prj.getGroupId(), prj.getArtifactId(), prj.getVersion()));
1938
1939 if (prj.getArtifactId().equals(artifact.getArtifactId())
1940 && prj.getGroupId().equals(artifact.getGroupId())
1941 && prj.getVersion().equals(artifact.getBaseVersion())) {
1942
1943 final String displayName = String.format("%s:%s:%s",
1944 prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1945 getLog().info(String.format(infoLogTemplate,
1946 displayName));
1947 final Dependency d = newDependency(prj);
1948 final String key = String.format("%s:%s:%s", prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1949 d.setSha1sum(Checksum.getSHA1Checksum(key));
1950 d.setSha256sum(Checksum.getSHA256Checksum(key));
1951 d.setMd5sum(Checksum.getMD5Checksum(key));
1952 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1953 d.setDisplayFileName(displayName);
1954 d.addProjectReference(depender.getName());
1955 final String includedby = buildReference(
1956 depender.getGroupId(),
1957 depender.getArtifactId(),
1958 depender.getVersion());
1959 d.addIncludedBy(includedby);
1960 d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", prj.getArtifactId(), Confidence.HIGHEST);
1961 d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", prj.getArtifactId(), Confidence.LOW);
1962
1963 d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST);
1964 d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW);
1965 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1966 Identifier id;
1967 try {
1968 id = new PurlIdentifier(StandardTypes.MAVEN, artifact.getGroupId(),
1969 artifact.getArtifactId(), artifact.getVersion(), Confidence.HIGHEST);
1970 } catch (MalformedPackageURLException ex) {
1971 getLog().debug("Unable to create PackageURL object:" + key);
1972 id = new GenericIdentifier("maven:" + key, Confidence.HIGHEST);
1973 }
1974 d.addSoftwareIdentifier(id);
1975
1976 d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId()));
1977 d.setVersion(prj.getVersion());
1978 d.setPackagePath(displayName);
1979 if (prj.getDescription() != null) {
1980 JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description");
1981 }
1982 for (License l : prj.getLicenses()) {
1983 final StringBuilder license = new StringBuilder();
1984 if (l.getName() != null) {
1985 license.append(l.getName());
1986 }
1987 if (l.getUrl() != null) {
1988 license.append(" ").append(l.getUrl());
1989 }
1990 if (d.getLicense() == null) {
1991 d.setLicense(license.toString());
1992 } else if (!d.getLicense().contains(license)) {
1993 d.setLicense(String.format("%s%n%s", d.getLicense(), license));
1994 }
1995 }
1996 engine.addDependency(d);
1997 return true;
1998 }
1999 }
2000 return false;
2001 }
2002
2003 Dependency newDependency(MavenProject prj) {
2004 final File pom = new File(prj.getBasedir(), "pom.xml");
2005
2006 if (pom.isFile()) {
2007 getLog().debug("Adding virtual dependency from pom.xml");
2008 return new Dependency(pom, true);
2009 } else if (prj.getFile().isFile()) {
2010 getLog().debug("Adding virtual dependency from file");
2011 return new Dependency(prj.getFile(), true);
2012 } else {
2013 return new Dependency(true);
2014 }
2015 }
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028 private boolean addSnapshotReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
2029 if (!artifact.isSnapshot()) {
2030 return false;
2031 }
2032 return addVirtualDependencyFromReactor(engine, artifact, depender, "Found snapshot reactor project in aggregate for %s - "
2033 + "creating a virtual dependency as the snapshot found in the repository may contain outdated dependencies.");
2034 }
2035
2036
2037
2038
2039
2040
2041
2042
2043 public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest(MavenProject project, List<ArtifactRepository> repos) {
2044 final ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
2045 buildingRequest.setRemoteRepositories(repos);
2046 buildingRequest.setProject(project);
2047 return buildingRequest;
2048 }
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058 protected void runCheck() throws MojoExecutionException, MojoFailureException {
2059 muteNoisyLoggers();
2060 try (Engine engine = initializeEngine()) {
2061 ExceptionCollection exCol = null;
2062 if (scanDependencies) {
2063 exCol = scanDependencies(engine);
2064 }
2065 if (scanPlugins) {
2066 exCol = scanPlugins(engine, exCol);
2067 }
2068 try {
2069 engine.analyzeDependencies();
2070 } catch (ExceptionCollection ex) {
2071 exCol = handleAnalysisExceptions(exCol, ex);
2072 }
2073 if (exCol == null || !exCol.isFatal()) {
2074
2075 File outputDir = getCorrectOutputDirectory(this.getProject());
2076 if (outputDir == null) {
2077
2078
2079 outputDir = new File(this.getProject().getBuild().getDirectory());
2080 }
2081 try {
2082 final MavenProject p = this.getProject();
2083 for (String f : getFormats()) {
2084 engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), outputDir, f, exCol);
2085 }
2086 } catch (ReportException ex) {
2087 if (exCol == null) {
2088 exCol = new ExceptionCollection(ex);
2089 } else {
2090 exCol.addException(ex);
2091 }
2092 if (this.isFailOnError()) {
2093 throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2094 } else {
2095 getLog().debug("Error writing the report", ex);
2096 }
2097 }
2098 showSummary(this.getProject(), engine.getDependencies());
2099 checkForFailure(engine.getDependencies());
2100 if (exCol != null && this.isFailOnError()) {
2101 throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2102 }
2103 }
2104 } catch (DatabaseException ex) {
2105 if (getLog().isDebugEnabled()) {
2106 getLog().debug("Database connection error", ex);
2107 }
2108 final String msg = "An exception occurred connecting to the local database. Please see the log file for more details.";
2109 if (this.isFailOnError()) {
2110 throw new MojoExecutionException(msg, ex);
2111 }
2112 getLog().error(msg, ex);
2113 } finally {
2114 getSettings().cleanup();
2115 }
2116 }
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128 private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException {
2129 ExceptionCollection returnEx = currentEx;
2130 if (returnEx == null) {
2131 returnEx = newEx;
2132 } else {
2133 returnEx.getExceptions().addAll(newEx.getExceptions());
2134 if (newEx.isFatal()) {
2135 returnEx.setFatal(true);
2136 }
2137 }
2138 if (returnEx.isFatal()) {
2139 final String msg = String.format("Fatal exception(s) analyzing %s", getProject().getName());
2140 if (this.isFailOnError()) {
2141 throw new MojoExecutionException(msg, returnEx);
2142 }
2143 getLog().error(msg);
2144 if (getLog().isDebugEnabled()) {
2145 getLog().debug(returnEx);
2146 }
2147 } else {
2148 final String msg = String.format("Exception(s) analyzing %s", getProject().getName());
2149 if (getLog().isDebugEnabled()) {
2150 getLog().debug(msg, returnEx);
2151 }
2152 }
2153 return returnEx;
2154 }
2155
2156
2157
2158
2159
2160
2161
2162
2163 protected abstract ExceptionCollection scanDependencies(Engine engine) throws MojoExecutionException;
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174 protected abstract ExceptionCollection scanPlugins(Engine engine, ExceptionCollection exCol) throws MojoExecutionException;
2175
2176
2177
2178
2179
2180
2181 @Override
2182 public File getReportOutputDirectory() {
2183 return reportOutputDirectory;
2184 }
2185
2186
2187
2188
2189
2190
2191 @Override
2192 public void setReportOutputDirectory(File directory) {
2193 reportOutputDirectory = directory;
2194 }
2195
2196
2197
2198
2199
2200
2201 public File getOutputDirectory() {
2202 return outputDirectory;
2203 }
2204
2205
2206
2207
2208
2209
2210
2211 @Override
2212 public final boolean isExternalReport() {
2213 return true;
2214 }
2215
2216
2217
2218
2219
2220
2221 @Override
2222 public String getOutputName() {
2223 final Set<String> selectedFormats = getFormats();
2224 if (selectedFormats.contains("HTML") || selectedFormats.contains("ALL") || selectedFormats.size() > 1) {
2225 return "dependency-check-report";
2226 } else if (selectedFormats.contains("JENKINS")) {
2227 return "dependency-check-jenkins.html";
2228 } else if (selectedFormats.contains("XML")) {
2229 return "dependency-check-report.xml";
2230 } else if (selectedFormats.contains("JUNIT")) {
2231 return "dependency-check-junit.xml";
2232 } else if (selectedFormats.contains("JSON")) {
2233 return "dependency-check-report.json";
2234 } else if (selectedFormats.contains("SARIF")) {
2235 return "dependency-check-report.sarif";
2236 } else if (selectedFormats.contains("CSV")) {
2237 return "dependency-check-report.csv";
2238 } else {
2239 getLog().warn("Unknown report format used during site generation.");
2240 return "dependency-check-report";
2241 }
2242 }
2243
2244
2245
2246
2247
2248
2249 @Override
2250 public String getCategoryName() {
2251 return MavenReport.CATEGORY_PROJECT_REPORTS;
2252 }
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265 protected Engine initializeEngine() throws DatabaseException, MojoExecutionException, MojoFailureException {
2266 populateSettings();
2267 try {
2268 Downloader.getInstance().configure(settings);
2269 } catch (InvalidSettingException e) {
2270 if (this.failOnError) {
2271 throw new MojoFailureException(e.getMessage(), e);
2272 } else {
2273 throw new MojoExecutionException(e.getMessage(), e);
2274 }
2275 }
2276 return new Engine(settings);
2277 }
2278
2279
2280
2281
2282
2283
2284
2285 protected void populateSettings() throws MojoFailureException, MojoExecutionException {
2286 settings = new Settings();
2287 InputStream mojoProperties = null;
2288 try {
2289 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
2290 settings.mergeProperties(mojoProperties);
2291 } catch (IOException ex) {
2292 getLog().warn("Unable to load the dependency-check maven mojo.properties file.");
2293 if (getLog().isDebugEnabled()) {
2294 getLog().debug("", ex);
2295 }
2296 } finally {
2297 if (mojoProperties != null) {
2298 try {
2299 mojoProperties.close();
2300 } catch (IOException ex) {
2301 if (getLog().isDebugEnabled()) {
2302 getLog().debug("", ex);
2303 }
2304 }
2305 }
2306 }
2307 settings.setStringIfNotEmpty(Settings.KEYS.MAVEN_LOCAL_REPO, mavenSettings.getLocalRepository());
2308 settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
2309 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
2310 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIRED_ENABLED, enableRetired);
2311 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_DEP_ENABLED, golangDepEnabled);
2312 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_MOD_ENABLED, golangModEnabled);
2313 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_DART_ENABLED, dartAnalyzerEnabled);
2314 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_GOLANG_PATH, pathToGo);
2315 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_YARN_PATH, pathToYarn);
2316 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_PNPM_PATH, pathToPnpm);
2317
2318
2319 final Proxy mavenProxyHttp = getMavenProxy(PROTOCOL_HTTP);
2320 final Proxy mavenProxyHttps = getMavenProxy(PROTOCOL_HTTPS);
2321 String httpsNonProxyHosts = null;
2322 String httpNonProxyHosts = null;
2323 boolean proxySetFromMavenSettings = false;
2324 if (mavenProxyHttps != null || mavenProxyHttp != null) {
2325 final String existingHttps = StringUtils.trimToNull(System.getProperty("https.proxyHost"));
2326 if (existingHttps == null) {
2327 proxySetFromMavenSettings = true;
2328 if (mavenProxyHttps != null) {
2329 setProxyServerSysPropsFromMavenProxy(mavenProxyHttps, PROTOCOL_HTTPS);
2330 if (mavenProxyHttps.getNonProxyHosts() != null && !mavenProxyHttps.getNonProxyHosts().isEmpty()) {
2331 httpsNonProxyHosts = mavenProxyHttps.getNonProxyHosts();
2332 }
2333 } else {
2334 setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTPS);
2335 httpsNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2336 }
2337 }
2338 final String existingHttp = StringUtils.trimToNull(System.getProperty("http.proxyHost"));
2339 if (mavenProxyHttp != null && existingHttp == null) {
2340 proxySetFromMavenSettings = true;
2341 setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTP);
2342 httpNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2343 }
2344 if (proxySetFromMavenSettings) {
2345 final String existingNonProxyHosts = System.getProperty("http.nonProxyHosts");
2346 System.setProperty("http.nonProxyHosts", mergeNonProxyHosts(existingNonProxyHosts, httpNonProxyHosts, httpsNonProxyHosts));
2347 }
2348 } else if (this.proxy != null && this.proxy.getHost() != null) {
2349
2350 settings.setString(Settings.KEYS.PROXY_SERVER, this.proxy.getHost());
2351 settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(this.proxy.getPort()));
2352
2353 configureServerCredentials(this.proxy.getServerId(), Settings.KEYS.PROXY_USERNAME, Settings.KEYS.PROXY_PASSWORD);
2354 }
2355
2356 final String[] suppressions = determineSuppressions();
2357 settings.setArrayIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressions);
2358 settings.setBooleanIfNotNull(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, versionCheckEnabled);
2359 settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
2360 settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_READ_TIMEOUT, readTimeout);
2361 settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile);
2362 settings.setFloat(Settings.KEYS.JUNIT_FAIL_ON_CVSS, junitFailOnCVSS);
2363 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
2364 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
2365 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUGETCONF_ENABLED, nugetconfAnalyzerEnabled);
2366 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_LIBMAN_ENABLED, libmanAnalyzerEnabled);
2367 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
2368 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_USE_CACHE, centralAnalyzerUseCache);
2369 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_ENABLED, artifactoryAnalyzerEnabled);
2370 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
2371 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
2372 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MSBUILD_PROJECT_ENABLED, msbuildAnalyzerEnabled);
2373 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
2374 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_KNOWN_EXPLOITED_ENABLED, knownExploitedEnabled);
2375 settings.setStringIfNotEmpty(Settings.KEYS.KEV_URL, knownExploitedUrl);
2376 try {
2377 configureCredentials(knownExploitedServerId, knownExploitedUser, knownExploitedPassword, knownExploitedBearerToken,
2378 Settings.KEYS.KEV_USER, Settings.KEYS.KEV_PASSWORD, Settings.KEYS.KEV_BEARER_TOKEN);
2379 } catch (InitializationException ex) {
2380 if (this.failOnError) {
2381 throw new MojoFailureException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2382 } else {
2383 throw new MojoExecutionException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2384 }
2385 }
2386 settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
2387 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_DOTNET_PATH, pathToCore);
2388 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
2389 configureServerCredentials(nexusServerId, Settings.KEYS.ANALYZER_NEXUS_USER, Settings.KEYS.ANALYZER_NEXUS_PASSWORD);
2390 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
2391 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_URL, artifactoryAnalyzerUrl);
2392 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_USES_PROXY, artifactoryAnalyzerUseProxy);
2393 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_PARALLEL_ANALYSIS, artifactoryAnalyzerParallelAnalysis);
2394 settings.setBooleanIfNotNull(Settings.KEYS.FAIL_ON_UNUSED_SUPPRESSION_RULE, failBuildOnUnusedSuppressionRule);
2395 if (Boolean.TRUE.equals(artifactoryAnalyzerEnabled)) {
2396 if (artifactoryAnalyzerServerId != null) {
2397 configureServerCredentials(artifactoryAnalyzerServerId, Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME,
2398 Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN);
2399 } else {
2400 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME, artifactoryAnalyzerUsername);
2401 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN, artifactoryAnalyzerApiToken);
2402 }
2403 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_BEARER_TOKEN, artifactoryAnalyzerBearerToken);
2404 }
2405 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
2406 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
2407 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
2408 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
2409 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
2410 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
2411 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MAVEN_INSTALL_ENABLED, mavenInstallAnalyzerEnabled);
2412 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIP_ENABLED, pipAnalyzerEnabled);
2413 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIPFILE_ENABLED, pipfileAnalyzerEnabled);
2414 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_POETRY_ENABLED, poetryAnalyzerEnabled);
2415 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
2416 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_SKIP_DEV, composerAnalyzerSkipDev);
2417 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CPANFILE_ENABLED, cpanfileAnalyzerEnabled);
2418 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
2419 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_ENABLED, nodeAuditAnalyzerEnabled);
2420 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_URL, nodeAuditAnalyzerUrl);
2421 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_USE_CACHE, nodeAuditAnalyzerUseCache);
2422 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_SKIPDEV, nodePackageSkipDevDependencies);
2423 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_SKIPDEV, nodeAuditSkipDevDependencies);
2424 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_YARN_AUDIT_ENABLED, yarnAuditAnalyzerEnabled);
2425 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PNPM_AUDIT_ENABLED, pnpmAuditAnalyzerEnabled);
2426 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_ENABLED, retireJsAnalyzerEnabled);
2427 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_URL, retireJsUrl);
2428 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FORCEUPDATE, retireJsForceUpdate);
2429
2430 try {
2431 configureCredentials(retireJsUrlServerId, retireJsUser, retireJsPassword, retireJsBearerToken,
2432 Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_USER, Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_PASSWORD, Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_BEARER_TOKEN);
2433 } catch (InitializationException ex) {
2434 if (this.failOnError) {
2435 throw new MojoFailureException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2436 } else {
2437 throw new MojoExecutionException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2438 }
2439 }
2440 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_ENABLED, mixAuditAnalyzerEnabled);
2441 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_PATH, mixAuditPath);
2442 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, bundleAuditAnalyzerEnabled);
2443 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, bundleAuditPath);
2444 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_WORKING_DIRECTORY, bundleAuditWorkingDirectory);
2445 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COCOAPODS_ENABLED, cocoapodsAnalyzerEnabled);
2446 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CARTHAGE_ENABLED, carthageAnalyzerEnabled);
2447 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED, swiftPackageManagerAnalyzerEnabled);
2448 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_RESOLVED_ENABLED, swiftPackageResolvedAnalyzerEnabled);
2449 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_ENABLED, ossindexAnalyzerEnabled);
2450 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_URL, ossindexAnalyzerUrl);
2451 if (StringUtils.isEmpty(ossIndexUsername) || StringUtils.isEmpty(ossIndexPassword)) {
2452 configureServerCredentials(ossIndexServerId, Settings.KEYS.ANALYZER_OSSINDEX_USER, Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD);
2453 } else {
2454 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_USER, ossIndexUsername);
2455 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD, ossIndexPassword);
2456 }
2457 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_USE_CACHE, ossindexAnalyzerUseCache);
2458 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS, ossIndexWarnOnlyOnRemoteErrors);
2459 if (retirejs != null) {
2460 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FILTER_NON_VULNERABLE, retirejs.getFilterNonVulnerable());
2461 settings.setArrayIfNotEmpty(Settings.KEYS.ANALYZER_RETIREJS_FILTERS, retirejs.getFilters());
2462 }
2463
2464 settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
2465 settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
2466 settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
2467 if (databaseUser == null && databasePassword == null && serverId != null) {
2468 configureServerCredentials(serverId, Settings.KEYS.DB_USER, Settings.KEYS.DB_PASSWORD);
2469 } else {
2470 settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
2471 settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
2472 }
2473 settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
2474 settings.setStringIfNotEmpty(Settings.KEYS.DB_FILE_NAME, dbFilename);
2475 settings.setStringIfNotNull(Settings.KEYS.NVD_API_ENDPOINT, nvdApiEndpoint);
2476 settings.setIntIfNotNull(Settings.KEYS.NVD_API_DELAY, nvdApiDelay);
2477 settings.setIntIfNotNull(Settings.KEYS.NVD_API_RESULTS_PER_PAGE, nvdApiResultsPerPage);
2478 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_URL, nvdDatafeedUrl);
2479 settings.setIntIfNotNull(Settings.KEYS.NVD_API_VALID_FOR_HOURS, nvdValidForHours);
2480 settings.setIntIfNotNull(Settings.KEYS.NVD_API_MAX_RETRY_COUNT, nvdMaxRetryCount);
2481 if (nvdApiKey == null) {
2482 if (nvdApiKeyEnvironmentVariable != null) {
2483 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, System.getenv(nvdApiKeyEnvironmentVariable));
2484 getLog().debug("Using NVD API key from environment variable " + nvdApiKeyEnvironmentVariable);
2485 } else if (nvdApiServerId != null) {
2486 try {
2487 configureServerCredentialsApiKey(nvdApiServerId, Settings.KEYS.NVD_API_KEY);
2488 } catch (InitializationException ex) {
2489 if (this.failOnError) {
2490 throw new MojoFailureException("Invalid plugin configuration specified for NVD API authentication", ex);
2491 } else {
2492 throw new MojoExecutionException("Invalid plugin configuration specified for NVD API authentication", ex);
2493 }
2494 }
2495 getLog().debug("Using NVD API key from server's password with id " + nvdApiServerId + " in settings.xml");
2496 }
2497 } else {
2498 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, nvdApiKey);
2499 }
2500 try {
2501 configureCredentials(nvdDatafeedServerId, nvdUser, nvdPassword, nvdBearerToken,
2502 Settings.KEYS.NVD_API_DATAFEED_USER, Settings.KEYS.NVD_API_DATAFEED_PASSWORD, Settings.KEYS.NVD_API_DATAFEED_BEARER_TOKEN);
2503 } catch (InitializationException ex) {
2504 if (this.failOnError) {
2505 throw new MojoFailureException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2506 } else {
2507 throw new MojoExecutionException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2508 }
2509 }
2510 settings.setBooleanIfNotNull(Settings.KEYS.PRETTY_PRINT, prettyPrint);
2511 artifactScopeExcluded = new ArtifactScopeExcluded(skipTestScope, skipProvidedScope, skipSystemScope, skipRuntimeScope);
2512 artifactTypeExcluded = new ArtifactTypeExcluded(skipArtifactType);
2513 try {
2514 configureCredentials(suppressionFileServerId, suppressionFileUser, suppressionFilePassword, suppressionFileBearerToken,
2515 Settings.KEYS.SUPPRESSION_FILE_USER, Settings.KEYS.SUPPRESSION_FILE_PASSWORD, Settings.KEYS.SUPPRESSION_FILE_BEARER_TOKEN);
2516 } catch (InitializationException ex) {
2517 if (this.failOnError) {
2518 throw new MojoFailureException("Invalid plugin configuration specified for suppression file authentication", ex);
2519 } else {
2520 throw new MojoExecutionException("Invalid plugin configuration specified for suppression file authentication", ex);
2521 }
2522 }
2523
2524 settings.setIntIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, hostedSuppressionsValidForHours);
2525 settings.setStringIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_URL, hostedSuppressionsUrl);
2526 settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, hostedSuppressionsForceUpdate);
2527 settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_ENABLED, hostedSuppressionsEnabled);
2528 try {
2529 configureCredentials(hostedSuppressionsServerId, hostedSuppressionsUser, hostedSuppressionsPassword, hostedSuppressionsBearerToken,
2530 Settings.KEYS.HOSTED_SUPPRESSIONS_USER, Settings.KEYS.HOSTED_SUPPRESSIONS_PASSWORD, Settings.KEYS.HOSTED_SUPPRESSIONS_BEARER_TOKEN);
2531 } catch (InitializationException ex) {
2532 if (this.failOnError) {
2533 throw new MojoFailureException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2534 } else {
2535 throw new MojoExecutionException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2536 }
2537 }
2538 }
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558 private void configureCredentials(String serverId, String usernameValue, String passwordValue, String tokenValue,
2559 String userKey, String passwordKey, String tokenKey) throws InitializationException {
2560 if (serverId != null) {
2561 if (usernameValue != null || passwordValue != null || tokenValue != null) {
2562 throw new InitializationException(
2563 "Username/password/token configurations should be left out when a serverId (" + serverId + ") is configured");
2564 }
2565 final Server server = settingsXml.getServer(serverId);
2566 if (server != null) {
2567 configureFromServer(server, userKey, passwordKey, tokenKey, serverId);
2568 } else {
2569 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId));
2570 }
2571 } else {
2572 settings.setStringIfNotEmpty(userKey, usernameValue);
2573 settings.setStringIfNotEmpty(passwordKey, passwordValue);
2574 settings.setStringIfNotEmpty(tokenKey, tokenValue);
2575 }
2576 }
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591 private void configureFromServer(Server server, String userKey, String passwordKey, String tokenKey, String serverId) throws InitializationException {
2592 final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
2593 final String username = server.getUsername();
2594 final String password;
2595 if (result.getProblems().isEmpty()) {
2596 password = result.getServer().getPassword();
2597 } else {
2598 logProblems(result.getProblems(), "server setting for " + serverId);
2599 getLog().debug("Using raw password from settings.xml for server " + serverId);
2600 password = server.getPassword();
2601 }
2602 if (username != null) {
2603 if (userKey != null && passwordKey != null) {
2604 settings.setStringIfNotEmpty(userKey, username);
2605 settings.setStringIfNotEmpty(passwordKey, password);
2606 } else {
2607 getLog().warn("Basic type server authentication encountered in serverId " + serverId + ", but only Bearer authentication is "
2608 + "supported for the resource. For Bearer authentication tokens you should leave out the username in the server-entry in"
2609 + " settings.xml");
2610 settings.setStringIfNotEmpty(tokenKey, password);
2611 }
2612 } else {
2613 if (tokenKey != null) {
2614 settings.setStringIfNotEmpty(tokenKey, password);
2615 } else {
2616 throw new InitializationException(
2617 "Bearer type server authentication encountered in serverId " + serverId + ", but only Basic authentication is supported for "
2618 + "the resource. Looks like the username was forgotten to be added in the server-entry in settings.xml");
2619 }
2620 }
2621 }
2622
2623 private String mergeNonProxyHosts(String existingNonProxyHosts, String httpNonProxyHosts, String httpsNonProxyHosts) {
2624 final HashSet<String> mergedNonProxyHosts = new HashSet<>();
2625 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(existingNonProxyHosts).split("\\|")));
2626 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpNonProxyHosts).split("\\|")));
2627 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpsNonProxyHosts).split("\\|")));
2628 return String.join("|", mergedNonProxyHosts);
2629 }
2630
2631 private void setProxyServerSysPropsFromMavenProxy(Proxy mavenProxy, String protocol) {
2632 System.setProperty(protocol + ".proxyHost", mavenProxy.getHost());
2633 if (mavenProxy.getPort() > 0) {
2634 System.setProperty(protocol + ".proxyPort", String.valueOf(mavenProxy.getPort()));
2635 }
2636 if (mavenProxy.getUsername() != null && !mavenProxy.getUsername().isEmpty()) {
2637 System.setProperty(protocol + ".proxyUser", mavenProxy.getUsername());
2638 }
2639 final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(mavenProxy));
2640 final String password;
2641 if (result.getProblems().isEmpty()) {
2642 password = result.getProxy().getPassword();
2643 } else {
2644 logProblems(result.getProblems(), "proxy settings for " + mavenProxy.getId());
2645 getLog().debug("Using raw password from settings.xml for proxy " + mavenProxy.getId());
2646 password = mavenProxy.getPassword();
2647 }
2648 if (password != null && !password.isEmpty()) {
2649 System.setProperty(protocol + ".proxyPassword", password);
2650 }
2651 }
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662 private void configureServerCredentials(String serverId, String userSettingKey, String passwordSettingKey) throws MojoFailureException, MojoExecutionException {
2663 try {
2664 configureCredentials(serverId, null, null, null, userSettingKey, passwordSettingKey, null);
2665 } catch (InitializationException ex) {
2666 if (this.failOnError) {
2667 throw new MojoFailureException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2668 } else {
2669 throw new MojoExecutionException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2670 }
2671 }
2672 }
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682 private void configureServerCredentialsApiKey(String serverId, String apiKeySetting) throws InitializationException {
2683 configureCredentials(serverId, null, null, null, null, null, apiKeySetting);
2684 }
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695 private void logProblems(List<SettingsProblem> problems, String credentialDesc) {
2696 final String message = "Problems while decrypting " + credentialDesc;
2697 getLog().warn(message);
2698 if (getLog().isDebugEnabled()) {
2699 final StringBuilder dbgMessage = new StringBuilder("Problems while decrypting ").append(credentialDesc).append(": ");
2700 boolean first = true;
2701 for (SettingsProblem problem : problems) {
2702 dbgMessage.append(first ? "" : ", ").append(problem.getMessage());
2703 dbgMessage.append("caused by ").append(problem.getException());
2704 first = false;
2705 }
2706 getLog().debug(dbgMessage.toString());
2707 }
2708 }
2709
2710
2711
2712
2713
2714
2715
2716 private String[] determineSuppressions() {
2717 String[] suppressions = suppressionFiles;
2718 if (suppressionFile != null) {
2719 if (suppressions == null) {
2720 suppressions = new String[]{suppressionFile};
2721 } else {
2722 suppressions = Arrays.copyOf(suppressions, suppressions.length + 1);
2723 suppressions[suppressions.length - 1] = suppressionFile;
2724 }
2725 }
2726 return suppressions;
2727 }
2728
2729
2730
2731
2732 protected void muteNoisyLoggers() {
2733 System.setProperty("jcs.logSystem", "slf4j");
2734 if (!getLog().isDebugEnabled()) {
2735 Slf4jAdapter.muteLogging(true);
2736 }
2737
2738 final String[] noisyLoggers = {
2739 "org.apache.hc"
2740 };
2741 for (String loggerName : noisyLoggers) {
2742 System.setProperty("org.slf4j.simpleLogger.log." + loggerName, "error");
2743 }
2744 }
2745
2746
2747
2748
2749
2750
2751
2752 private Proxy getMavenProxy(String protocol) {
2753 if (mavenSettings != null) {
2754 final List<Proxy> proxies = mavenSettings.getProxies();
2755 if (proxies != null && !proxies.isEmpty()) {
2756 if (mavenSettingsProxyId != null) {
2757 for (Proxy proxy : proxies) {
2758 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
2759 return proxy;
2760 }
2761 }
2762 } else {
2763 for (Proxy aProxy : proxies) {
2764 if (aProxy.isActive() && aProxy.getProtocol().equals(protocol)) {
2765 return aProxy;
2766 }
2767 }
2768 }
2769 }
2770 }
2771 return null;
2772 }
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784 protected MavenProject getProject() {
2785 return project;
2786 }
2787
2788
2789
2790
2791
2792
2793 protected List<MavenProject> getReactorProjects() {
2794 return reactorProjects;
2795 }
2796
2797
2798
2799
2800
2801
2802 private Set<String> getFormats() {
2803 final Set<String> invalid = new HashSet<>();
2804 final Set<String> selectedFormats = formats == null || formats.length == 0 ? new HashSet<>() : new HashSet<>(Arrays.asList(formats));
2805 selectedFormats.forEach((s) -> {
2806 try {
2807 ReportGenerator.Format.valueOf(s.toUpperCase());
2808 } catch (IllegalArgumentException ex) {
2809 invalid.add(s);
2810 }
2811 });
2812 invalid.forEach((s) -> getLog().warn("Invalid report format specified: " + s));
2813 if (selectedFormats.contains("true")) {
2814 selectedFormats.remove("true");
2815 }
2816 if (format != null && selectedFormats.isEmpty()) {
2817 selectedFormats.add(format);
2818 }
2819 return selectedFormats;
2820 }
2821
2822
2823
2824
2825
2826
2827
2828 public List<String> getExcludes() {
2829 if (excludes == null) {
2830 excludes = new ArrayList<>();
2831 }
2832 return excludes;
2833 }
2834
2835
2836
2837
2838
2839
2840 protected Filter<String> getArtifactScopeExcluded() {
2841 return artifactScopeExcluded;
2842 }
2843
2844
2845
2846
2847
2848
2849 protected Settings getSettings() {
2850 return settings;
2851 }
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862 protected void checkForFailure(Dependency[] dependencies) throws MojoFailureException {
2863 final StringBuilder ids = new StringBuilder();
2864 for (Dependency d : dependencies) {
2865 boolean addName = true;
2866 for (Vulnerability v : d.getVulnerabilities()) {
2867 final double cvssV2 = v.getCvssV2() != null && v.getCvssV2().getCvssData() != null && v.getCvssV2().getCvssData().getBaseScore() != null ? v.getCvssV2().getCvssData().getBaseScore() : -1;
2868 final double cvssV3 = v.getCvssV3() != null && v.getCvssV3().getCvssData() != null && v.getCvssV3().getCvssData().getBaseScore() != null ? v.getCvssV3().getCvssData().getBaseScore() : -1;
2869 final double cvssV4 = v.getCvssV4() != null && v.getCvssV4().getCvssData() != null && v.getCvssV4().getCvssData().getBaseScore() != null ? v.getCvssV4().getCvssData().getBaseScore() : -1;
2870 final boolean useUnscored = cvssV2 == -1 && cvssV3 == -1 && cvssV4 == -1;
2871 final double unscoredCvss = (useUnscored && v.getUnscoredSeverity() != null) ? SeverityUtil.estimateCvssV2(v.getUnscoredSeverity()) : -1;
2872
2873 if (failBuildOnAnyVulnerability
2874 || cvssV2 >= failBuildOnCVSS
2875 || cvssV3 >= failBuildOnCVSS
2876 || cvssV4 >= failBuildOnCVSS
2877 || unscoredCvss >= failBuildOnCVSS
2878
2879 || failBuildOnCVSS <= 0.0
2880 ) {
2881 String name = v.getName();
2882 if (cvssV4 >= 0.0) {
2883 name += "(" + cvssV4 + ")";
2884 } else if (cvssV3 >= 0.0) {
2885 name += "(" + cvssV3 + ")";
2886 } else if (cvssV2 >= 0.0) {
2887 name += "(" + cvssV2 + ")";
2888 } else if (unscoredCvss >= 0.0) {
2889 name += "(" + unscoredCvss + ")";
2890 }
2891 if (addName) {
2892 addName = false;
2893 ids.append(NEW_LINE).append(d.getFileName()).append(" (")
2894 .append(Stream.concat(d.getSoftwareIdentifiers().stream(), d.getVulnerableSoftwareIdentifiers().stream())
2895 .map(Identifier::getValue)
2896 .collect(Collectors.joining(", ")))
2897 .append("): ")
2898 .append(name);
2899 } else {
2900 ids.append(", ").append(name);
2901 }
2902 }
2903 }
2904 }
2905 if (ids.length() > 0) {
2906 final String msg;
2907 if (showSummary) {
2908 if (failBuildOnAnyVulnerability) {
2909 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities: %n%s%n%n"
2910 + "See the dependency-check report for more details.%n%n", ids);
2911 } else {
2912 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities that have a CVSS score greater than or "
2913 + "equal to '%.1f': %n%s%n%nSee the dependency-check report for more details.%n%n", failBuildOnCVSS, ids);
2914 }
2915 } else {
2916 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities.%n%n"
2917 + "See the dependency-check report for more details.%n%n");
2918 }
2919 throw new MojoFailureException(msg);
2920 }
2921 }
2922
2923
2924
2925
2926
2927
2928
2929
2930 protected void showSummary(MavenProject mp, Dependency[] dependencies) {
2931 if (showSummary) {
2932 DependencyCheckScanAgent.showSummary(mp.getName(), dependencies);
2933 }
2934 }
2935
2936
2937
2938 private ExceptionCollection scanDependencyNode(DependencyNode dependencyNode, DependencyNode root,
2939 Engine engine, MavenProject project, List<ArtifactResult> allResolvedDeps,
2940 ProjectBuildingRequest buildingRequest, boolean aggregate, ExceptionCollection exceptionCollection) {
2941 ExceptionCollection exCol = exceptionCollection;
2942 if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope())
2943 || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) {
2944 return exCol;
2945 }
2946
2947 boolean isResolved = false;
2948 File artifactFile = null;
2949 String artifactId = null;
2950 String groupId = null;
2951 String version = null;
2952 List<ArtifactVersion> availableVersions = null;
2953 if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
2954 final Artifact a = dependencyNode.getArtifact();
2955 if (a.isResolved() && a.getFile().isFile()) {
2956 artifactFile = a.getFile();
2957 isResolved = artifactFile.isFile();
2958 groupId = a.getGroupId();
2959 artifactId = a.getArtifactId();
2960 version = a.getVersion();
2961 availableVersions = a.getAvailableVersions();
2962 } else {
2963 for (org.apache.maven.model.Dependency d : project.getDependencies()) {
2964 if (d.getSystemPath() != null && artifactsMatch(d, a)) {
2965 artifactFile = new File(d.getSystemPath());
2966 isResolved = artifactFile.isFile();
2967 groupId = a.getGroupId();
2968 artifactId = a.getArtifactId();
2969 version = a.getVersion();
2970 availableVersions = a.getAvailableVersions();
2971 break;
2972 }
2973 }
2974 }
2975 Throwable ignored = null;
2976 if (!isResolved) {
2977
2978
2979 try {
2980 tryResolutionOnce(project, allResolvedDeps, buildingRequest);
2981 final Artifact result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
2982 isResolved = result.isResolved();
2983 artifactFile = result.getFile();
2984 groupId = result.getGroupId();
2985 artifactId = result.getArtifactId();
2986 version = result.getVersion();
2987 availableVersions = result.getAvailableVersions();
2988 } catch (DependencyNotFoundException | DependencyResolverException e) {
2989 getLog().warn("Error performing last-resort System-scoped dependency resolution: " + e.getMessage());
2990 ignored = e;
2991 }
2992 }
2993 if (!isResolved) {
2994 final StringBuilder message = new StringBuilder("Unable to resolve system scoped dependency: ");
2995 if (artifactFile != null) {
2996 message.append(dependencyNode.toNodeString()).append(" at path ").append(artifactFile);
2997 } else {
2998 message.append(dependencyNode.toNodeString()).append(" at path ").append(a.getFile());
2999 }
3000 getLog().error(message);
3001 if (exCol == null) {
3002 exCol = new ExceptionCollection();
3003 }
3004 final Exception thrown = new DependencyNotFoundException(message.toString());
3005 if (ignored != null) {
3006 thrown.addSuppressed(ignored);
3007 }
3008 exCol.addException(thrown);
3009 }
3010 } else {
3011 final Artifact dependencyArtifact = dependencyNode.getArtifact();
3012 final Artifact result;
3013 if (dependencyArtifact.isResolved()) {
3014
3015
3016
3017 getLog().debug(String.format("Skipping artifact %s, already resolved", dependencyArtifact.getArtifactId()));
3018 result = dependencyArtifact;
3019 } else {
3020 try {
3021 tryResolutionOnce(project, allResolvedDeps, buildingRequest);
3022 result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
3023 } catch (DependencyNotFoundException | DependencyResolverException ex) {
3024 getLog().debug(String.format("Aggregate : %s", aggregate));
3025 boolean addException = true;
3026
3027 if (!aggregate) {
3028
3029 } else if (addReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3030
3031 addException = false;
3032 }
3033 if (addException) {
3034 if (exCol == null) {
3035 exCol = new ExceptionCollection();
3036 }
3037 exCol.addException(ex);
3038 }
3039 return exCol;
3040 }
3041 }
3042 if (aggregate && virtualSnapshotsFromReactor
3043 && dependencyNode.getArtifact().isSnapshot()
3044 && addSnapshotReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3045 return exCol;
3046 }
3047 isResolved = result.isResolved();
3048 artifactFile = result.getFile();
3049 groupId = result.getGroupId();
3050 artifactId = result.getArtifactId();
3051 version = result.getVersion();
3052 availableVersions = result.getAvailableVersions();
3053 }
3054 if (isResolved && artifactFile != null) {
3055 final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
3056 createProjectReferenceName(project, dependencyNode));
3057 if (deps != null) {
3058 processResolvedArtifact(artifactFile, deps, groupId, artifactId, version, root, project, availableVersions, dependencyNode);
3059 } else if ("import".equals(dependencyNode.getArtifact().getScope())) {
3060 final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope",
3061 dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3062 getLog().debug(msg);
3063 } else if ("pom".equals(dependencyNode.getArtifact().getType())) {
3064 exCol = processPomArtifact(artifactFile, root, project, engine, exCol);
3065 } else {
3066 if (!scannedFiles.contains(artifactFile)) {
3067 final String msg = String.format("No analyzer could be found or the artifact has been scanned twice for '%s:%s' in project %s",
3068 dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3069 getLog().warn(msg);
3070 }
3071 }
3072 } else {
3073 final String msg = String.format("Unable to resolve '%s' in project %s",
3074 dependencyNode.getArtifact().getId(), project.getName());
3075 getLog().debug(msg);
3076 if (exCol == null) {
3077 exCol = new ExceptionCollection();
3078 }
3079 }
3080 return exCol;
3081 }
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102 private void tryResolutionOnce(MavenProject project, List<ArtifactResult> allResolvedDeps, ProjectBuildingRequest buildingRequest) throws DependencyResolverException {
3103 if (allResolvedDeps.isEmpty()) {
3104 try {
3105 final List<org.apache.maven.model.Dependency> dependencies = project.getDependencies();
3106 final List<org.apache.maven.model.Dependency> managedDependencies = project
3107 .getDependencyManagement() == null ? null : project.getDependencyManagement().getDependencies();
3108 final Iterable<ArtifactResult> allDeps = dependencyResolver
3109 .resolveDependencies(buildingRequest, dependencies, managedDependencies, null);
3110 allDeps.forEach(allResolvedDeps::add);
3111 } catch (DependencyResolverException dre) {
3112 if (dre.getCause() instanceof org.eclipse.aether.resolution.DependencyResolutionException) {
3113 final List<ArtifactResult> successResults = Mshared998Util
3114 .getResolutionResults((org.eclipse.aether.resolution.DependencyResolutionException) dre.getCause());
3115 allResolvedDeps.addAll(successResults);
3116 } else {
3117 throw dre;
3118 }
3119 }
3120 }
3121 }
3122
3123
3124
3125 private void processResolvedArtifact(File artifactFile, final List<Dependency> deps,
3126 String groupId, String artifactId, String version, DependencyNode root,
3127 MavenProject project1, List<ArtifactVersion> availableVersions,
3128 DependencyNode dependencyNode) {
3129 scannedFiles.add(artifactFile);
3130 Dependency d = null;
3131 if (deps.size() == 1) {
3132 d = deps.get(0);
3133
3134 } else {
3135 for (Dependency possible : deps) {
3136 if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
3137 d = possible;
3138 break;
3139 }
3140 }
3141 for (Dependency dep : deps) {
3142 if (d != null && d != dep) {
3143 final String includedBy = buildReference(groupId, artifactId, version);
3144 dep.addIncludedBy(includedBy);
3145 }
3146 }
3147 }
3148 if (d != null) {
3149 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
3150 d.addAsEvidence("pom", ma, Confidence.HIGHEST);
3151 if (root != null) {
3152 final String includedby = buildReference(
3153 root.getArtifact().getGroupId(),
3154 root.getArtifact().getArtifactId(),
3155 root.getArtifact().getVersion());
3156 d.addIncludedBy(includedby);
3157 } else {
3158 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3159 d.addIncludedBy(includedby);
3160 }
3161 if (availableVersions != null) {
3162 for (ArtifactVersion av : availableVersions) {
3163 d.addAvailableVersion(av.toString());
3164 }
3165 }
3166 getLog().debug(String.format("Adding project reference %s on dependency %s", project1.getName(), d.getDisplayFileName()));
3167 } else if (getLog().isDebugEnabled()) {
3168 final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", dependencyNode.getArtifact().getId(), project1.getName());
3169 getLog().debug(msg);
3170 }
3171 }
3172
3173
3174 private ExceptionCollection processPomArtifact(File artifactFile, DependencyNode root,
3175 MavenProject project1, Engine engine, ExceptionCollection exCollection) {
3176 ExceptionCollection exCol = exCollection;
3177 try {
3178 final Dependency d = new Dependency(artifactFile.getAbsoluteFile());
3179 final Model pom = PomUtils.readPom(artifactFile.getAbsoluteFile());
3180 JarAnalyzer.setPomEvidence(d, pom, null, true);
3181 if (root != null) {
3182 final String includedby = buildReference(
3183 root.getArtifact().getGroupId(),
3184 root.getArtifact().getArtifactId(),
3185 root.getArtifact().getVersion());
3186 d.addIncludedBy(includedby);
3187 } else {
3188 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3189 d.addIncludedBy(includedby);
3190 }
3191 engine.addDependency(d);
3192 } catch (AnalysisException ex) {
3193 if (exCol == null) {
3194 exCol = new ExceptionCollection();
3195 }
3196 exCol.addException(ex);
3197 getLog().debug("Error reading pom " + artifactFile.getAbsoluteFile(), ex);
3198 }
3199 return exCol;
3200 }
3201
3202 }
3203