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