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