Compare commits

...

422 Commits

Author SHA1 Message Date
Jeremy Long
1b3b4a5906 version 1.3.2 2015-11-29 07:34:45 -05:00
Jeremy Long
5c8b374352 updated documentation 2015-11-28 08:14:00 -05:00
Jeremy Long
e05cef6886 extended the wrong base test case 2015-11-27 07:07:17 -05:00
Jeremy Long
cb39ecacf9 moved dependency-check-gradle to a new repo 2015-11-27 06:54:48 -05:00
Jeremy Long
e6816f94eb moving documentation of gradle and jenkins plugins under the main parent site 2015-11-26 06:36:35 -05:00
Jeremy Long
8b5dbeab44 removed stack trace in build when bundle audit is not installed 2015-11-25 05:59:58 -05:00
Jeremy Long
29c21c3611 pmd/checkstyle/findbugs corrections 2015-11-25 05:43:04 -05:00
Jeremy Long
e05bed8d65 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-11-24 16:12:30 -05:00
Jeremy Long
1b2210aba0 pmd/checkstyle/findbugs corrections 2015-11-24 16:12:23 -05:00
Jeremy Long
7fb1b1d57b Merge pull request #330 from dwvisser/ruby-bundler
Ruby bundler-audit Analyzer
2015-11-24 15:53:00 -05:00
Jeremy Long
a3adf71a1d avoid npe 2015-11-24 05:43:45 -05:00
Jeremy Long
51d81fab5d grok assembly exe was hanging, reordered so input stream was processed before error stream to resolve the issue. 2015-11-24 05:34:34 -05:00
Dale Visser
2ed5dc153a Fixed merge conflict in App.java 2015-11-23 13:27:22 -05:00
Jeremy Long
5f8f156bee Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-11-22 07:31:27 -05:00
Jeremy Long
eb03c90d7a updated documentation 2015-11-22 07:31:17 -05:00
Jeremy Long
fc05471086 bug fix that might be related to #388, in addition added logging incase the bug fix does not work 2015-11-22 07:30:28 -05:00
Jeremy Long
b9db2dd89f Merge pull request #409 from awhitford/MinorCodeTweaks
Thanks!
2015-11-22 07:14:12 -05:00
Jeremy Long
de7fe21a4f Merge pull request #411 from hansjoachim/upgrade-slf4j
Upgraded slf4j to latest version
2015-11-22 07:07:07 -05:00
Jeremy Long
56f9a7c4f9 Merge pull request #407 from awhitford/DepUpg
Upgraded dependencies.
2015-11-22 07:06:38 -05:00
Hans Joachim Desserud
df569a5ae2 Upgraded slf4j to latest version 2015-11-14 10:10:44 +01:00
Jeremy Long
acb9d04c51 updated to be feature complete with 1.3.2-SNAPSHOT 2015-11-11 18:44:19 -05:00
Jeremy Long
09c4708a22 update for issue #410 2015-11-11 00:58:00 -05:00
Anthony Whitford
b346dfe0a3 Minor code tweaks. 2015-11-10 00:09:01 -08:00
Jeremy Long
5f259cb88c added missed configuration options for new analyzers 2015-11-07 06:37:36 -05:00
Anthony Whitford
fb2aff3310 Upgraded dependencies. 2015-11-06 23:16:12 -08:00
Jeremy Long
3c4c65c28c corrected NVD CVE URLs 2015-11-04 06:00:04 -05:00
Jeremy Long
15885e3e8c Merge branch 'awhitford-ModelInterpolationAlt' 2015-11-03 05:52:54 -05:00
Jeremy Long
5508c60e85 resulved conflict 2015-11-03 05:52:22 -05:00
Jeremy Long
ffc341e4b9 Merge pull request #405 from awhitford/StringToChar
One character String constants with char constants
2015-11-03 05:43:41 -05:00
Jeremy Long
41a68f7b25 Merge pull request #406 from awhitford/DropCountCharacters
Removed unnecessary countCharacter method.
2015-11-03 05:42:28 -05:00
Anthony Whitford
041d3c5312 Removed unnecessary countCharacter method by leveraging StringUtils.countMatches. 2015-11-01 23:19:37 -08:00
Anthony Whitford
8e8b462bc8 Replaced one character String constants with char constants, when applicable. 2015-11-01 22:39:30 -08:00
Jeremy Long
efbc76e06f Merge pull request #402 from awhitford/SettingsSetters
New setters for Settings
2015-11-01 05:52:34 -05:00
Jeremy Long
67a44d2adc added postgres 2015-11-01 05:50:08 -05:00
Anthony Whitford
92a35b929a Leveraged the new setters with null and empty checking for Settings. 2015-10-31 10:26:32 -07:00
Anthony Whitford
e5744dd63f Added extra setters with null and empty checks. 2015-10-31 10:25:50 -07:00
Jeremy Long
f2f3d050bd added 3.0 update schema 2015-10-31 07:25:02 -04:00
Jeremy Long
0cbecbe3a0 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-10-30 05:42:36 -04:00
Jeremy Long
51a8b5a058 added mysql dialect 2015-10-30 05:41:12 -04:00
Jeremy Long
aaf716e54b Merge pull request #395 from awhitford/IOUtils
Leverage IOUtils
2015-10-30 05:32:44 -04:00
Jeremy Long
209fcc7946 Merge pull request #397 from awhitford/ModelInterpolate
Improved interpolateString.
2015-10-30 05:31:35 -04:00
Jeremy Long
a5cb131806 Merge pull request #400 from kgeis/patch-1
Update index.md.vm
2015-10-30 05:23:09 -04:00
Ken Geis
8fbeb5f5d5 Update index.md.vm
update usage examples to match currently used flags (--app -> --project)
2015-10-28 09:26:59 -07:00
Anthony Whitford
a92bdfe30d Alternative interpolateString implementation leveraging commons-lang3. 2015-10-28 00:08:12 -07:00
Anthony Whitford
7f130ff036 Improved interpolateString. 2015-10-27 23:25:28 -07:00
Jeremy Long
b704f72854 fixed npe 2015-10-27 06:15:34 -04:00
Anthony Whitford
e21f8a97ac More opportunities to leverage IOUtils. 2015-10-27 01:00:29 -07:00
Anthony Whitford
a8ff403809 Removed unused imports. 2015-10-27 01:00:04 -07:00
Anthony Whitford
22097c0a25 Replaced boiler-plate file read with simpler IOUtils call. 2015-10-27 00:10:32 -07:00
Jeremy Long
92e7d9cf80 improved update failure reporting 2015-10-26 06:36:10 -04:00
Jeremy Long
54d921f275 added test case 2015-10-26 06:32:02 -04:00
Jeremy Long
08d7b3dbce currently unused but contains DDL that may be needed in the future 2015-10-26 06:31:43 -04:00
Jeremy Long
6949b3c229 update file cannot contain comments 2015-10-26 06:30:56 -04:00
Jeremy Long
b0ca38bd29 reverted surefire due to IDE integration failures with 2.19 2015-10-26 06:30:16 -04:00
Jeremy Long
cf173ee9e7 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-10-25 06:22:36 -04:00
Jeremy Long
aa9908b34a updated test properties w/ changes that had been made in the main properties 2015-10-25 06:22:30 -04:00
Jeremy Long
640674ef72 minor - added a comment explaining one of the preoperties 2015-10-25 06:21:48 -04:00
Jeremy Long
0c69ab80bb Merge pull request #382 from awhitford/MojoStreamClose
Removed unnecessary OutputStream closing.
2015-10-25 06:04:28 -04:00
Jeremy Long
662557c2f3 Merge pull request #387 from fabioscala/feature/overrideSuppressionFile
Allow setting suppression file in gradle plugin
2015-10-25 06:03:15 -04:00
Jeremy Long
346b2c31d2 moved default values to the properties file instead of hard-coding them 2015-10-25 05:58:57 -04:00
Jeremy Long
62dbf99557 moved default values to the properties file instead of hard-coding them 2015-10-25 05:57:24 -04:00
Jeremy Long
99b140adaa updated field name to make it more clear 2015-10-24 06:19:00 -04:00
Jeremy Long
387d577d4f updated field name to make it more clear 2015-10-24 06:18:36 -04:00
Jeremy Long
ab7eee7db9 updated field name to make it more clear 2015-10-24 06:18:09 -04:00
Jeremy Long
487a45f01b updated field name to make it more clear 2015-10-24 06:17:31 -04:00
Jeremy Long
60665c6bd8 Merge pull request #392 from awhitford/PluginUpgrades
Upgraded plugins.
2015-10-23 06:30:17 -04:00
Jeremy Long
8fc9a3d6d1 Merge pull request #391 from awhitford/CpeSetting
Change CpeUpdater to use CPE_MODIFIED_VALID_FOR_DAYS
2015-10-23 06:29:51 -04:00
Jeremy Long
05a05f7e88 Merge branch 'awhitford-NvdCheck' 2015-10-23 06:28:34 -04:00
Jeremy Long
0c5bdfd7b7 added a setInt in support of PR #390 2015-10-23 06:28:04 -04:00
Jeremy Long
626e93c7e3 minor changes to patch for PR #390 2015-10-23 06:27:29 -04:00
Jeremy Long
b588c4c900 set a default value of four hours for issue #390 2015-10-23 06:26:42 -04:00
Jeremy Long
c52a0d88df expanded issue #390 to the CLI 2015-10-23 06:25:47 -04:00
Jeremy Long
84838d19d9 added documentation for issue #390 2015-10-23 06:25:20 -04:00
Jeremy Long
faf335a181 expanded issue #390 to the Ant task 2015-10-23 06:24:14 -04:00
Jeremy Long
5c25351884 removed default value that over-wrote the properties file value 2015-10-23 06:22:58 -04:00
Jeremy Long
520f3cb09a Merge branch 'NvdCheck' of https://github.com/awhitford/DependencyCheck into awhitford-NvdCheck 2015-10-23 05:32:27 -04:00
Anthony Whitford
e234246618 Upgraded plugins. 2015-10-22 00:18:50 -07:00
Anthony Whitford
5d1d378f61 Shouldn't CPE Updater use the CPE_MODIFIED_VALID_FOR_DAYS setting (not CVE)? 2015-10-21 23:56:28 -07:00
Anthony Whitford
cef3bb7424 Reworked withinDateRange to avoid type conversion between doubles and longs; expressed in long integer math. 2015-10-21 23:27:03 -07:00
Anthony Whitford
ccb03f2763 Added cveValidForHours parameter that can suppress redundant and repetitive checks for NVD CVE changes. 2015-10-21 23:25:18 -07:00
Anthony Whitford
1f6168366b Added logic to optionally prevent overly repetitive checks for NVD CVE changes. 2015-10-21 23:23:47 -07:00
Anthony Whitford
cd5bf85245 Added a database property for recording the last time the NVD CVE was checked. 2015-10-21 23:21:25 -07:00
Anthony Whitford
f2778e5d28 Adding a setting to suppress repetitive NVD checks. 2015-10-21 23:19:57 -07:00
Jeremy Long
c2e6065ed7 added option to change the name of the report per issue #389 2015-10-20 06:18:28 -04:00
Jeremy Long
fccba5f7fd Merge pull request #381 from awhitford/SkipMojo
Added basic skip option for mojos.
2015-10-20 05:58:16 -04:00
Jeremy Long
3f230c5a05 resolve issue #372 2015-10-18 06:32:44 -04:00
Jeremy Long
dc849c3891 removed duplicate abstract test base 2015-10-18 06:17:21 -04:00
Jeremy Long
2770b58a20 fixing the build 2015-10-18 06:07:23 -04:00
Jeremy Long
37519acfb8 minor performance improvement 2015-10-17 07:42:09 -04:00
Jeremy Long
ad8c7b3cd2 missed one character in my lucene escape util 2015-10-17 07:40:38 -04:00
Jeremy Long
04db8d3208 Merge pull request #385 from awhitford/FileUtils
Leverage FilenameUtils
2015-10-16 06:30:53 -04:00
Jeremy Long
666e3b1e30 fix for issue #384 2015-10-16 06:23:03 -04:00
Fabio Scala
dc68781c06 Allow setting suppression file in gradle plugin 2015-10-15 11:24:33 +02:00
Jeremy Long
a7f50d147e depending on test order this test may fail if ArchiveAnalyzer was previously loaded. 2015-10-14 07:12:04 -04:00
Anthony Whitford
7e639db5de Leveraging FilenameUtils rather than string dissection. 2015-10-14 00:16:20 -07:00
Anthony Whitford
19a97a1706 Demonstrating the benefit of commons-io instead of the simpler string dissection. 2015-10-13 23:59:31 -07:00
Anthony Whitford
cd66a9ef61 Demonstrating the benefit of commons-io instead of the simpler string dissection. 2015-10-13 23:59:11 -07:00
Anthony Whitford
f121430a5d Simplified getFileExtension by leveraging commons-io. Also cut a line from delete. 2015-10-13 23:50:41 -07:00
Jeremy Long
2f518dacfc Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-10-13 21:24:22 -04:00
Jeremy Long
fded8b6cd3 fixed issue #383 2015-10-13 21:24:03 -04:00
Jeremy Long
3b6c64dc9d move test resource to correct directory 2015-10-13 19:03:33 -04:00
Jeremy Long
d742985640 resolve issue #377 2015-10-13 19:03:19 -04:00
Jeremy Long
a13dd58989 Merge pull request #380 from awhitford/TestLint
Removed compiler warnings from test code.
2015-10-12 06:46:50 -04:00
Jeremy Long
622b3210ae Merge pull request #379 from awhitford/HashSetLen
Sized the new HashSet to avoid rehashing risk.
2015-10-12 06:46:12 -04:00
Jeremy Long
90c97ed6aa Merge pull request #376 from awhitford/ComposerExSerial
Added missing serialVersionUID to new ComposerException.
2015-10-12 06:45:38 -04:00
Jeremy Long
53a4dfbf88 Merge pull request #378 from awhitford/RmNonCloseStream
Removing unused NonClosingStream.
2015-10-12 06:45:20 -04:00
Jeremy Long
f488c57363 Merge branch 'awhitford-DbMerge' 2015-10-12 06:44:00 -04:00
Jeremy Long
0ce830ca9d fixed test case to correctly initialize the settings 2015-10-12 06:43:32 -04:00
Jeremy Long
30ae418c2c updated MySQL profile 2015-10-12 06:42:55 -04:00
Jeremy Long
3b976d211f upgrdae db schema version 2015-10-12 06:15:24 -04:00
Jeremy Long
cca49b5dc2 added information regarding updating the database schema 2015-10-12 06:13:06 -04:00
Jeremy Long
8c2b2070c6 added URL to database upgrade page 2015-10-12 05:53:07 -04:00
Jeremy Long
24b8ff26db Merge branch 'DbMerge' of https://github.com/awhitford/DependencyCheck into awhitford-DbMerge 2015-10-12 05:48:03 -04:00
Jeremy Long
f0d93538ae changed update script to fail on non-H2 databases; they require manual upgrades 2015-10-12 05:47:50 -04:00
Jeremy Long
02eab65c4e upgrade h2 db schema to 3.0 2015-10-12 05:47:00 -04:00
Jeremy Long
d941aa7df3 script to upgrade a MySQL db 2015-10-12 05:46:33 -04:00
Anthony Whitford
b5026a45f6 Removed unnecessary OutputStream closing. Also the flush and reset are not necessary since the stream is being closed right away. 2015-10-11 19:09:03 -07:00
Anthony Whitford
79fde3ebc9 Added basic skip option for mojos. 2015-10-11 18:44:25 -07:00
Anthony Whitford
031d648585 Removed compiler warnings from test code. 2015-10-11 17:48:27 -07:00
Anthony Whitford
762b2fe7d6 Leverage Collections.singleton for single entry HashSets. 2015-10-11 17:32:08 -07:00
Anthony Whitford
5db377923e Sized the new HashSet to avoid rehashing risk. 2015-10-11 16:51:57 -07:00
Anthony Whitford
c3177df739 Removing unused NonClosingStream. 2015-10-11 11:42:03 -07:00
Anthony Whitford
0dc36765f1 Added missing serialVersionUID to new ComposerException. 2015-10-10 16:19:59 -07:00
Jeremy Long
38e61ebd8d Merge branch 'awhitford-MvnPhase' 2015-10-10 06:15:29 -04:00
Jeremy Long
529b9739b5 changed default phase to VERIFY 2015-10-10 06:14:50 -04:00
Jeremy Long
a014ca7d8a Merge branch 'MvnPhase' of https://github.com/awhitford/DependencyCheck into awhitford-MvnPhase 2015-10-10 05:59:04 -04:00
Jeremy Long
83701f7d0d Merge pull request #374 from awhitford/EngineScanTweak
Consolidated scan(Set) and scan(List) with scan(Collection).
2015-10-10 05:54:31 -04:00
Jeremy Long
b2500939f3 Merge pull request #375 from skitt/cme-fix
Avoid ConcurrentModificationExceptions
2015-10-10 05:52:32 -04:00
Stephen Kitt
1852b9dbb2 Avoid ConcurrentModificationExceptions
AggregateMojo.getDescendants() can end up adding descendants while
it's iterating over them. This separates the addition from the
iteration to avoid this.

Signed-off-by: Stephen Kitt <skitt@redhat.com>
2015-10-09 17:07:27 +02:00
Anthony Whitford
069474fc71 Consolidated scan(Set) and scan(List) with scan(Collection). 2015-10-09 07:52:43 -07:00
Jeremy Long
e7f518264a Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-10-09 08:52:06 -04:00
Jeremy Long
b0b096c3f5 updated version to 1.3.2-SNAPSHOT 2015-10-09 08:51:58 -04:00
Jeremy Long
bfa9d04d42 added another suppression rule 2015-10-09 08:33:04 -04:00
Jeremy Long
7dbe58469a Merge pull request #371 from awhitford/CpeLucenePerf
Re-use Document and Field instances to minimize GC overhead.
2015-10-09 07:03:35 -04:00
Jeremy Long
41b36dabc2 Merge pull request #370 from awhitford/DontLogToString
Do not need or want to call toString for a logger parameter.
2015-10-09 07:01:44 -04:00
Jeremy Long
4a685557d9 Merge pull request #369 from awhitford/BadSuppress
Removed unnecessary @SuppressWarnings.
2015-10-09 07:01:02 -04:00
Jeremy Long
e7ef4b6906 Merge pull request #367 from awhitford/SettingsCleanup
Settings cleanup
2015-10-09 07:00:39 -04:00
Jeremy Long
67502fb9d3 Merge pull request #368 from awhitford/UtilsCleanup
Utils cleanup
2015-10-09 06:59:33 -04:00
Anthony Whitford
960283bdcf Do not need or want to call toString for a logger parameter. 2015-10-09 02:08:07 -07:00
Anthony Whitford
39f30eab7a Re-use Document and Field instances to minimize GC overhead. See http://wiki.apache.org/lucene-java/ImproveIndexingSpeed 2015-10-09 00:38:55 -07:00
Anthony Whitford
24b4741aaf Removed unnecessary @SuppressWarnings. 2015-10-08 23:40:14 -07:00
Anthony Whitford
64f373fb43 Removed old warning suppression. 2015-10-08 20:58:20 -07:00
Anthony Whitford
bc1830d8eb Removed redundant call to length for substring. 2015-10-08 20:57:28 -07:00
Anthony Whitford
f2a2a91682 Slight simplification to standard getInt and getLong. 2015-10-08 00:56:38 -07:00
Anthony Whitford
274ac339ad Corrected a few bugs in Settings. 2015-10-08 00:39:57 -07:00
Anthony Whitford
1d916286ee Changing the check phase from compile to verify. 2015-10-07 23:11:53 -07:00
Jeremy Long
832d54300a fixed suppression for issue #365 2015-10-03 07:41:15 -04:00
Jeremy Long
ba6d3bbe15 added suppression for issue #365 2015-10-03 07:35:05 -04:00
Jeremy Long
c1d0789ac7 the Central analyzer should be enabled by default 2015-09-30 06:37:47 -04:00
Dale Visser
0573d0083e Ruby Bundler: Throw AnalysisException in initialize if can't run bundle-audit. 2015-09-22 15:07:43 -04:00
Dale Visser
e57d62b682 Merge branch 'upmaster' into ruby-bundler
Conflicts:
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java
	dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
2015-09-22 14:21:43 -04:00
Jeremy Long
bb6f27b322 updated other tool(s) listed 2015-09-22 06:12:10 -04:00
Jeremy Long
86f424ad37 Merge pull request #358 from wmaintw/master
update the version of dependency-check-core that the gradle plugin used
2015-09-22 06:01:19 -04:00
ma wei
ad81bbc761 modify README 2015-09-21 09:26:25 +08:00
ma wei
07e868e6f6 upgrade dependency check core version to 1.3.1 2015-09-21 09:24:58 +08:00
Jeremy Long
b45700df03 version 1.3.1 2015-09-20 07:17:00 -04:00
Jeremy Long
93ce2a8e3a fixed path in zip to be different then the cli 2015-09-20 07:14:02 -04:00
Jeremy Long
fbc4d46962 updated language list to include php 2015-09-20 06:39:55 -04:00
Jeremy Long
d73d138b3f checkstyle/pmd/findbugs corrections 2015-09-20 06:39:27 -04:00
Jeremy Long
14ea21d53d checkstyle/pmd/findbugs corrections 2015-09-20 06:38:47 -04:00
Jeremy Long
2b3791b83e checkstyle/findbugs/pmd/copyright corrections 2015-09-19 08:20:58 -04:00
Jeremy Long
e04809f96b checkstyle/findbugs/pmd/copyright corrections 2015-09-19 08:20:14 -04:00
Jeremy Long
9203acff9c checkstyle/pmd/findbugs patches 2015-09-19 07:52:24 -04:00
Jeremy Long
afc1a9f077 removed unused settings 2015-09-18 06:53:30 -04:00
Jeremy Long
fc57851113 added options to disable analyzers 2015-09-18 06:52:36 -04:00
Jeremy Long
1f1d3f843f Merge branch 'colezlaw-composer-json' 2015-09-18 05:47:35 -04:00
Jeremy Long
b389260dec updated copyright 2015-09-18 05:47:06 -04:00
ma wei
1f37a5ff8f update the example command in README file 2015-09-17 17:17:41 +08:00
ma wei
815d60eca2 update README, fix typo which would lead to unable to apply this plugin 2015-09-17 17:15:42 +08:00
Dale Visser
877a584a26 Ruby Bundler: Disable Gemspec analysis if successful init. Moved to new analysis phase after init, before info collection. 2015-09-15 12:27:26 -04:00
Dale Visser
0c60c9ff75 Merge branch 'upmaster' into ruby-bundler 2015-09-15 11:59:59 -04:00
Will Stranathan
6a7a868b71 Initial checkin of ComposerLockAnalyzer 2015-09-14 22:14:00 -04:00
Jeremy Long
b5a070b228 Merge pull request #345 from hansjoachim/upgrades
Upgrade jmockit to 1.19
2015-09-14 19:29:15 -04:00
Dale Visser
39f13c6e5b Merge branch 'upmaster' into ruby-bundler 2015-09-14 17:14:20 -04:00
Jeremy Long
8c98da09f0 Merge pull request #355 from hansjoachim/warnings
Warnings
2015-09-13 19:31:16 -04:00
Jeremy Long
ed70a7200c Merge pull request #356 from awhitford/CompilerWarn
Enabled Compiler Lint Check and Deprecation Warnings
2015-09-13 19:28:26 -04:00
Anthony Whitford
ea4410cd16 Added missing serialVersionUID. 2015-09-13 10:57:54 -07:00
Anthony Whitford
9d9b1cbcd5 Replaced hashCode to leverage builder instead of deprecated ObjectUtils methods. 2015-09-13 10:55:02 -07:00
Anthony Whitford
f17d8f38fb Replaced equals and hashCode to leverage builders instead of deprecated ObjectUtils methods. 2015-09-13 10:48:03 -07:00
Anthony Whitford
0efc9d1cd2 Added missing serialVersionUID. 2015-09-13 10:34:19 -07:00
Anthony Whitford
4f5d5f1afd Added missing serialVersionUID. 2015-09-13 10:30:08 -07:00
Anthony Whitford
c4d8d7abf4 Removed redundant maven-compiler-plugin declaration. 2015-09-13 10:22:44 -07:00
Anthony Whitford
3fad29a709 Enabled lint check and deprecation warnings during compilation. 2015-09-13 10:22:25 -07:00
Hans Joachim Desserud
665f204c1f Code review: remove outcommented @Override annotation 2015-09-13 19:05:53 +02:00
Hans Joachim Desserud
362b651823 Unused imports 2015-09-13 17:06:44 +02:00
Hans Joachim Desserud
49b56588b8 Replace with foreach 2015-09-13 17:04:46 +02:00
Hans Joachim Desserud
c7a763ffdc Remove inheritance from Junit3 class and empty, unused methods 2015-09-13 17:01:32 +02:00
Hans Joachim Desserud
5435ddad9f Place array designator on the type 2015-09-13 16:46:14 +02:00
Hans Joachim Desserud
0ecd466c4c Add missing @Override annotations 2015-09-13 14:52:08 +02:00
Jeremy Long
6117e25b97 resolved merge 2015-09-13 07:49:25 -04:00
Jeremy Long
ee10f09bc6 Merge branch 'awhitford-StringB' 2015-09-13 07:47:11 -04:00
Jeremy Long
58512e302f resolved conflicts 2015-09-13 07:46:46 -04:00
Jeremy Long
ce564c209b removed deprecated/unused methods 2015-09-13 07:43:05 -04:00
Jeremy Long
7296d49693 Merge pull request #352 from awhitford/mpirp
Upgraded maven-project-info-reports-plugin from 2.8 to 2.8.1.
2015-09-13 07:41:01 -04:00
Jeremy Long
290fdc4c0f Merge pull request #350 from awhitford/AnalyzeIO
Replaced code with IOUtils.copy.

Thanks for the PR!
2015-09-13 07:40:41 -04:00
Jeremy Long
1fa5ae695d Merge pull request #349 from hansjoachim/warnings
Fixes various warnings
2015-09-13 07:37:25 -04:00
Jeremy Long
b2ba6d38b8 Merge branch 'hansjoachim-directoryscanner' 2015-09-13 07:29:56 -04:00
Jeremy Long
620f1b94bc added more false positive suppressions 2015-09-13 07:29:17 -04:00
Jeremy Long
c8fb5d1a9a excluded ant-launcher 2015-09-13 07:28:41 -04:00
Jeremy Long
1f763aeb72 Merge branch 'directoryscanner' of https://github.com/hansjoachim/DependencyCheck into hansjoachim-directoryscanner 2015-09-13 07:13:47 -04:00
Jeremy Long
fcfb019555 suppressed findbugs redundant null check 2015-09-13 07:03:55 -04:00
Jeremy Long
d4c1acb126 checkstyle fix - empty catch 2015-09-13 07:03:15 -04:00
Jeremy Long
862bf43685 suppressed checkstyle warnings 2015-09-13 07:02:41 -04:00
Jeremy Long
f83139a9ee fixed line length checkstyle finding 2015-09-13 07:02:13 -04:00
Jeremy Long
3d938b3edf added findbugs annotations to allow suppression 2015-09-13 07:01:28 -04:00
Jeremy Long
6c6ae66e36 added SuppressionCommentFilter so we can suppress individual findings 2015-09-13 07:01:10 -04:00
Jeremy Long
813e423bec added findbugs annotations to allow suppression 2015-09-13 07:00:27 -04:00
Anthony Whitford
a9a235fc87 Replaced StringBuffer with more efficient StringBuilder. 2015-09-12 19:53:44 -07:00
Anthony Whitford
6e1c6b4bed Replaced StringBuffer with more efficient StringBuilder. 2015-09-12 19:50:43 -07:00
Anthony Whitford
2214059a63 Upgraded maven-project-info-reports-plugin from 2.8 to 2.8.1. Also enabled cim report (since ci is being used). 2015-09-12 18:48:30 -07:00
Anthony Whitford
424cfcfa0c Added optional merge property support via a database dialect. Note that saveProperties was broken and unused, so removed. 2015-09-12 14:13:46 -07:00
Anthony Whitford
ce871dfa3e Replaced code with IOUtils.copy. 2015-09-12 10:55:33 -07:00
Hans Joachim Desserud
48a6eb1f86 Prefer interfaces over concerete classes. Did not change return type for public methods as this might potentially cause problems/need for changes for external users 2015-09-12 15:35:56 +02:00
Hans Joachim Desserud
fb85fb5b76 Ensure that we assert something. If the iterator doesn't have any values we would never enter the loop, but the test would still be green 2015-09-12 15:03:41 +02:00
Hans Joachim Desserud
c39c3cfdae Comment for review 2015-09-12 15:02:22 +02:00
Hans Joachim Desserud
e2fa7c666a Unused variable 2015-09-12 14:53:01 +02:00
Hans Joachim Desserud
f49cc6fb1f Unused methods in test 2015-09-12 14:51:49 +02:00
Hans Joachim Desserud
69bef59473 Remove superflous semicolon 2015-09-12 14:50:35 +02:00
Hans Joachim Desserud
9e931b9eb0 Remove modified copy of Apache Ant's DirectoryScanner 2015-09-12 14:14:54 +02:00
Hans Joachim Desserud
b26d9ea1e0 Replace use of included DirectoryScanner with Apache Ant's 2015-09-12 14:14:53 +02:00
Hans Joachim Desserud
ca5607d79e Removed empty methods from test 2015-09-12 14:14:08 +02:00
Hans Joachim Desserud
903eaed250 Remove unused imports 2015-09-12 14:06:47 +02:00
Jeremy Long
0859eab2dc corrected documentation 2015-09-12 06:59:19 -04:00
Jeremy Long
f0f84722ba removed unused import 2015-09-12 06:59:07 -04:00
Hans Joachim Desserud
17b8ba7069 Upgrade jmockit to 1.19 2015-09-12 12:40:01 +02:00
Jeremy Long
eb91152cfa updated the dependency-check-ant documentation 2015-09-11 06:53:58 -04:00
Jeremy Long
08c1b6879e changed scope on ant dependencies to provided 2015-09-11 06:15:59 -04:00
Jeremy Long
0077a8f67c removed link to usage.html as it was removed 2015-09-11 06:15:26 -04:00
Jeremy Long
a89cc67bd2 fixed hyperlink (usage->index) 2015-09-11 06:14:47 -04:00
Jeremy Long
388415ecc2 fixed hyperlink 2015-09-11 06:13:30 -04:00
Jeremy Long
44c5ba208d added documentation about unused code 2015-09-11 05:31:09 -04:00
Jeremy Long
d3a51857cb Merge pull request #344 from awhitford/DbOpts
Db opts
2015-09-11 05:25:16 -04:00
Anthony Whitford
11a3db5d64 Revert "Replaced update or insert property logic with merge property logic."
This reverts commit ece4a51b94.
2015-09-10 23:21:44 -07:00
Anthony Whitford
f3be8ae608 Merge remote-tracking branch 'jeremylong/master' into DbOpts 2015-09-10 23:17:46 -07:00
Jeremy Long
0577c9121c merge conflicts resolved 2015-09-10 06:47:38 -04:00
Jeremy Long
058f51e8c1 removed the shade plugin 2015-09-10 06:43:43 -04:00
Jeremy Long
698444caec changed the name of the data directory 2015-09-10 06:42:48 -04:00
Jeremy Long
d575df4b19 updated release to correctly bundle the zip 2015-09-10 06:42:25 -04:00
Jeremy Long
bee98513a2 cleaned up notices because additional notices are no longer added by shade 2015-09-10 06:41:48 -04:00
Anthony Whitford
3746df49ee Added type declarations. 2015-09-10 00:21:54 -07:00
Anthony Whitford
d98f67eab9 Added missing serialVersionUID. 2015-09-10 00:20:03 -07:00
Anthony Whitford
fde415e251 Added missing serialVersionUID. 2015-09-10 00:05:04 -07:00
Anthony Whitford
5702f39181 Addressed possible resource leak. 2015-09-09 23:54:20 -07:00
Anthony Whitford
45658afd89 Replaced empty string equals check with an isEmpty check. 2015-09-09 23:20:51 -07:00
Anthony Whitford
ece4a51b94 Replaced update or insert property logic with merge property logic. 2015-09-09 23:18:38 -07:00
Dale Visser
837d4918f2 Merge branch 'upmaster' into ruby-bundler. Fixed omission of --disableBundleAudit option.
Conflicts:
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java
2015-09-09 18:09:41 -04:00
Jeremy Long
57ae0f1676 resolved command line invocation of aggregate resulting in missing html report (#189) 2015-09-09 06:15:17 -04:00
Jeremy Long
48e644e007 removed un-needed call to log.isDebugEnabled() 2015-09-09 05:58:51 -04:00
Jeremy Long
49a04fa913 Merge branch 'awhitford-FluidoSkin14' 2015-09-08 06:43:06 -04:00
Jeremy Long
df943bcf75 Merge branch 'FluidoSkin14' of https://github.com/awhitford/DependencyCheck into awhitford-FluidoSkin14 2015-09-08 06:35:14 -04:00
Jeremy Long
fdbec176fa fixed logging statements to use slf4j format syntax instead of String.format syntax 2015-09-08 06:31:59 -04:00
Jeremy Long
4b2b4e5482 Merge pull request #343 from awhitford/CodeTweaks
Code tweaks
2015-09-08 06:20:18 -04:00
Anthony Whitford
96768d8529 Replaced Date manipulation with more efficient System call. 2015-09-08 01:01:13 -07:00
Anthony Whitford
2689a08026 Replaced Date manipulation with more efficient System call. 2015-09-07 17:50:02 -07:00
Anthony Whitford
54be70672e Replaced Date manipulation with more efficient System call. 2015-09-07 17:49:11 -07:00
Anthony Whitford
480fa50af5 Corrected Javadoc to eliminate warning. 2015-09-07 17:01:24 -07:00
Anthony Whitford
b51731d15f Added final keyword. 2015-09-07 16:35:23 -07:00
Anthony Whitford
c09650a136 Removed unused slf4j-ext and slf4j-jdk14 dependency declarations. 2015-09-07 16:30:58 -07:00
Anthony Whitford
769fcb20d8 Removed a now unused import. 2015-09-07 16:29:27 -07:00
Anthony Whitford
537c4b3a50 Added missing final keywords. 2015-09-07 16:28:55 -07:00
Anthony Whitford
a75c17ac5e Added final keywords and elaborated the javax.json imports. 2015-09-07 16:28:22 -07:00
Anthony Whitford
85604e8afa Logback-core is a transitive dependency from logback-classic -- no need to explicitly mention it. JSoup type is jar by default, so no need to mention that. SLF4J-Ext does not seem to be used, so can drop that. H2 only has runtime scope. 2015-09-07 16:01:10 -07:00
Anthony Whitford
9a45c9aa7c Removed unused Cal10n MessageConveyor. 2015-09-07 15:21:54 -07:00
Anthony Whitford
01450bacc2 Removed a redundant null check, and replaced an addAll with the constructor population. 2015-09-07 14:51:26 -07:00
Anthony Whitford
af0255ee09 Rather than create a collection, then call addAll to populate, the collection can be created with the collection to clone. 2015-09-07 14:48:23 -07:00
Anthony Whitford
df25bbb6d2 Replaced json iteration with more efficient entrySet. Also corrected an invalid logging statement. 2015-09-07 14:43:34 -07:00
Anthony Whitford
444685bc05 Inner class should be static (since it doesn't reference parent). 2015-09-07 14:40:32 -07:00
Anthony Whitford
115f63c330 Removed an unused import and combined nested if statements. 2015-09-07 14:38:43 -07:00
Anthony Whitford
f9dbc4f7bf Upgraded Fluido Skin to 1.4 (from 1.3.1). 2015-09-07 10:54:01 -07:00
Jeremy Long
83263f8dee Update README.md
added build badge
2015-09-07 07:43:33 -04:00
Jeremy Long
a452ade957 Merge pull request #339 from awhitford/DependencyUpgrades
Upgraded dependencies.
2015-09-07 07:36:47 -04:00
Jeremy Long
1f48af024e Merge pull request #338 from awhitford/PomCleanup
Pom cleanup
2015-09-07 07:34:07 -04:00
Jeremy Long
0a643d7195 Merge pull request #340 from awhitford/CommonsLang3
Upgraded commons-lang-2.6 to newer commons-lang3-3.4.
2015-09-07 07:30:52 -04:00
Jeremy Long
c3835b9da7 removed erroneous short cli argument for exclude 2015-09-07 07:27:39 -04:00
Jeremy Long
bb1a96cf7a Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-09-07 07:25:36 -04:00
Jeremy Long
56360301d7 changed debug message to an error 2015-09-07 07:25:29 -04:00
Jeremy Long
435cccdeae Merge pull request #341 from awhitford/CommonsCli131
Upgraded commons-cli to 1.3.1 (from 1.2).
2015-09-07 07:24:48 -04:00
Anthony Whitford
b11b472933 Upgraded commons-cli to 1.3.1 (from 1.2). See http://commons.apache.org/proper/commons-cli/release_1_3.html for upgrade details. 2015-09-07 02:27:10 -07:00
Anthony Whitford
514f8398e2 Upgraded commons-lang-2.6 to newer commons-lang3-3.4. 2015-09-07 01:09:41 -07:00
Anthony Whitford
90935fef25 Upgraded dependencies. 2015-09-07 00:40:30 -07:00
Anthony Whitford
9b5ce1c3a6 Upgraded shade plugin to 2.4.1 (from 2.3). 2015-09-06 23:20:15 -07:00
Anthony Whitford
8ad1639b02 License is inherited from Parent POM -- no need to restate unless it is different. 2015-09-06 22:30:01 -07:00
Anthony Whitford
6d70332cd6 Centralized the Versions report to the parent pom. 2015-09-06 22:21:50 -07:00
Anthony Whitford
717f6240e3 Centralized javadoc reporting to parent pom. 2015-09-06 20:51:56 -07:00
Anthony Whitford
ab782054a1 Missed this lingering redundant maven-project-info-reports-plugin declaration. 2015-09-06 13:37:04 -07:00
Anthony Whitford
b481f01217 Moved the maven-plugin-plugin declarations into the maven module since it is unique to that module. 2015-09-06 13:05:17 -07:00
Anthony Whitford
d0f884f5b2 Centralized the maven-surefire-report-plugin to the parent pom. Note that gradle and jenkins modules are skipped since it does not apply. 2015-09-06 12:56:36 -07:00
Anthony Whitford
51e66354b0 No need to explicitly add a jar goal when it implicitly exists already for a jar module. 2015-09-06 11:18:56 -07:00
Jeremy Long
1efe90f445 Merge pull request #337 from awhitford/Checkstyle
Thanks again!
2015-09-06 06:12:19 -04:00
Anthony Whitford
7b47b7549d Removed redundant declarations for maven-compiler-plugin and maven-jar-plugin. 2015-09-06 01:42:01 -07:00
Anthony Whitford
7ccb77fb57 Removed unnecessary property for findbugs-maven-plugin since it is now only declared once. 2015-09-06 01:32:00 -07:00
Anthony Whitford
a32fa69823 Moved taglist-maven-plugin to the parent pom. (Gradle and Jenkins modules don't have them -- before or after.) This will make it easier to manage and evolve. 2015-09-06 01:29:17 -07:00
Anthony Whitford
ece4cb03ad project.build.sourceEncoding is already specified in the parent pom, so this is not necessary. 2015-09-06 00:53:53 -07:00
Anthony Whitford
5c53b6528f Centralized the findbugs-maven-plugin to the parent pom. Gradle and Jenkins modules skip it naturally. The onlyAnlyze setting for utils is maintained via a property. Also was able to upgrade to latest plugin, version 3.0.2. 2015-09-06 00:51:28 -07:00
Anthony Whitford
9b92007eff Centralized cobertura plugin to the parent pom and was able to upgrade it from 2.6 to 2.7. 2015-09-06 00:23:24 -07:00
Anthony Whitford
e433809f4d Moved maven-jxr-plugin and maven-project-info-reports-plugin reporting declarations into the parent pom. No need to duplicate in child modules. Utils did not have project-info reports, but there does not seem to be a good reason. Also note that the JXR plugin is naturally skipped when it does not apply (there is no java code), so not necessary to explicitly skip it for gradle and jenkins modules. 2015-09-05 23:57:53 -07:00
Anthony Whitford
d74218004a Reporting section for jenkins module is completely redundant with the parent pom. It can be removed and will generate the same report. 2015-09-05 23:17:28 -07:00
Anthony Whitford
c35276e3df Reporting section for gradle module is completely redundant with the parent pom. It can be removed and will generate the same report. 2015-09-05 23:15:35 -07:00
Anthony Whitford
064236ed5b Added Dependency plugin to Reporting section because it has an excellent Dependency Analysis Report. 2015-09-05 22:56:36 -07:00
Anthony Whitford
2a50dcba9d Removed Checkstyle and PMD violations. 2015-09-05 22:25:59 -07:00
Anthony Whitford
f7974b324b Exclude generated HelpMojo.java file from Checkstyle analysis. 2015-09-05 22:25:38 -07:00
Jeremy Long
3bb716b060 Merge pull request #336 from awhitford/Timing
Added time measurements for key steps.
2015-09-05 21:08:05 -04:00
Jeremy Long
39e465261f Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-09-05 21:07:47 -04:00
Jeremy Long
784b78b17c added another timer to pull #336 2015-09-05 21:07:29 -04:00
Jeremy Long
22c68ed8ef Merge pull request #331 from wmaintw/master
add compatibility supports
2015-09-05 21:00:15 -04:00
Jeremy Long
c4c670a3b1 Merge pull request #334 from awhitford/MavenPluginWarnings
Removed deprecated code.
2015-09-05 20:59:05 -04:00
Jeremy Long
17a05cc1d4 removed excessive logging used to debug 2015-09-05 20:56:54 -04:00
Jeremy Long
d452c5fabb fixed shift operator per issue #335 2015-09-05 20:56:18 -04:00
Jeremy Long
2cf974ef02 maven-reporting-api cannot be scoped to provided 2015-09-05 07:09:01 -04:00
Jeremy Long
1f0e789575 fixed bug that might contribute to issue #189 2015-09-05 06:48:00 -04:00
Anthony Whitford
92e1fd3f28 Added time measurements for key steps. 2015-09-05 00:31:50 -07:00
Jeremy Long
49736a87aa Merge branch 'awhitford-FixSite' 2015-09-03 05:32:06 -04:00
Anthony Whitford
d009e39842 Removed unnecessary maven-site-plugin dependency, and maven-plugin-annotations dependency is provided. 2015-09-03 01:47:46 -07:00
Anthony Whitford
c2b8901537 Removed deprecated code. 2015-09-03 01:25:53 -07:00
Anthony Whitford
dd910cb5ec Updated plugins. 2015-09-03 00:48:06 -07:00
Jeremy Long
4632753f02 commented out initial attempt at issue #22 to resolve issue #327 2015-09-02 06:42:36 -04:00
Jeremy Long
3fdcd12b4f maven dependencies should be marked as provided per issue #329 2015-09-02 06:05:56 -04:00
ma wei
94d1d611c7 add compatibility supports 2015-09-02 13:45:06 +08:00
Jeremy Long
27b54a0bfa changed taskdef.properties file name 2015-09-01 06:37:44 -04:00
Jeremy Long
1b1ecd0748 split monolithic taskdef into three primary taskdefs 2015-08-31 06:59:57 -04:00
Dale Visser
1e29d2e751 Merge branch 'upmaster' into ruby-bundler
Conflicts:
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java
2015-08-30 15:11:33 -04:00
Dale Visser
a0437bf933 Ruby bunder: Code needed to disable the analyzer in the CLI if desired. 2015-08-30 15:07:21 -04:00
Dale Visser
73e0292a4b Ruby Bundler: Added informative message about updating DB. Switched most log messages to debug level. 2015-08-30 14:52:55 -04:00
Dale Visser
c393e74160 Ruby bundler: Better message and logging when bundle-audit not found. 2015-08-30 14:31:58 -04:00
Dale Visser
80c4666198 Ruby bundler: More method extractions to eliminate monolithic method. 2015-08-30 14:16:32 -04:00
Dale Visser
ea7bd1f700 Ruby bundler: tidied up how extracted method is used. 2015-08-30 14:06:47 -04:00
Dale Visser
b3a55cc85d Ruby bundler: extracted method 2015-08-30 13:57:30 -04:00
Dale Visser
036200350d Ruby bundler: add needed null checks to avoid NPEs. 2015-08-30 13:50:22 -04:00
Jeremy Long
e630c484ff implementing the purge feature as requested in issue #328 2015-08-30 07:02:26 -04:00
Dale Visser
713e9658c5 Ruby bundler: got description working. Added boilerplate text describing differences from standard D-C vulnerability report. 2015-08-29 12:29:44 -04:00
Dale Visser
782039810e Ruby Bundler: Added URL to report. 2015-08-29 11:33:16 -04:00
Dale Visser
b473d8ab9c Ruby Bundler: Added URL to report. 2015-08-29 11:28:38 -04:00
Dale Visser
2eb6918fb3 Ruby Bundler: Clean up report a little bit, and grouped vulnerabilities under dependencies, when appropriate. 2015-08-29 11:06:24 -04:00
Jeremy Long
29626666a7 removed debug logging 2015-08-29 08:38:49 -04:00
Jeremy Long
dc41c9a671 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-08-29 08:02:42 -04:00
Jeremy Long
83af70bb59 corrected argument name for the purge nvd option 2015-08-29 07:57:54 -04:00
Jeremy Long
b293873640 finished deprecating the application name argument in favor of project name per issue #320 2015-08-29 07:12:40 -04:00
Jeremy Long
8bb92815cb added argument to purge local NVD per issue #328 2015-08-29 06:58:13 -04:00
Jeremy Long
7a8f7199c8 renaming app argument to project per issue #320 2015-08-29 06:48:52 -04:00
Dale Visser
6f4ce34840 Ruby Bundler: Added CVSS score and a little hack to avoid dependency bundling. 2015-08-28 21:31:01 -04:00
Dale Visser
8853552161 Ruby Bundler: Successfully adding vulnerability into report, though all displayed info not looking great. 2015-08-28 19:56:35 -04:00
Dale Visser
95d3d17d83 Ruby Bundler: Now successfully creating temp files for dependency objects. 2015-08-28 13:58:49 -04:00
Jeremy Long
3594280b04 Merge pull request #326 from dwvisser/doc-updates
Added previously overlooked documentation for CMake, Node.js and Ruby Gems Analyzers
2015-08-28 06:12:54 -04:00
Jeremy Long
1e447c6e3e Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-08-28 05:27:16 -04:00
Jeremy Long
c41a288280 added null checks 2015-08-28 05:27:00 -04:00
Dale Visser
a0492fe944 Merge branch 'upmaster' into ruby-bundler
Conflicts:
	dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
2015-08-27 14:05:36 -04:00
Dale Visser
1fffebd497 Docs: Added Ruby Gemspec analyzer page, fixed typos on Node.js page. 2015-08-26 14:40:36 -04:00
Dale Visser
62c05049a7 Docs: Added node.js page, fixed typos in Python page. 2015-08-26 14:25:32 -04:00
Dale Visser
0fdf377d45 Docs: Added CMake analyzer page. 2015-08-26 14:11:30 -04:00
Dale Visser
6ca8e2644a Docs: Fixed sidebar links to OpenSSL and Python analyzer pages. 2015-08-26 13:59:28 -04:00
Dale Visser
4a3061db6d Docs: Added CMake to landing page, and links to Autoconf and CMake. Added missing analyzers to analyzers list. Shortened my analyzer URLs, though not all in site index yet. 2015-08-26 13:54:15 -04:00
Dale Visser
61ac81518a Docs: Added Ruby and Node.js to landing page. Added table row for Node.js in Analyzers list. 2015-08-26 12:27:38 -04:00
Jeremy Long
acd4b4371d Merge pull request #323 from wmaintw/master
Implement the nested configuration for proxy and cve related settings
2015-08-26 06:05:38 -04:00
Jeremy Long
1d20291d44 Merge branch 'dwvisser-node-js-analyzer' 2015-08-26 06:03:32 -04:00
Dale Visser
c60245ea2b Node.js Analyzer: Switched from org.json to Glassfish JSR 353 reference implementation. 2015-08-25 17:28:17 -04:00
Dale Visser
9e25480baa Merge branch 'upmaster' into node-js-analyzer
Conflicts:
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java
	dependency-check-cli/src/site/markdown/arguments.md
	dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
2015-08-25 13:03:12 -04:00
ma wei
facd803943 update README file 2015-08-25 23:17:12 +08:00
ma wei
05c8a6282d upgrade to 0.0.7 2015-08-25 23:06:34 +08:00
ma wei
3f9ae34203 refactor: change method name for override settings 2015-08-25 19:50:50 +08:00
ma wei
afb85309a2 implement nested configuration for CVE settings 2015-08-25 19:49:03 +08:00
ma wei
2c5e64d0d5 update README for configuration change 2015-08-25 19:17:55 +08:00
ma wei
ddb8c432be implement the nested configuration for proxy settings 2015-08-25 19:11:27 +08:00
Jeremy Long
054be314f6 added targetCompatibility = 1.7 per issue #321 2015-08-25 06:13:29 -04:00
Jeremy Long
e484c5754e Merge pull request #312 from dwvisser/rubygems-analyzer-pr
Rubygems analyzer
2015-08-25 05:31:10 -04:00
Jeremy Long
b36c4f65e5 Merge pull request #322 from wmaintw/master
Remove duplicated configuration items in DependencyCheckTask
2015-08-25 05:28:34 -04:00
Jeremy Long
4bdfbcc916 Merge pull request #316 from dwvisser/iso-scanning
Help for scanning ISO images on Linux, Mac OS X, and Windows
2015-08-25 05:27:10 -04:00
ma wei
519198bb61 Merge remote-tracking branch 'upstream/master' 2015-08-24 22:29:28 +08:00
ma wei
9a7c342f91 modify spec for testing project extension 2015-08-24 22:25:03 +08:00
ma wei
761a5ed3dd remove duplicated configuration items in DependencyCheckTask 2015-08-24 22:17:16 +08:00
Jeremy Long
481e753ad4 corrected spring-security false positives per issue #319 and #311 2015-08-23 06:45:35 -04:00
Dale Visser
271016f0fa Added verbose flag to get as much reportable info as possible. 2015-08-19 15:33:50 -04:00
Dale Visser
4493f895c6 Added test resources to cover interesting bundle-audit cases. 2015-08-19 15:26:17 -04:00
Dale Visser
5c32ecd8e1 Ruby Analyzer: Added bundle-audit analyzer. So far just launches if available and logs the output. 2015-08-18 16:59:39 -04:00
Dale Visser
0b5244d321 Markdown escape * character fix 2015-08-18 12:37:09 -04:00
Jeremy Long
b6f9715174 Merge pull request #318 from dwvisser/code-inspection-fixes
Random fixes to issues found by IntelliJ IDEA code inspection.
2015-08-17 19:46:41 -04:00
Dale Visser
2db1f8d2b6 Random fixes to issues found by IntelliJ IDEA code inspection. 2015-08-17 18:55:51 -04:00
Dale Visser
4c5957ae40 ISO scanning: Fixed slight errors in Python file types, and made formatting consistent. 2015-08-17 14:49:24 -04:00
Dale Visser
38cd19de15 ISO scanning: Added clarification on what can be scanned. Fleshed out file type analyzers page with details. Re-ordered side menu alphabetically to match. 2015-08-17 12:16:45 -04:00
Jeremy Long
f66ffbdd63 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-08-16 06:25:02 -04:00
Jeremy Long
8d3f08e529 fixed links 2015-08-16 06:24:08 -04:00
Jeremy Long
4209c1c406 Merge pull request #315 from recena/master
Fixed links
2015-08-16 06:17:24 -04:00
Dale Visser
1cd12d0a0c Documentation giving help for scanning ISO images on Linux, Mac OS X, and Windows. 2015-08-14 13:51:38 -04:00
Manuel Recena
7eb18e1931 Fixed links 2015-08-14 12:33:47 +02:00
ma wei
d308e50e1e remove duplicated plugin properties file 2015-08-14 17:12:28 +08:00
Dale Visser
88569cb369 rubygems: Finished command-line interface integration. 2015-08-12 12:08:05 -04:00
Dale Visser
235869fc79 rubygems: Reformat and consisitent parameter naming in private methods. 2015-08-12 12:08:05 -04:00
Dale Visser
89166e81fb rubygems: Add summary to evidence, inline constants that were only being used once. 2015-08-12 12:08:05 -04:00
Dale Visser
2d109b81cf rubygems: Used substring(int) to remove the need for Matcher.find(int).
Also fixed javadoc, made some variables final, shortened a variable name.
2015-08-12 12:06:18 -04:00
Dale Visser
5c02b4dccb rubygems: Added new analyzer to META-INF/services. Confirmed correlation with CPE in CLI. 2015-08-12 12:06:18 -04:00
Dale Visser
e7f154b58d rubygems: Various refactoring improvements. 2015-08-12 12:00:56 -04:00
Dale Visser
c0752575c6 rubygems: All evidence assertions now passing. 2015-08-12 12:00:43 -04:00
Dale Visser
7eb2c89f39 rugygems: Added gemspec test resources, test cases, and minimal code to run tests and have evidence gathering test fail. 2015-08-12 11:58:46 -04:00
Dale Visser
bf4eb07342 Node.js: Added missing command-line option for disableing Node.js analyzer. 2015-08-11 15:27:20 -04:00
Jeremy Long
c856d01b52 removed un-needed dependencies 2015-08-09 16:05:14 -04:00
Dale Visser
7a535b2576 node.js: Added parent folder to display file name. Added try-catch for JSONException, logging warning message in that case. 2015-08-09 11:32:57 -04:00
Dale Visser
4b17fd88a3 node.js: Adding name_project to vendor evidence, as many node.js projects seem to follow this pattern with their CPEs. Also, logging warnings whenever JSON parse doesn't go as expected. 2015-08-09 11:18:16 -04:00
Jeremy Long
8d1f3f723f version 1.3.1-SNAPSHOT 2015-08-09 10:25:44 -04:00
Jeremy Long
a543fbbec9 added an additional attempt to remove the temporary directory 2015-08-09 10:25:30 -04:00
Jeremy Long
37f50db00e removed related dependencies from hashCode and equals to resolve issue #293 2015-08-09 09:56:20 -04:00
Jeremy Long
ccb87f43b7 made suppression notes textarea readonly to resolve issue #306 2015-08-09 09:36:55 -04:00
Jeremy Long
d569f39f53 Merge branch 'master' of github.com:jeremylong/DependencyCheck 2015-08-09 09:10:32 -04:00
Jeremy Long
fb3951772f fixed errors due to null values per issue #309 2015-08-09 09:10:18 -04:00
Jeremy Long
2c00bf4040 Merge pull request #305 from wmaintw/master
[new pull request] Implement configuration item "quickQueryTimpstamp" in grade plugin
2015-08-07 18:26:03 -04:00
Dale Visser
4f8772bd77 node.js: Added parameter to cli. 2015-08-07 16:10:56 -04:00
Dale Visser
b4c3046ab5 node.js: Added package.json eveidence gathering, using json.org package for the parsing. 2015-08-07 15:41:01 -04:00
Dale Visser
2441b92bc6 node.js: Initial commit, with analysis test failing. 2015-08-07 14:43:08 -04:00
ma wei
c39eec32f2 ignore gradle generated temporary files 2015-08-07 10:14:34 +08:00
ma wei
7837718d04 update README file 2015-08-07 10:13:53 +08:00
ma wei
7069671471 fix issue that fail to publish gradle plugin to gradle plugin portal 2015-08-07 10:13:27 +08:00
ma wei
d1dbde2890 fix issue that fail to publish gradle plugin to maven central 2015-08-07 10:13:00 +08:00
ma wei
0472471ac9 update the gradle plugin version to 0.0.6 2015-08-07 10:11:34 +08:00
ma wei
62a0b8da90 add configuration, let user has ability to control HTTP method used during the update process to avoid proxy problem 2015-08-07 10:09:40 +08:00
ma wei
810530fabd upgrade dependency check core and utils version to 1.3.0 2015-08-07 10:08:37 +08:00
Jeremy Long
707de56612 Merge pull request #302 from dwvisser/290-add-bz2-format
Add bzip2 format to ArchiveAnalyzer
2015-08-06 07:02:21 -04:00
Jeremy Long
921b0eb229 Merge pull request #301 from dwvisser/run-against-cached-db-pr
Help page for how to use multiple local snapshots of the NVD
2015-08-05 22:54:33 -04:00
Jeremy Long
9afb92f0ed Merge pull request #303 from colezlaw/homebrew-cli-instructions
Added homebrew installation instructions
2015-08-05 22:52:36 -04:00
Will Stranathan
1ded88e089 Added homebrew installation instructions 2015-08-05 20:58:20 -04:00
Dale Visser
1f074ff400 290: Further refactoring for readability. 2015-08-05 17:42:25 -04:00
Dale Visser
4764f61b48 290: Added unit tests and implementation to support bzip2. 2015-08-05 17:42:10 -04:00
Dale Visser
56424924bb 290: Extracted some methods to reduce average method size, and eliminate some duplicate code. 2015-08-05 17:42:10 -04:00
Dale Visser
4c3831ec74 Removed superfluous phrase. 2015-08-05 12:03:21 -04:00
Dale Visser
ba564a6aed Added page to site that documents how to take daily snapshots of the NVD,
and run D-C cli against those snapshots.
2015-08-05 11:57:23 -04:00
321 changed files with 11657 additions and 14288 deletions

View File

@@ -1,3 +1,4 @@
[![Build Status](https://dependency-check.ci.cloudbees.com/buildStatus/icon?job=dependency-check)](https://dependency-check.ci.cloudbees.com/job/dependency-check/)
Dependency-Check
================
@@ -9,7 +10,7 @@ Current Releases
-------------
### Jenkins Plugin
For instructions on the use of the Jenkins plugin please see the [Jenkins dependency-check page](http://wiki.jenkins-ci.org/x/CwDgAQ).
For instructions on the use of the Jenkins plugin please see the [OWASP Dependency-Check Plugin page](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).
### Command Line
@@ -37,7 +38,7 @@ $ dependency-check --app Testing --out . --scan [path to jar files to be scanned
### Maven Plugin
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/usage.html).
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven).
The plugin can be configured using the following:
```xml
@@ -66,7 +67,7 @@ The plugin can be configured using the following:
### Ant Task
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html).
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant).
Development Usage
-------------
@@ -109,7 +110,7 @@ Copyright & License
Dependency-Check is Copyright (c) 2012-2015 Jeremy Long. All Rights Reserved.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/LICENSE.txt) file for the full license.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt] [notices] file for more information.

View File

@@ -1,9 +1,6 @@
-----------------------------
---begin dependency-check----
-----------------------------
dependency-check
OWASP dependency-check
Copyright (c) 2012-2013 Jeremy Long. All Rights Reserved.
Copyright (c) 2012-2015 Jeremy Long. All Rights Reserved.
The licenses for the software listed below can be found in the META-INF/licenses/[dependency name].
@@ -19,11 +16,3 @@ An original copy of the license agreement can be found at: http://www.h2database
This product includes data from the Common Weakness Enumeration (CWE): http://cwe.mitre.org/
This product downloads and utilizes data from the National Vulnerability Database hosted by NIST: http://nvd.nist.gov/download.cfm
-----------------------------
---end dependency-check------
-----------------------------
Notices below are from dependent libraries and have been included via maven-shade-plugin.
-----------------------------

View File

@@ -1,25 +1,134 @@
Dependency-Check Ant Task
Dependency-Check-Gradle
=========
Dependency-Check Ant Task can be used to check the project dependencies for published security vulnerabilities. The checks
performed are a "best effort" and as such, there could be false positives as well as false negatives. However,
vulnerabilities in 3rd party components is a well-known problem and is currently documented in the 2013 OWASP
Top 10 as [A9 - Using Components with Known Vulnerabilities](https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities).
**Working in progress**
Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html).
This is a DependencyCheck gradle plugin designed for project which use Gradle as build script.
Mailing List
------------
Dependency-Check is a utility that attempts to detect publicly disclosed vulnerabilities contained within project dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.
Subscribe: [dependency-check+subscribe@googlegroups.com](mailto:dependency-check+subscribe@googlegroups.com)
=========
Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.com)
## What's New
Current latest version is `0.0.8`
Copyright & License
-------------------
## Usage
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
### Step 1, Apply dependency check gradle plugin
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/LICENSE.txt) file for the full license.
Install from Maven central repo
Dependency-Check-Ant makes use of other open source libraries. Please see the [NOTICE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-ant/blob/master/NOTICES.txt) file for more information.
```groovy
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.owasp:dependency-check-gradle:1.3.2'
}
}
apply plugin: 'dependency-check-gradle'
```
### Step 2, Run gradle task
Once gradle plugin applied, run following gradle task to check dependencies:
```
gradle dependencyCheck --info
```
The reports will be generated automatically under `./reports` folder.
If your project includes multiple sub-projects, the report will be generated for each sub-project in different sub-directory.
## FAQ
> **Questions List:**
> - What if I'm behind a proxy?
> - What if my project includes multiple sub-project? How can I use this plugin for each of them including the root project?
> - How to customize the report directory?
### What if I'm behind a proxy?
Maybe you have to use proxy to access internet, in this case, you could configure proxy settings for this plugin:
```groovy
dependencyCheck {
proxy {
server = "127.0.0.1" // required, the server name or IP address of the proxy
port = 3128 // required, the port number of the proxy
// optional, the proxy server might require username
// username = "username"
// optional, the proxy server might require password
// password = "password"
}
}
```
In addition, if the proxy only allow HTTP `GET` or `POST` methods, you will find that the update process will always fail,
the root cause is that every time you run `dependencyCheck` task, it will try to query the latest timestamp to determine whether need to perform an update action,
and for performance reason the HTTP method it uses by default is `HEAD`, which probably is disabled or not supported by the proxy. To avoid this problem, you can simply change the HTTP method by below configuration:
```groovy
dependencyCheck {
quickQueryTimestamp = false // when set to false, it means use HTTP GET method to query timestamp. (default value is true)
}
```
### What if my project includes multiple sub-project? How can I use this plugin for each of them including the root project?
Try put 'apply plugin: "dependency-check"' inside the 'allprojects' or 'subprojects' if you'd like to check all sub-projects only, see below:
(1) For all projects including root project:
```groovy
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.8"
}
}
allprojects {
apply plugin: "dependency-check"
}
```
(2) For all sub-projects:
```groovy
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.8"
}
}
subprojects {
apply plugin: "dependency-check"
}
```
In this way, the dependency check will be executed for all projects (including root project) or just sub projects.
### How to customize the report directory?
By default, all reports will be placed under `./reports` folder, to change the default directory, just modify it in the configuration section like this:
```groovy
subprojects {
apply plugin: "dependency-check"
dependencyCheck {
outputDirectory = "./customized-path/security-report"
}
}
```

View File

@@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.2</version>
</parent>
<artifactId>dependency-check-ant</artifactId>
@@ -190,38 +190,36 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/NOTICE.txt</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>META-INF/NOTICE</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>META-INF/LICENSE</resource>
</transformer>
</transformers>
<attach>false</attach> <!-- don't install/deploy this archive -->
</configuration>
<executions>
<execution>
<id>create-distribution</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/release.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
@@ -229,9 +227,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<!--instrumentation>
<ignoreTrivial>true</ignoreTrivial>
</instrumentation-->
<check>
<branchRate>85</branchRate>
<lineRate>85</lineRate>
@@ -273,96 +268,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${reporting.project-info-reports-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>summary</report>
<report>license</report>
<report>help</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${reporting.javadoc-plugin.version}</version>
<configuration>
<failOnError>false</failOnError>
<bottom>Copyright© 2012-15 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${reporting.versions-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>dependency-updates-report</report>
<report>plugin-updates-report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>${reporting.jxr-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${reporting.cobertura-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${reporting.surefire-report-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>report-only</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
<version>${reporting.taglist-plugin.version}</version>
<configuration>
<tagListOptions>
<tagClasses>
<tagClass>
<displayName>Todo Work</displayName>
<tags>
<tag>
<matchString>todo</matchString>
<matchType>ignoreCase</matchType>
</tag>
<tag>
<matchString>FIXME</matchString>
<matchType>exact</matchType>
</tag>
</tags>
</tagClass>
</tagClasses>
</tagListOptions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
@@ -395,11 +300,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
</rulesets>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${reporting.findbugs-plugin.version}</version>
</plugin>
</plugins>
</reporting>
<dependencies>
@@ -423,6 +323,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>

View File

@@ -12,18 +12,25 @@
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!--fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<outputDirectory>dependency-check</outputDirectory>
<directory>${project.build.directory}</directory>
<includes>
<include>dependency-check*.jar</include>
</includes>
</fileSet>
</fileSets>
</fileSets-->
<files>
<file>
<source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source>
<outputDirectory>dependency-check-ant</outputDirectory>
<destName>dependency-check-ant.jar</destName>
</file>
</files>
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<outputDirectory>dependency-check-ant/lib</outputDirectory>
<scope>runtime</scope>
</dependencySet>
</dependencySets>

View File

@@ -24,7 +24,7 @@ import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter;
/**
* An instance of {@link org.slf4j.Logger} which simply calls the log method on the delegate Ant task
* An instance of {@link org.slf4j.Logger} which simply calls the log method on the delegate Ant task.
*
* @author colezlaw
*/
@@ -63,7 +63,9 @@ public class AntLoggerAdapter extends MarkerIgnoringBase {
@Override
public void trace(String msg) {
task.log(msg, Project.MSG_VERBOSE);
if (task != null) {
task.log(msg, Project.MSG_VERBOSE);
}
}
@Override

View File

@@ -0,0 +1,127 @@
/*
* This file is part of dependency-check-ant.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.taskdefs;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.impl.StaticLoggerBinder;
/**
* An Ant task definition to execute dependency-check during an Ant build.
*
* @author Jeremy Long
*/
public class Purge extends Task {
/**
* The properties file location.
*/
private static final String PROPERTIES_FILE = "task.properties";
/**
* Construct a new DependencyCheckTask.
*/
public Purge() {
super();
// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
// core end up coming through this tasks logger
StaticLoggerBinder.getSingleton().setTask(this);
}
/**
* The location of the data directory that contains
*/
private String dataDirectory = null;
/**
* Get the value of dataDirectory.
*
* @return the value of dataDirectory
*/
public String getDataDirectory() {
return dataDirectory;
}
/**
* Set the value of dataDirectory.
*
* @param dataDirectory new value of dataDirectory
*/
public void setDataDirectory(String dataDirectory) {
this.dataDirectory = dataDirectory;
}
@Override
public void execute() throws BuildException {
populateSettings();
File db;
try {
db = new File(Settings.getDataDirectory(), "dc.h2.db");
if (db.exists()) {
if (db.delete()) {
log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
} else {
log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR);
}
} else {
log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR);
}
} catch (IOException ex) {
log("Unable to delete the database", Project.MSG_ERR);
} finally {
Settings.cleanup(true);
}
}
/**
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
* required to change the proxy server, port, and connection timeout.
*/
protected void populateSettings() {
Settings.initialize();
InputStream taskProperties = null;
try {
taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
Settings.mergeProperties(taskProperties);
} catch (IOException ex) {
log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN);
} finally {
if (taskProperties != null) {
try {
taskProperties.close();
} catch (IOException ex) {
log("", ex, Project.MSG_DEBUG);
}
}
}
if (dataDirectory != null) {
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
} else {
final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
final File base = jarPath.getParentFile();
final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
final File dataDir = new File(base, sub);
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
}
}
}

View File

@@ -0,0 +1,437 @@
/*
* This file is part of dependency-check-ant.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.taskdefs;
import org.apache.tools.ant.BuildException;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.impl.StaticLoggerBinder;
/**
* An Ant task definition to execute dependency-check update. This will download the latest data from the National Vulnerability
* Database (NVD) and store a copy in the local database.
*
* @author Jeremy Long
*/
public class Update extends Purge {
/**
* Construct a new UpdateTask.
*/
public Update() {
super();
// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
// core end up coming through this tasks logger
StaticLoggerBinder.getSingleton().setTask(this);
}
/**
* The Proxy Server.
*/
private String proxyServer;
/**
* Get the value of proxyServer.
*
* @return the value of proxyServer
*/
public String getProxyServer() {
return proxyServer;
}
/**
* Set the value of proxyServer.
*
* @param server new value of proxyServer
*/
public void setProxyServer(String server) {
this.proxyServer = server;
}
/**
* The Proxy Port.
*/
private String proxyPort;
/**
* Get the value of proxyPort.
*
* @return the value of proxyPort
*/
public String getProxyPort() {
return proxyPort;
}
/**
* Set the value of proxyPort.
*
* @param proxyPort new value of proxyPort
*/
public void setProxyPort(String proxyPort) {
this.proxyPort = proxyPort;
}
/**
* The Proxy username.
*/
private String proxyUsername;
/**
* Get the value of proxyUsername.
*
* @return the value of proxyUsername
*/
public String getProxyUsername() {
return proxyUsername;
}
/**
* Set the value of proxyUsername.
*
* @param proxyUsername new value of proxyUsername
*/
public void setProxyUsername(String proxyUsername) {
this.proxyUsername = proxyUsername;
}
/**
* The Proxy password.
*/
private String proxyPassword;
/**
* Get the value of proxyPassword.
*
* @return the value of proxyPassword
*/
public String getProxyPassword() {
return proxyPassword;
}
/**
* Set the value of proxyPassword.
*
* @param proxyPassword new value of proxyPassword
*/
public void setProxyPassword(String proxyPassword) {
this.proxyPassword = proxyPassword;
}
/**
* The Connection Timeout.
*/
private String connectionTimeout;
/**
* Get the value of connectionTimeout.
*
* @return the value of connectionTimeout
*/
public String getConnectionTimeout() {
return connectionTimeout;
}
/**
* Set the value of connectionTimeout.
*
* @param connectionTimeout new value of connectionTimeout
*/
public void setConnectionTimeout(String connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
/**
* The database driver name; such as org.h2.Driver.
*/
private String databaseDriverName;
/**
* Get the value of databaseDriverName.
*
* @return the value of databaseDriverName
*/
public String getDatabaseDriverName() {
return databaseDriverName;
}
/**
* Set the value of databaseDriverName.
*
* @param databaseDriverName new value of databaseDriverName
*/
public void setDatabaseDriverName(String databaseDriverName) {
this.databaseDriverName = databaseDriverName;
}
/**
* The path to the database driver JAR file if it is not on the class path.
*/
private String databaseDriverPath;
/**
* Get the value of databaseDriverPath.
*
* @return the value of databaseDriverPath
*/
public String getDatabaseDriverPath() {
return databaseDriverPath;
}
/**
* Set the value of databaseDriverPath.
*
* @param databaseDriverPath new value of databaseDriverPath
*/
public void setDatabaseDriverPath(String databaseDriverPath) {
this.databaseDriverPath = databaseDriverPath;
}
/**
* The database connection string.
*/
private String connectionString;
/**
* Get the value of connectionString.
*
* @return the value of connectionString
*/
public String getConnectionString() {
return connectionString;
}
/**
* Set the value of connectionString.
*
* @param connectionString new value of connectionString
*/
public void setConnectionString(String connectionString) {
this.connectionString = connectionString;
}
/**
* The user name for connecting to the database.
*/
private String databaseUser;
/**
* Get the value of databaseUser.
*
* @return the value of databaseUser
*/
public String getDatabaseUser() {
return databaseUser;
}
/**
* Set the value of databaseUser.
*
* @param databaseUser new value of databaseUser
*/
public void setDatabaseUser(String databaseUser) {
this.databaseUser = databaseUser;
}
/**
* The password to use when connecting to the database.
*/
private String databasePassword;
/**
* Get the value of databasePassword.
*
* @return the value of databasePassword
*/
public String getDatabasePassword() {
return databasePassword;
}
/**
* Set the value of databasePassword.
*
* @param databasePassword new value of databasePassword
*/
public void setDatabasePassword(String databasePassword) {
this.databasePassword = databasePassword;
}
/**
* The url for the modified NVD CVE (1.2 schema).
*/
private String cveUrl12Modified;
/**
* Get the value of cveUrl12Modified.
*
* @return the value of cveUrl12Modified
*/
public String getCveUrl12Modified() {
return cveUrl12Modified;
}
/**
* Set the value of cveUrl12Modified.
*
* @param cveUrl12Modified new value of cveUrl12Modified
*/
public void setCveUrl12Modified(String cveUrl12Modified) {
this.cveUrl12Modified = cveUrl12Modified;
}
/**
* The url for the modified NVD CVE (2.0 schema).
*/
private String cveUrl20Modified;
/**
* Get the value of cveUrl20Modified.
*
* @return the value of cveUrl20Modified
*/
public String getCveUrl20Modified() {
return cveUrl20Modified;
}
/**
* Set the value of cveUrl20Modified.
*
* @param cveUrl20Modified new value of cveUrl20Modified
*/
public void setCveUrl20Modified(String cveUrl20Modified) {
this.cveUrl20Modified = cveUrl20Modified;
}
/**
* Base Data Mirror URL for CVE 1.2.
*/
private String cveUrl12Base;
/**
* Get the value of cveUrl12Base.
*
* @return the value of cveUrl12Base
*/
public String getCveUrl12Base() {
return cveUrl12Base;
}
/**
* Set the value of cveUrl12Base.
*
* @param cveUrl12Base new value of cveUrl12Base
*/
public void setCveUrl12Base(String cveUrl12Base) {
this.cveUrl12Base = cveUrl12Base;
}
/**
* Data Mirror URL for CVE 2.0.
*/
private String cveUrl20Base;
/**
* Get the value of cveUrl20Base.
*
* @return the value of cveUrl20Base
*/
public String getCveUrl20Base() {
return cveUrl20Base;
}
/**
* Set the value of cveUrl20Base.
*
* @param cveUrl20Base new value of cveUrl20Base
*/
public void setCveUrl20Base(String cveUrl20Base) {
this.cveUrl20Base = cveUrl20Base;
}
/**
* The number of hours to wait before re-checking for updates.
*/
private Integer cveValidForHours;
/**
* Get the value of cveValidForHours.
*
* @return the value of cveValidForHours
*/
public Integer getCveValidForHours() {
return cveValidForHours;
}
/**
* Set the value of cveValidForHours.
*
* @param cveValidForHours new value of cveValidForHours
*/
public void setCveValidForHours(Integer cveValidForHours) {
this.cveValidForHours = cveValidForHours;
}
/**
* Executes the update by initializing the settings, downloads the NVD XML data, and then processes the data storing it in the
* local database.
*
* @throws BuildException thrown if a connection to the local database cannot be made.
*/
@Override
public void execute() throws BuildException {
populateSettings();
Engine engine = null;
try {
engine = new Engine(Update.class.getClassLoader());
engine.doUpdates();
} catch (DatabaseException ex) {
throw new BuildException("Unable to connect to the dependency-check database; unable to update the NVD data", ex);
} finally {
Settings.cleanup(true);
if (engine != null) {
engine.cleanup();
}
}
}
/**
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
* required to change the proxy server, port, and connection timeout.
*
* @throws BuildException thrown when an invalid setting is configured.
*/
@Override
protected void populateSettings() throws BuildException {
super.populateSettings();
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
if (cveValidForHours != null) {
if (cveValidForHours >= 0) {
Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
} else {
throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater");
}
}
}
}

View File

@@ -0,0 +1,3 @@
dependency-check=org.owasp.dependencycheck.taskdefs.Check
dependency-check-purge=org.owasp.dependencycheck.taskdefs.Purge
dependency-check-update=org.owasp.dependencycheck.taskdefs.Update

View File

@@ -1,2 +1,2 @@
# the path to the data directory
data.directory=dependency-check-data
data.directory=data

View File

@@ -1,3 +0,0 @@
# define custom tasks here
dependencycheck=org.owasp.dependencycheck.taskdefs.DependencyCheckTask

View File

@@ -0,0 +1,19 @@
Configuration
====================
The dependency-check-purge task deletes the local copy of the NVD. This task
should rarely be used, if ever. This is included as a convenience method in
the rare circumstance that the local H2 database because corrupt.
```xml
<target name="dependency-check-purge" description="Dependency-Check purge">
<dependency-check-purge />
</target>
```
Configuration: dependency-check-purge Task
--------------------
The following properties can be set on the dependency-check-purge task.
Property | Description | Default Value
----------------------|----------------------------------------------------------------|------------------
dataDirectory | Data directory that is used to store the local copy of the NVD | data

View File

@@ -0,0 +1,44 @@
Configuration
====================
The dependency-check-update task downloads and updates the local copy of the NVD.
There are several reasons that one may want to use this task; primarily, creating
an update that will be run only once a day or once every few days (but not greater
then 7 days) and then use the `autoUpdate="false"` setting on individual
dependency-check scans. See [Internet Access Required](https://jeremylong.github.io/DependencyCheck/data/index.html)
for more information on why this task would be used.
```xml
<target name="dependency-check-update" description="Dependency-Check Update">
<dependency-check-update />
</target>
```
Configuration: dependency-check-update Task
--------------------
The following properties can be set on the dependency-check task.
Property | Description | Default Value
----------------------|------------------------------------|------------------
proxyServer | The Proxy Server. | &nbsp;
proxyPort | The Proxy Port. | &nbsp;
proxyUsername | Defines the proxy user name. | &nbsp;
proxyPassword | Defines the proxy password. | &nbsp;
connectionTimeout | The URL Connection Timeout. | &nbsp;
Advanced Configuration
====================
The following properties can be configured in the plugin. However, they are less frequently changed. One exception
may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment.
Property | Description | Default Value
---------------------|-------------------------------------------------------------------------------------------------------|------------------
cveUrl12Modified | URL for the modified CVE 1.2. | https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
cveUrl20Modified | URL for the modified CVE 2.0. | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | https://nvd.nist.gov/download/nvdcve-%d.xml.gz
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
dataDirectory | Data directory that is used to store the local copy of the NVD. This should generally not be changed. | data
databaseDriverName | The name of the database driver. Example: org.h2.Driver. | &nbsp;
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. | &nbsp;
connectionString | The connection string used to connect to the database. | &nbsp;
databaseUser | The username used when connecting to the database. | &nbsp;
databasePassword | The password used when connecting to the database. | &nbsp;

View File

@@ -1,5 +1,11 @@
Configuration
====================
Once dependency-check-ant has been [installed](index.html) the defined tasks can be used.
* dependency-check - the primary task used to check the project dependencies. Configuration options are below.
* dependency-check-purge - deletes the local copy of the NVD; this should rarely be used (if ever). See the [purge configuration](config-purge.html) for more information.
* dependency-check-update - downloads and updates the local copy of the NVD. See the [update configuration](config-update.html) for more information.
To configure the dependency-check task you can add it to a target and include a
file based [resource collection](http://ant.apache.org/manual/Types/resources.html#collection)
such as a [FileSet](http://ant.apache.org/manual/Types/fileset.html), [DirSet](http://ant.apache.org/manual/Types/dirset.html),
@@ -8,7 +14,7 @@ the project's dependencies.
```xml
<target name="dependency-check" description="Dependency-Check Analysis">
<dependency-check applicationname="Hello World"
<dependency-check projectname="Hello World"
reportoutputdirectory="${basedir}"
reportformat="ALL">
@@ -19,24 +25,24 @@ the project's dependencies.
</target>
```
Configuration
====================
The following properties can be set on the dependency-check-maven plugin.
Configuration: dependency-check Task
--------------------
The following properties can be set on the dependency-check-update task.
Property | Description | Default Value
----------------------|------------------------------------|------------------
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
updateOnly | If set to true only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. | false
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
reportFormat | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) | &nbsp;
proxyServer | The Proxy Server. | &nbsp;
proxyPort | The Proxy Port. | &nbsp;
proxyUsername | Defines the proxy user name. | &nbsp;
proxyPassword | Defines the proxy password. | &nbsp;
connectionTimeout | The URL Connection Timeout. | &nbsp;
Property | Description | Default Value
----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD | 4
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
projectName | The name of the project being scanned. | Dependency-Check
reportFormat | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) | &nbsp;
proxyServer | The Proxy Server. | &nbsp;
proxyPort | The Proxy Port. | &nbsp;
proxyUsername | Defines the proxy user name. | &nbsp;
proxyPassword | Defines the proxy password. | &nbsp;
connectionTimeout | The URL Connection Timeout. | &nbsp;
Analyzer Configuration
====================
@@ -46,18 +52,26 @@ Note, that specific analyzers will automatically disable themselves if no file
types that they support are detected - so specifically disabling them may not
be needed.
Property | Description | Default Value
------------------------|---------------------------------------------------------------------------|------------------
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | &nbsp;
jarAnalyzer | Sets whether the Jar Analyzer will be used. | true
centralAnalyzerEnabled | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer (see below). | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true
nexusUrl | Defines the Nexus web service endpoint (example http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. | &nbsp;
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. | &nbsp;
Property | Description | Default Value
------------------------------|---------------------------------------------------------------------------|------------------
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | &nbsp;
jarAnalyzer | Sets whether the Jar Analyzer will be used. | true
centralAnalyzerEnabled | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer (see below). | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. This analyzer is superceded by the Central Analyzer; however, you can configure this to run against a Nexus Pro installation. | true
nexusUrl | Defines the Nexus web service endpoint (example http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. | &nbsp;
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
pyDistributionAnalyzerEnabled | Sets whether the Python Distribution Analyzer will be used. | true
pyPackageAnalyzerEnabled | Sets whether the Python Package Analyzer will be used. | true
rubygemsAnalyzerEnabled | Sets whether the Ruby Gemspec Analyzer will be used. | true
opensslAnalyzerEnabled | Sets whether or not the openssl Analyzer should be used. | true
cmakeAnalyzerEnabled | Sets whether or not the CMake Analyzer should be used. | true
autoconfAnalyzerEnabled | Sets whether or not the autoconf Analyzer should be used. | true
composerAnalyzerEnabled | Sets whether or not the PHP Composer Lock File Analyzer should be used. | true
nodeAnalyzerEnabled | Sets whether or not the Node.js Analyzer should be used. | true
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. | &nbsp;
Advanced Configuration
====================
@@ -70,7 +84,7 @@ cveUrl12Modified | URL for the modified CVE 1.2.
cveUrl20Modified | URL for the modified CVE 2.0. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | http://nvd.nist.gov/download/nvdcve-%d.xml
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. | &nbsp;
dataDirectory | Data directory that is used to store the local copy of the NVD. This should generally not be changed. | data
databaseDriverName | The name of the database driver. Example: org.h2.Driver. | &nbsp;
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. | &nbsp;
connectionString | The connection string used to connect to the database. | &nbsp;

View File

@@ -7,23 +7,25 @@ identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.
Installation
====================
Download dependency-check-ant from [bintray here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-${project.version}.jar).
To install dependency-check-ant place the dependency-check-ant-${project.version}.jar into
the lib directory of your Ant instalation directory. Once installed you can add
the taskdef to you build.xml and add the task to a new or existing target:
1. Download dependency-check-ant from [bintray here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-${project.version}-release.zip).
2. Unzip the archive
3. Add the taskdef to your build.xml:
```xml
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask"/>
```
```xml
<!-- Set the value to the installation directory's path -->
<property name="dependency-check.home" value="C:/tools/dependency-check-ant"/>
<path id="dependency-check.path">
<pathelement location="${dependency-check.home}/dependency-check-ant.jar"/>
</path>
<taskdef resource="dependency-check-taskdefs.properties">
<classpath refid="dependency-check.path" />
</taskdef>
```
4. Use the defined taskdefs:
* [dependency-check](configuration.html) - the primary task used to check the project dependencies.
* [dependency-check-purge](config-purge.html) - deletes the local copy of the NVD; this should rarely be used (if ever).
* [dependency-check-update](config-update.html) - downloads and updates the local copy of the NVD.
If you do not want to install dependency-check-ant into your ant's lib directory when you define the task def you
must add the classpath to the taskdef:
```xml
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask">
<classpath path="[path]/[to]/dependency-check-ant-${project.version}.jar"/>
</taskdef>
```
It is important to understand that the first time this task is executed it may
take 10 minutes or more as it downloads and processes the data from the National

View File

@@ -1,33 +0,0 @@
Usage
====================
First, add the dependency-check-ant taskdef to your build.xml (see the [installation guide](installation.html)):
```xml
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask"/>
```
Or
```xml
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask">
<classpath path="[path]/[to]/dependency-check-ant-${project.version}.jar"/>
</taskdef>
```
Next, add the task to a target of your choosing:
```xml
<target name="dependency-check" description="Dependency-Check Analysis">
<dependency-check applicationname="Hello World"
autoupdate="true"
reportoutputdirectory="${basedir}"
reportformat="HTML">
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</dependency-check>
</target>
```
See the [configuration guide](configuration.html) for more information.

View File

@@ -28,7 +28,6 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
</breadcrumbs>
<menu name="Getting Started">
<item name="Installation" href="installation.html"/>
<item name="Usage" href="usage.html"/>
<item name="Configuration" href="configuration.html"/>
</menu>
<menu ref="reports" />

View File

@@ -26,7 +26,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
import org.owasp.dependencycheck.BaseDBTestCase;
import org.owasp.dependencycheck.utils.Settings;
import static org.junit.Assert.assertTrue;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Dependency-Check Test Build" default="test.fileset" basedir=".">
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask" />
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.Check" />
<target name="test.fileset">
<dependency-check

View File

@@ -19,6 +19,6 @@ Copyright & License
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/LICENSE.txt) file for the full license.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
Dependency-Check Command Line makes use of other open source libraries. Please see the [NOTICE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/NOTICES.txt) file for more information.
Dependency-Check Command Line makes use of other open source libraries. Please see the [NOTICE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/dependency-check-cli/NOTICE.txt) file for more information.

View File

@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.2</version>
</parent>
<artifactId>dependency-check-cli</artifactId>
@@ -124,10 +124,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
@@ -178,96 +174,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${reporting.project-info-reports-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>summary</report>
<report>license</report>
<report>help</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${reporting.javadoc-plugin.version}</version>
<configuration>
<failOnError>false</failOnError>
<bottom>Copyright<EFBFBD> 2012-15 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${reporting.versions-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>dependency-updates-report</report>
<report>plugin-updates-report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>${reporting.jxr-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${reporting.cobertura-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${reporting.surefire-report-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>report-only</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
<version>${reporting.taglist-plugin.version}</version>
<configuration>
<tagListOptions>
<tagClasses>
<tagClass>
<displayName>Todo Work</displayName>
<tags>
<tag>
<matchString>todo</matchString>
<matchType>ignoreCase</matchType>
</tag>
<tag>
<matchString>FIXME</matchString>
<matchType>exact</matchType>
</tag>
</tags>
</tagClass>
</tagClasses>
</tagListOptions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
@@ -300,11 +206,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
</rulesets>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${reporting.findbugs-plugin.version}</version>
</plugin>
</plugins>
</reporting>
<dependencies>
@@ -334,5 +235,15 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@@ -27,11 +27,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang.StringUtils;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.DirectoryScanner;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
@@ -90,7 +91,28 @@ public class App {
prepareLogger(cli.getVerboseLog());
}
if (cli.isGetVersion()) {
if (cli.isPurge()) {
if (cli.getConnectionString() != null) {
LOGGER.error("Unable to purge the database when using a non-default connection string");
} else {
populateSettings(cli);
File db;
try {
db = new File(Settings.getDataDirectory(), "dc.h2.db");
if (db.exists()) {
if (db.delete()) {
LOGGER.info("Database file purged; local copy of the NVD has been removed");
} else {
LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
}
} else {
LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
}
} catch (IOException ex) {
LOGGER.error("Unable to delete the database");
}
}
} else if (cli.isGetVersion()) {
cli.printVersionInfo();
} else if (cli.isUpdateOnly()) {
populateSettings(cli);
@@ -98,7 +120,7 @@ public class App {
} else if (cli.isRunScan()) {
populateSettings(cli);
try {
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(),
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(),
cli.getExcludeList(), cli.getSymLinkDepth());
} catch (InvalidScanPathException ex) {
LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
@@ -156,7 +178,8 @@ public class App {
//LOGGER.debug("baseDir: {}", baseDir);
//LOGGER.debug("include: {}", include);
scanner.setBasedir(baseDir);
scanner.setIncludes(include);
final String[] includes = {include};
scanner.setIncludes(includes);
scanner.setMaxLevelsOfSymlinks(symLinkDepth);
if (symLinkDepth <= 0) {
scanner.setFollowSymlinks(false);
@@ -245,16 +268,6 @@ public class App {
final String dataDirectory = cli.getDataDirectory();
final File propertiesFile = cli.getPropertiesFile();
final String suppressionFile = cli.getSuppressionFile();
final boolean jarDisabled = cli.isJarDisabled();
final boolean archiveDisabled = cli.isArchiveDisabled();
final boolean pyDistDisabled = cli.isPythonDistributionDisabled();
final boolean cMakeDisabled = cli.isCmakeDisabled();
final boolean pyPkgDisabled = cli.isPythonPackageDisabled();
final boolean autoconfDisabled = cli.isAutoconfDisabled();
final boolean assemblyDisabled = cli.isAssemblyDisabled();
final boolean nuspecDisabled = cli.isNuspecDisabled();
final boolean centralDisabled = cli.isCentralDisabled();
final boolean nexusDisabled = cli.isNexusDisabled();
final String nexusUrl = cli.getNexusUrl();
final String databaseDriverName = cli.getDatabaseDriverName();
final String databaseDriverPath = cli.getDatabaseDriverPath();
@@ -267,6 +280,7 @@ public class App {
final String cveMod20 = cli.getModifiedCve20Url();
final String cveBase12 = cli.getBaseCve12Url();
final String cveBase20 = cli.getBaseCve20Url();
final Integer cveValidForHours = cli.getCveValidForHours();
if (propertiesFile != null) {
try {
@@ -296,63 +310,41 @@ public class App {
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
}
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
if (proxyServer != null && !proxyServer.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
}
if (proxyPort != null && !proxyPort.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
}
if (proxyUser != null && !proxyUser.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser);
}
if (proxyPass != null && !proxyPass.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass);
}
if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
}
if (suppressionFile != null && !suppressionFile.isEmpty()) {
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
}
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
//File Type Analyzer Settings
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !pyDistDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !pyPkgDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !autoconfDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cMakeDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
if (nexusUrl != null && !nexusUrl.isEmpty()) {
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
}
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
}
if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
}
if (connectionString != null && !connectionString.isEmpty()) {
Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
}
if (databaseUser != null && !databaseUser.isEmpty()) {
Settings.setString(Settings.KEYS.DB_USER, databaseUser);
}
if (databasePassword != null && !databasePassword.isEmpty()) {
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
}
if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
}
if (pathToMono != null && !pathToMono.isEmpty()) {
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
}
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
if (cveBase12 != null && !cveBase12.isEmpty()) {
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
@@ -392,7 +384,7 @@ public class App {
}
/**
* Takes a path and resolves it to be a canonical & absolute path. The caveats are that this method will take an Ant style
* Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style
* file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
* or ?).
*

View File

@@ -22,13 +22,12 @@ import java.io.FileNotFoundException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
import org.owasp.dependencycheck.utils.InvalidSettingException;
import org.owasp.dependencycheck.utils.Settings;
@@ -78,7 +77,7 @@ public final class CliParser {
* @throws ParseException if the arguments are invalid
*/
private CommandLine parseArgs(String[] args) throws ParseException {
final CommandLineParser parser = new PosixParser();
final CommandLineParser parser = new DefaultParser();
final Options options = createCommandLineOptions();
return parser.parse(options, args);
}
@@ -91,14 +90,27 @@ public final class CliParser {
* @throws ParseException is thrown if there is an exception parsing the command line.
*/
private void validateArgs() throws FileNotFoundException, ParseException {
if (isUpdateOnly() || isRunScan()) {
final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
if (value != null) {
try {
final int i = Integer.parseInt(value);
if (i < 0) {
throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
}
} catch (NumberFormatException ex) {
throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
}
}
}
if (isRunScan()) {
validatePathExists(getScanFiles(), ARGUMENT.SCAN);
validatePathExists(getReportDirectory(), ARGUMENT.OUT);
if (getPathToMono() != null) {
validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
}
if (!line.hasOption(ARGUMENT.APP_NAME)) {
throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) {
throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name.");
}
if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
@@ -208,8 +220,8 @@ public final class CliParser {
final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
"Print this message.");
final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
.withDescription("Print the advanced help message.").create();
final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
.desc("Print the advanced help message.").build();
final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
false, "Print the version information.");
@@ -217,44 +229,48 @@ public final class CliParser {
final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
false, "Disables the automatic updating of the CPE data.");
final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME)
.withDescription("The name of the application being scanned. This is a required argument.")
.create(ARGUMENT.APP_NAME_SHORT);
final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
.desc("The name of the project being scanned. This is a required argument.")
.build();
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
.withDescription("The path to scan - this option can be specified multiple times. Ant style"
final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
.desc("The path to scan - this option can be specified multiple times. Ant style"
+ " paths are supported (e.g. path/**/*.jar).")
.create(ARGUMENT.SCAN_SHORT);
.build();
final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
.withDescription("Specify and exclusion pattern. This option can be specified multiple times"
final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
.desc("Specify and exclusion pattern. This option can be specified multiple times"
+ " and it accepts Ant style excludsions.")
.create();
.build();
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
.withDescription("A property file to load.")
.create(ARGUMENT.PROP_SHORT);
final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
.desc("A property file to load.")
.build();
final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
.withDescription("The folder to write reports to. This defaults to the current directory. "
final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
.desc("The folder to write reports to. This defaults to the current directory. "
+ "It is possible to set this to a specific file name if the format argument is not set to ALL.")
.create(ARGUMENT.OUT_SHORT);
.build();
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
.withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
.create(ARGUMENT.OUTPUT_FORMAT_SHORT);
final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
.desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
.build();
final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
.withDescription("The file path to write verbose logging information.")
.create(ARGUMENT.VERBOSE_LOG_SHORT);
final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
.desc("The file path to write verbose logging information.")
.build();
final Option symLinkDepth = OptionBuilder.withArgName("depth").hasArg().withLongOpt(ARGUMENT.SYM_LINK_DEPTH)
.withDescription("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
.create();
final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
.desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
.build();
final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
.withDescription("The file path to the suppression XML file.")
.create();
final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
.desc("The file path to the suppression XML file.")
.build();
final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
.desc("The number of hours to wait before checking for new updates from the NVD.")
.build();
//This is an option group because it can be specified more then once.
final OptionGroup og = new OptionGroup();
@@ -265,9 +281,9 @@ public final class CliParser {
options.addOptionGroup(og)
.addOptionGroup(exog)
.addOption(projectName)
.addOption(out)
.addOption(outputFormat)
.addOption(appName)
.addOption(version)
.addOption(help)
.addOption(advancedHelp)
@@ -275,7 +291,8 @@ public final class CliParser {
.addOption(symLinkDepth)
.addOption(props)
.addOption(verboseLog)
.addOption(suppressionFile);
.addOption(suppressionFile)
.addOption(cveValidForHours);
}
/**
@@ -288,111 +305,122 @@ public final class CliParser {
@SuppressWarnings("static-access")
private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
final Option cve12Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_12)
.withDescription("Base URL for each years CVE 1.2, the %d will be replaced with the year. ")
.create();
final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
.desc("Base URL for each years CVE 1.2, the %d will be replaced with the year. ")
.build();
final Option cve20Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_20)
.withDescription("Base URL for each years CVE 2.0, the %d will be replaced with the year.")
.create();
final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
.desc("Base URL for each years CVE 2.0, the %d will be replaced with the year.")
.build();
final Option cve12Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_12)
.withDescription("URL for the modified CVE 1.2.")
.create();
final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
.desc("URL for the modified CVE 1.2.")
.build();
final Option cve20Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_20)
.withDescription("URL for the modified CVE 2.0.")
.create();
final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
.desc("URL for the modified CVE 2.0.")
.build();
final Option updateOnly = OptionBuilder.withLongOpt(ARGUMENT.UPDATE_ONLY)
.withDescription("Only update the local NVD data cache; no scan will be executed.").create();
final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
.desc("Only update the local NVD data cache; no scan will be executed.").build();
final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY)
.withDescription("The location of the H2 Database file. This option should generally not be set.")
.create(ARGUMENT.DATA_DIRECTORY_SHORT);
final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
.desc("The location of the H2 Database file. This option should generally not be set.")
.build();
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
.withDescription("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
+ "If not set the Nexus Analyzer will be disabled.").create();
final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
.desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
+ "If not set the Nexus Analyzer will be disabled.").build();
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
.withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
.create();
final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
.desc("Whether or not the configured proxy should be used when connecting to Nexus.")
.build();
final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
.withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
.withDescription("A comma separated list of additional extensions to be scanned as ZIP files "
+ "(ZIP, EAR, WAR are already treated as zip files)").create();
final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
.longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
.desc("A comma separated list of additional extensions to be scanned as ZIP files "
+ "(ZIP, EAR, WAR are already treated as zip files)").build();
final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO)
.withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
.create();
final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
.desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
.build();
final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
.longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
.desc("The path to bundle-audit for Gem bundle analysis.").build();
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
.withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
.create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
.longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
.build();
final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
.withDescription("The proxy server to use when downloading resources.").create();
final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
.desc("The proxy server to use when downloading resources.").build();
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
.withDescription("The proxy port to use when downloading resources.").create();
final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
.desc("The proxy port to use when downloading resources.").build();
final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
.withDescription("The proxy username to use when downloading resources.").create();
final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
.desc("The proxy username to use when downloading resources.").build();
final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
.withDescription("The proxy password to use when downloading resources.").create();
final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
.desc("The proxy password to use when downloading resources.").build();
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
.withDescription("The connection string to the database.").create();
final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
.desc("The connection string to the database.").build();
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
.withDescription("The username used to connect to the database.").create();
final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
.desc("The username used to connect to the database.").build();
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
.withDescription("The password for connecting to the database.").create();
final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
.desc("The password for connecting to the database.").build();
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
.withDescription("The database driver name.").create();
final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
.desc("The database driver name.").build();
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH)
.withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
.create();
final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
.desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
.build();
final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
.withDescription("Disable the Jar Analyzer.").create();
final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
.desc("Disable the Jar Analyzer.").build();
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
.withDescription("Disable the Archive Analyzer.").create();
final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
.desc("Disable the Archive Analyzer.").build();
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
.withDescription("Disable the Nuspec Analyzer.").create();
final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
.desc("Disable the Nuspec Analyzer.").build();
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
.withDescription("Disable the .NET Assembly Analyzer.").create();
final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
.desc("Disable the .NET Assembly Analyzer.").build();
final Option disablePythonDistributionAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_DIST)
.withDescription("Disable the Python Distribution Analyzer.").create();
final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
.desc("Disable the Python Distribution Analyzer.").build();
final Option disablePythonPackageAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_PKG)
.withDescription("Disable the Python Package Analyzer.").create();
final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
.desc("Disable the Python Package Analyzer.").build();
final Option disableAutoconfAnalyzer = OptionBuilder
.withLongOpt(ARGUMENT.DISABLE_AUTOCONF)
.withDescription("Disable the Autoconf Analyzer.").create();
final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
.desc("Disable the PHP Composer Analyzer.").build();
final Option disableOpenSSLAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_OPENSSL)
.withDescription("Disable the OpenSSL Analyzer.").create();
final Option disableCmakeAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CMAKE).
withDescription("Disable the Cmake Analyzer.").create();
final Option disableAutoconfAnalyzer = Option.builder()
.longOpt(ARGUMENT.DISABLE_AUTOCONF)
.desc("Disable the Autoconf Analyzer.").build();
final Option disableCentralAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CENTRAL)
.withDescription("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
+ "the Nexus Analyzer.").create();
final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
.desc("Disable the OpenSSL Analyzer.").build();
final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
.desc("Disable the Cmake Analyzer.").build();
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
.withDescription("Disable the Nexus Analyzer.").create();
final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
.desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
+ "the Nexus Analyzer.").build();
final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
.desc("Disable the Nexus Analyzer.").build();
final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
.desc("Purges the local NVD data cache")
.build();
options.addOption(updateOnly)
.addOption(cve12Base)
@@ -413,18 +441,28 @@ public final class CliParser {
.addOption(disableJarAnalyzer)
.addOption(disableArchiveAnalyzer)
.addOption(disableAssemblyAnalyzer)
.addOption(pathToBundleAudit)
.addOption(disablePythonDistributionAnalyzer)
.addOption(disableCmakeAnalyzer)
.addOption(disablePythonPackageAnalyzer)
.addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
.desc("Disable the Ruby Gemspec Analyzer.").build())
.addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
.desc("Disable the Ruby Bundler-Audit Analyzer.").build())
.addOption(disableAutoconfAnalyzer)
.addOption(disableComposerAnalyzer)
.addOption(disableOpenSSLAnalyzer)
.addOption(disableNuspecAnalyzer)
.addOption(disableCentralAnalyzer)
.addOption(disableNexusAnalyzer)
.addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
.desc("Disable the Node.js Package Analyzer.").build())
.addOption(nexusUrl)
.addOption(nexusUsesProxy)
.addOption(additionalZipExtensions)
.addOption(pathToMono);
.addOption(pathToMono)
.addOption(pathToBundleAudit)
.addOption(purge);
}
/**
@@ -437,11 +475,15 @@ public final class CliParser {
@SuppressWarnings({"static-access", "deprecation"})
private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL)
.withDescription("The proxy url argument is deprecated, use proxyserver instead.")
.create();
final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
.desc("The proxy url argument is deprecated, use proxyserver instead.")
.build();
final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
.desc("The name of the project being scanned.")
.build();
options.addOption(proxyServer);
options.addOption(appName);
}
/**
@@ -525,6 +567,16 @@ public final class CliParser {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
}
/**
* Returns true if the disableBundleAudit command line argument was specified.
*
* @return true if the disableBundleAudit command line argument was specified; otherwise false
*/
public boolean isBundleAuditDisabled() {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT);
}
/**
* Returns true if the disablePyDist command line argument was specified.
*
@@ -543,6 +595,15 @@ public final class CliParser {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
}
/**
* Returns whether the Ruby gemspec analyzer is disabled.
*
* @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false
*/
public boolean isRubyGemspecDisabled() {
return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
}
/**
* Returns true if the disableCmake command line argument was specified.
*
@@ -561,6 +622,15 @@ public final class CliParser {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
}
/**
* Returns true if the disableComposer command line argument was specified.
*
* @return true if the disableComposer command line argument was specified; otherwise false
*/
public boolean isComposerDisabled() {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER);
}
/**
* Returns true if the disableNexus command line argument was specified.
*
@@ -579,6 +649,15 @@ public final class CliParser {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
}
/**
* Returns true if the disableNodeJS command line argument was specified.
*
* @return true if the disableNodeJS command line argument was specified; otherwise false
*/
public boolean isNodeJsDisabled() {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS);
}
/**
* Returns true if the disableCentral command line argument was specified.
*
@@ -611,7 +690,7 @@ public final class CliParser {
// still honor the property if it's set.
if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
try {
return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
} catch (InvalidSettingException ise) {
return true;
}
@@ -679,6 +758,15 @@ public final class CliParser {
return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
}
/**
* Returns the path to bundle-audit for Ruby bundle analysis.
*
* @return the path to Mono
*/
public String getPathToBundleAudit() {
return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT);
}
/**
* Returns the output format specified on the command line. Defaults to HTML if no format was specified.
*
@@ -693,8 +781,14 @@ public final class CliParser {
*
* @return the application name.
*/
public String getApplicationName() {
return line.getOptionValue(ARGUMENT.APP_NAME);
public String getProjectName() {
final String appName = line.getOptionValue(ARGUMENT.APP_NAME);
String name = line.getOptionValue(ARGUMENT.PROJECT);
if (name == null && appName != null) {
name = appName;
LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead.");
}
return name;
}
/**
@@ -846,7 +940,7 @@ public final class CliParser {
* @return <code>true</code> if auto-update is allowed; otherwise <code>false</code>
*/
public boolean isAutoUpdate() {
return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
}
/**
@@ -855,7 +949,16 @@ public final class CliParser {
* @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>.
*/
public boolean isUpdateOnly() {
return (line == null) || line.hasOption(ARGUMENT.UPDATE_ONLY);
return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
}
/**
* Checks if the purge NVD flag has been set.
*
* @return <code>true</code> if the purge nvd flag has been set; otherwise <code>false</code>.
*/
public boolean isPurge() {
return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
}
/**
@@ -912,6 +1015,19 @@ public final class CliParser {
return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
}
/**
* Get the value of cveValidForHours.
*
* @return the value of cveValidForHours
*/
public Integer getCveValidForHours() {
final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
if (v != null) {
return Integer.parseInt(v);
}
return null;
}
/**
* A collection of static final strings that represent the possible command line arguments.
*/
@@ -937,6 +1053,10 @@ public final class CliParser {
* The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
*/
public static final String UPDATE_ONLY = "updateonly";
/**
* The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
*/
public static final String PURGE_NVD = "purge";
/**
* The long CLI argument name specifying the directory to write the reports to.
*/
@@ -954,12 +1074,22 @@ public final class CliParser {
*/
public static final String OUTPUT_FORMAT_SHORT = "f";
/**
* The long CLI argument name specifying the name of the application to be scanned.
* The long CLI argument name specifying the name of the project to be scanned.
*/
public static final String PROJECT = "project";
/**
* The long CLI argument name specifying the name of the application to be scanned.
*
* @deprecated project should be used instead
*/
@Deprecated
public static final String APP_NAME = "app";
/**
* The short CLI argument name specifying the name of the application to be scanned.
*
* @deprecated project should be used instead
*/
@Deprecated
public static final String APP_NAME_SHORT = "a";
/**
* The long CLI argument name asking for help.
@@ -1061,6 +1191,10 @@ public final class CliParser {
* The CLI argument name for setting the location of the suppression file.
*/
public static final String SUPPRESSION_FILE = "suppression";
/**
* The CLI argument name for setting the location of the suppression file.
*/
public static final String CVE_VALID_FOR_HOURS = "cveValidForHours";
/**
* Disables the Jar Analyzer.
*/
@@ -1077,6 +1211,14 @@ public final class CliParser {
* Disables the Python Package Analyzer.
*/
public static final String DISABLE_PY_PKG = "disablePyPkg";
/**
* Disables the Python Package Analyzer.
*/
public static final String DISABLE_COMPOSER = "disableComposer";
/**
* Disables the Ruby Gemspec Analyzer.
*/
public static final String DISABLE_RUBYGEMS = "disableRubygems";
/**
* Disables the Autoconf Analyzer.
*/
@@ -1089,6 +1231,10 @@ public final class CliParser {
* Disables the Assembly Analyzer.
*/
public static final String DISABLE_ASSEMBLY = "disableAssembly";
/**
* Disables the Ruby Bundler Audit Analyzer.
*/
public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
/**
* Disables the Nuspec Analyzer.
*/
@@ -1105,6 +1251,10 @@ public final class CliParser {
* Disables the OpenSSL Analyzer.
*/
public static final String DISABLE_OPENSSL = "disableOpenSSL";
/**
* Disables the Node.js Package Analyzer.
*/
public static final String DISABLE_NODE_JS = "disableNodeJS";
/**
* The URL of the nexus server.
*/
@@ -1145,5 +1295,9 @@ public final class CliParser {
* Exclude path argument.
*/
public static final String EXCLUDE = "exclude";
/**
* The CLI argument name for setting the path to bundle-audit for Ruby bundle analysis.
*/
public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
}
}

View File

@@ -22,7 +22,12 @@ package org.owasp.dependencycheck;
*
* @author Jeremy Long
*/
class InvalidScanPathException extends Exception {
public class InvalidScanPathException extends Exception {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new InvalidScanPathException.

View File

@@ -5,7 +5,7 @@ The following table lists the command line arguments:
Short | Argument&nbsp;Name&nbsp;&nbsp; | Parameter | Description | Requirement
-------|-----------------------|-----------------|-------------|------------
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
| \-\-project | \<name\> | The name of the project being scanned. | Required
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify Ant style paths (e.g. directory/**/*.jar). | Required
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**). | Optional
| \-\-symLink | \<depth\> | The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. | Optional
@@ -13,29 +13,35 @@ Short | Argument&nbsp;Name&nbsp;&nbsp; | Parameter | Description | Requir
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../general/suppression.html). | Optional
\-h | \-\-help | | Print the help message. | Optional
| \-\-advancedHelp | | Print the advanced help message. | Optional
\-v | \-\-version | | Print the version information. | Optional
| \-\-cveValidForHours | \<hours\> | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional
Advanced Options
================
Short | Argument&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Parameter | Description | Default&nbsp;Value
-------|-----------------------|-----------------|----------------------------------------------------------------------------------|-------------------
| \-\-cveUrl12Modified | \<url\> | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml
| \-\-cveUrl20Modified | \<url\> | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
| \-\-cveUrl12Base | \<url\> | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml
| \-\-cveUrl20Base | \<url\> | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
| \-\-cveUrl12Modified | \<url\> | URL for the modified CVE 1.2 | https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
| \-\-cveUrl20Modified | \<url\> | URL for the modified CVE 2.0 | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
| \-\-cveUrl12Base | \<url\> | Base URL for each year's CVE 1.2, the %d will be replaced with the year | https://nvd.nist.gov/download/nvdcve-%d.xml.gz
| \-\-cveUrl20Base | \<url\> | Base URL for each year's CVE 2.0, the %d will be replaced with the year | https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
\-P | \-\-propertyfile | \<file\> | Specifies a file that contains properties to use instead of applicaion defaults. | &nbsp;
| \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. | &nbsp;
| \-\-disablePyDist | | Sets whether the Python Distribution Analyzer will be used. | false
| \-\-disablePyPkg | | Sets whether the Python Package Analyzer will be used. | false
| \-\-disableNodeJS | | Sets whether the Node.js Package Analyzer will be used. | false
| \-\-disableRubygems | | Sets whether the Ruby Gemspec Analyzer will be used. | false
| \-\-disableBundleAudit | | Sets whether the Ruby Bundler Audit Analyzer will be used. | false
| \-\-disableAutoconf | | Sets whether the Autoconf Analyzer will be used. | false
| \-\-disableOpenSSL | | Sets whether the OpenSSL Analyzer will be used. | false
| \-\-disableCmake | | Sets whether the Cmake Analyzer will be used. | false
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
| \-\-disableCmake | | Sets whether the Cmake Analyzer will be disabled. | false
| \-\-disableArchive | | Sets whether the Archive Analyzer will be disabled. | false
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | &nbsp;
| \-\-disableJar | | Sets whether the Jar Analyzer will be used. | false
| \-\-disableJar | | Sets whether the Jar Analyzer will be disabled. | false
| \-\-disableComposer | | Sets whether the PHP Composer Lock File Analyzer will be disabled. | false
| \-\-disableCentral | | Sets whether the Central Analyzer will be used. **Disabling this analyzer is not recommended as it could lead to false negatives (e.g. libraries that have vulnerabilities may not be reported correctly).** If this analyzer is being disabled there is a good chance you also want to disable the Nexus Analyzer. | false
| \-\-disableNexus | | Sets whether the Nexus Analyzer will be used. Note, this has been superceded by the Central Analyzer. However, you can configure the Nexus URL to utilize an internally hosted Nexus Pro server. | false
| \-\-nexus | \<url\> | The url to the Nexus Server's web service end point (example: http://domain.enterprise/nexus/service/local/). If not set the Nexus Analyzer will be disabled. | &nbsp;
@@ -43,6 +49,7 @@ Short | Argument&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Paramete
| \-\-disableNuspec | | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | false
| \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false
| \-\-mono | \<path\> | The path to Mono for .NET Assembly analysis on non-windows systems. | &nbsp;
| \-\-bundleAudit | | The path to the bundle-audit executable. | &nbsp;
| \-\-proxyserver | \<server\> | The proxy server to use when downloading resources. | &nbsp;
| \-\-proxyport | \<port\> | The proxy port to use when downloading resources. | &nbsp;
| \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. | &nbsp;
@@ -54,3 +61,4 @@ Short | Argument&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Paramete
| \-\-dbPassword | \<password\> | The password for connecting to the database. | &nbsp;
| \-\-dbUser | \<user\> | The username used to connect to the database. | &nbsp;
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. | &nbsp;
| \-\-purge | | Delete the local copy of the NVD. This is used to force a refresh of the data. | &nbsp;

View File

@@ -14,14 +14,21 @@ script executable:
$ chmod +777 dependency-check.sh
To scan a folder on the system you can run:
#set( $H = '#' )
$H$H$H Homebrew
$ brew install dependency-check
This puts an executable `dependency-check` script in the `/bin` directory of
your homebrew installation.
To scan a folder on the system you can run:
$H$H$H Windows
dependency-check.bat --app "My App Name" --scan "c:\java\application\lib"
dependency-check.bat --project "My App Name" --scan "c:\java\application\lib"
$H$H$H *nix
dependency-check.sh --app "My App Name" --scan "/java/application/lib"
dependency-check.sh --project "My App Name" --scan "/java/application/lib"
To view the command line arguments, see the <a href="arguments.html">arguments page</a>, or you can run:
@@ -29,4 +36,4 @@ $H$H$H Windows
dependency-check.bat --help
$H$H$H *nix
dependency-check.sh --help
dependency-check.sh --help

View File

@@ -1,17 +1,19 @@
/*
* Copyright 2015 OWASP.
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 The OWASP Foundatio. All Rights Reserved.
*/
package org.owasp.dependencycheck;

View File

@@ -17,7 +17,7 @@ Copyright & License
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://github.com/jeremylong/DependencyCheck/dependency-check-cli/blob/master/LICENSE.txt) file for the full license.
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/LICENSE.txt) file for the full license.
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt] [notices] file for more information.
@@ -25,4 +25,4 @@ Dependency-Check makes use of several other open source libraries. Please see th
[wiki]: https://github.com/jeremylong/DependencyCheck/wiki
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
[post]: mailto:dependency-check@googlegroups.com
[notices]: https://github.com/jeremylong/DependencyCheck/blob/master/NOTICES.txt
[notices]: https://raw.githubusercontent.com/jeremylong/DependencyCheck/master/NOTICE.txt

View File

@@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.2</version>
</parent>
<artifactId>dependency-check-core</artifactId>
@@ -110,19 +110,17 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>test-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
@@ -212,81 +210,14 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgument>-Xlint:unchecked</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${reporting.project-info-reports-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>summary</report>
<report>license</report>
<report>help</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${reporting.javadoc-plugin.version}</version>
<configuration>
<failOnError>false</failOnError>
<bottom>Copyright© 2012-15 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${reporting.versions-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>dependency-updates-report</report>
<report>plugin-updates-report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>${reporting.jxr-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>${reporting.cobertura-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${reporting.surefire-report-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>report-only</report>
</reports>
</reportSet>
<reportSet>
<id>integration-tests</id>
<reports>
@@ -296,30 +227,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
<version>${reporting.taglist-plugin.version}</version>
<configuration>
<tagListOptions>
<tagClasses>
<tagClass>
<displayName>Todo Work</displayName>
<tags>
<tag>
<matchString>todo</matchString>
<matchType>ignoreCase</matchType>
</tag>
<tag>
<matchString>FIXME</matchString>
<matchType>exact</matchType>
</tag>
</tags>
</tagClass>
</tagClasses>
</tagListOptions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
@@ -352,11 +259,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</rulesets>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${reporting.findbugs-plugin.version}</version>
</plugin>
</plugins>
</reporting>
<dependencies>
@@ -371,22 +273,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- Set this to test so that each project that uses this has to have its own implementation of SLF4J -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<!-- For the CAL10N support -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-utils</artifactId>
@@ -411,8 +302,8 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
@@ -433,11 +324,15 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
@@ -573,7 +468,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skip>true</skip>
</configuration>
@@ -581,12 +475,68 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<systemProperties>
<property>
<name>data.driver_path</name>
<value>${basedir}/${driver_path}</value>
<value>${driver_path}</value>
</property>
<property>
<name>data.driver_name</name>
<value>${driver_name}</value>
</property>
<property>
<name>data.connection_string</name>
<value>${connection_string}</value>
</property>
</systemProperties>
<includes>
<include>**/*MySQLTest.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>Postgresql-IntegrationTest</id>
<activation>
<property>
<name>postgresql</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1204-jdbc42</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>data.driver_path</name>
<value>${driver_path}</value>
</property>
<property>
<name>data.driver_name</name>

View File

@@ -38,10 +38,12 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@@ -59,7 +61,7 @@ public class Engine implements FileFilter {
/**
* A Map of analyzers grouped by Analysis phase.
*/
private EnumMap<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
/**
* A Map of analyzers grouped by Analysis phase.
@@ -173,8 +175,7 @@ public class Engine implements FileFilter {
public List<Dependency> scan(String[] paths) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (String path : paths) {
final File file = new File(path);
final List<Dependency> d = scan(file);
final List<Dependency> d = scan(path);
if (d != null) {
deps.addAll(d);
}
@@ -214,33 +215,14 @@ public class Engine implements FileFilter {
}
/**
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
* Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
* identified are added to the dependency collection.
*
* @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned
* @since v0.3.2.5
*/
public List<Dependency> scan(Set<File> files) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (File file : files) {
final List<Dependency> d = scan(file);
if (d != null) {
deps.addAll(d);
}
}
return deps;
}
/**
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
* identified are added to the dependency collection.
*
* @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned
* @since v0.3.2.5
*/
public List<Dependency> scan(List<File> files) {
public List<Dependency> scan(Collection<File> files) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (File file : files) {
final List<Dependency> d = scan(file);
@@ -352,6 +334,7 @@ public class Engine implements FileFilter {
LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
LOGGER.info("Analysis Starting");
final long analysisStart = System.currentTimeMillis();
// analysis phases
for (AnalysisPhase phase : AnalysisPhase.values()) {
@@ -365,8 +348,7 @@ public class Engine implements FileFilter {
* This is okay for adds/deletes because it happens per analyzer.
*/
LOGGER.debug("Begin Analyzer '{}'", a.getName());
final Set<Dependency> dependencySet = new HashSet<Dependency>();
dependencySet.addAll(dependencies);
final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies);
for (Dependency d : dependencySet) {
boolean shouldAnalyze = true;
if (a instanceof FileTypeAnalyzer) {
@@ -398,7 +380,7 @@ public class Engine implements FileFilter {
}
LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
LOGGER.info("Analysis Complete");
LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
}
/**
@@ -442,6 +424,7 @@ public class Engine implements FileFilter {
*/
public void doUpdates() {
LOGGER.info("Checking for updates");
final long updateStart = System.currentTimeMillis();
final UpdateService service = new UpdateService(serviceClassLoader);
final Iterator<CachedWebDataSource> iterator = service.getDataSources();
while (iterator.hasNext()) {
@@ -454,7 +437,7 @@ public class Engine implements FileFilter {
LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex);
}
}
LOGGER.info("Check for updates complete");
LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
}
/**
@@ -477,6 +460,7 @@ public class Engine implements FileFilter {
* @param file a file extension
* @return true or false depending on whether or not the file extension is supported
*/
@Override
public boolean accept(File file) {
if (file == null) {
return false;

View File

@@ -840,8 +840,7 @@ public class DependencyCheckScanAgent {
*/
private Engine executeDependencyCheck() throws DatabaseException {
populateSettings();
Engine engine = null;
engine = new Engine();
final Engine engine = new Engine();
engine.setDependencies(this.dependencies);
engine.analyzeDependencies();
return engine;
@@ -898,67 +897,28 @@ public class DependencyCheckScanAgent {
}
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
if (proxyServer != null && !proxyServer.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
}
if (proxyPort != null && !proxyPort.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
}
if (proxyUsername != null && !proxyUsername.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername);
}
if (proxyPassword != null && !proxyPassword.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
}
if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
}
if (suppressionFile != null && !suppressionFile.isEmpty()) {
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
}
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
if (centralUrl != null && !centralUrl.isEmpty()) {
Settings.setString(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl);
}
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
if (nexusUrl != null && !nexusUrl.isEmpty()) {
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
}
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
}
if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
}
if (connectionString != null && !connectionString.isEmpty()) {
Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
}
if (databaseUser != null && !databaseUser.isEmpty()) {
Settings.setString(Settings.KEYS.DB_USER, databaseUser);
}
if (databasePassword != null && !databasePassword.isEmpty()) {
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
}
if (zipExtensions != null && !zipExtensions.isEmpty()) {
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
}
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
}
if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
}
if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
}
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
}
if (pathToMono != null && !pathToMono.isEmpty()) {
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
}
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
}
/**

View File

@@ -214,7 +214,7 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
* @return a Set of strings.
*/
protected static Set<String> newHashSet(String... strings) {
final Set<String> set = new HashSet<String>();
final Set<String> set = new HashSet<String>(strings.length);
Collections.addAll(set, strings);
return set;
}

View File

@@ -28,6 +28,10 @@ public enum AnalysisPhase {
* Initialization phase.
*/
INITIAL,
/**
* Pre information collection phase
*/
PRE_INFORMATION_COLLECTION,
/**
* Information collection phase.
*/

View File

@@ -18,7 +18,7 @@
package org.owasp.dependencycheck.analyzer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
@@ -26,7 +26,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
@@ -40,8 +39,12 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2Utils;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException;
@@ -49,6 +52,7 @@ import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.FileUtils;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,10 +69,6 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
/**
* The buffer size to use when extracting files from the archive.
*/
private static final int BUFFER_SIZE = 4096;
/**
* The count of directories created during analysis. This is used for creating temporary directories.
*/
@@ -101,20 +101,21 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
/**
* The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be
* explicitly handled in extractFiles().
* explicitly handled in {@link #extractFiles(File, File, Engine)}.
*/
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
/**
* Detects files with extensions to remove from the engine's collection of dependencies.
*/
private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz").build();
private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2")
.build();
static {
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
if (additionalZipExt != null) {
final Set<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt));
ZIPPABLES.addAll(ext);
final String[] ext = additionalZipExt.split("\\s*,\\s*");
Collections.addAll(ZIPPABLES, ext);
}
EXTENSIONS.addAll(ZIPPABLES);
}
@@ -194,8 +195,11 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
if (tempFileLocation != null && tempFileLocation.exists()) {
LOGGER.debug("Attempting to delete temporary files");
final boolean success = FileUtils.delete(tempFileLocation);
if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) {
LOGGER.warn("Failed to delete some temporary files, see the log for more details");
if (!success && tempFileLocation.exists()) {
final String[] l = tempFileLocation.list();
if (l != null && l.length > 0) {
LOGGER.warn("Failed to delete some temporary files, see the log for more details");
}
}
}
}
@@ -215,15 +219,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
extractFiles(f, tmpDir, engine);
//make a copy
List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
engine.scan(tmpDir);
List<Dependency> newDependencies = engine.getDependencies();
if (dependencies.size() != newDependencies.size()) {
//get the new dependencies
final Set<Dependency> dependencySet = new HashSet<Dependency>();
dependencySet.addAll(newDependencies);
dependencySet.removeAll(dependencies);
final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
if (!dependencySet.isEmpty()) {
for (Dependency d : dependencySet) {
//fix the dependency's display name and path
final String displayPath = String.format("%s%s",
@@ -245,41 +242,73 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
}
}
if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
final File tdir = getNextTempDirectory();
final String fileName = dependency.getFileName();
LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName));
final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
try {
org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
dependencies = new ArrayList<Dependency>(engine.getDependencies());
engine.scan(tmpLoc);
newDependencies = engine.getDependencies();
if (dependencies.size() != newDependencies.size()) {
//get the new dependencies
final Set<Dependency> dependencySet = new HashSet<Dependency>();
dependencySet.addAll(newDependencies);
dependencySet.removeAll(dependencies);
if (dependencySet.size() != 1) {
LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?");
}
for (Dependency d : dependencySet) {
//fix the dependency's display name and path
d.setFilePath(dependency.getFilePath());
d.setDisplayFileName(dependency.getFileName());
}
}
} catch (IOException ex) {
LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
}
}
addDisguisedJarsToDependencies(dependency, engine);
engine.getDependencies().remove(dependency);
}
Collections.sort(engine.getDependencies());
}
/**
* If a zip file was identified as a possible JAR, this method will add the zip to the list of dependencies.
*
* @param dependency the zip file
* @param engine the engine
* @throws AnalysisException thrown if there is an issue
*/
private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
final File tdir = getNextTempDirectory();
final String fileName = dependency.getFileName();
LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
try {
org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc);
if (!dependencySet.isEmpty()) {
if (dependencySet.size() != 1) {
LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?");
}
for (Dependency d : dependencySet) {
//fix the dependency's display name and path
d.setFilePath(dependency.getFilePath());
d.setDisplayFileName(dependency.getFileName());
}
}
} catch (IOException ex) {
LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
}
}
}
/**
* An empty dependency set.
*/
private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet();
/**
* Scan the given file/folder, and return any new dependencies found.
*
* @param engine used to scan
* @param file target of scanning
* @return any dependencies that weren't known to the engine before
*/
private static Set<Dependency> findMoreDependencies(Engine engine, File file) {
final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies());
engine.scan(file);
final List<Dependency> after = engine.getDependencies();
final boolean sizeChanged = before.size() != after.size();
final Set<Dependency> newDependencies;
if (sizeChanged) {
//get the new dependencies
newDependencies = new HashSet<Dependency>(after);
newDependencies.removeAll(before);
} else {
newDependencies = EMPTY_DEPENDENCY_SET;
}
return newDependencies;
}
/**
* Retrieves the next temporary directory to extract an archive too.
*
@@ -309,41 +338,41 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
* @throws AnalysisException thrown if the archive is not found
*/
private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
if (archive == null || destination == null) {
return;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(archive);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
throw new AnalysisException("Archive file was not found.", ex);
}
final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
try {
if (ZIPPABLES.contains(archiveExt)) {
extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
} else if ("tar".equals(archiveExt)) {
extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
} else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
final File f = new File(destination, uncompressedName);
if (engine.accept(f)) {
decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f);
}
}
} catch (ArchiveExtractionException ex) {
LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
LOGGER.debug("", ex);
} catch (IOException ex) {
LOGGER.warn("Exception reading archive '{}'.", archive.getName());
LOGGER.debug("", ex);
} finally {
if (archive != null && destination != null) {
FileInputStream fis;
try {
fis.close();
} catch (IOException ex) {
fis = new FileInputStream(archive);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
throw new AnalysisException("Archive file was not found.", ex);
}
final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
try {
if (ZIPPABLES.contains(archiveExt)) {
extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
} else if ("tar".equals(archiveExt)) {
extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
} else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
final File f = new File(destination, uncompressedName);
if (engine.accept(f)) {
decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f);
}
} else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) {
final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName());
final File f = new File(destination, uncompressedName);
if (engine.accept(f)) {
decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f);
}
}
} catch (ArchiveExtractionException ex) {
LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
LOGGER.debug("", ex);
} catch (IOException ex) {
LOGGER.warn("Exception reading archive '{}'.", archive.getName());
LOGGER.debug("", ex);
} finally {
close(fis);
}
}
}
@@ -360,75 +389,51 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
ArchiveEntry entry;
try {
while ((entry = input.getNextEntry()) != null) {
final File file = new File(destination, entry.getName());
if (entry.isDirectory()) {
final File d = new File(destination, entry.getName());
if (!d.exists()) {
if (!d.mkdirs()) {
final String msg = String.format("Unable to create directory '%s'.", d.getAbsolutePath());
throw new AnalysisException(msg);
}
}
} else {
final File file = new File(destination, entry.getName());
if (engine.accept(file)) {
LOGGER.debug("Extracting '{}'", file.getPath());
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
final File parent = file.getParentFile();
if (!parent.isDirectory()) {
if (!parent.mkdirs()) {
final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
throw new AnalysisException(msg);
}
}
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
int count;
final byte[] data = new byte[BUFFER_SIZE];
while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
bos.write(data, 0, count);
}
bos.flush();
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
final String msg = String.format("Unable to find file '%s'.", file.getName());
throw new AnalysisException(msg, ex);
} catch (IOException ex) {
LOGGER.debug("", ex);
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
throw new AnalysisException(msg, ex);
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
}
}
if (!file.exists() && !file.mkdirs()) {
final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath());
throw new AnalysisException(msg);
}
} else if (engine.accept(file)) {
extractAcceptedFile(input, file);
}
}
} catch (IOException ex) {
throw new ArchiveExtractionException(ex);
} catch (Throwable ex) {
throw new ArchiveExtractionException(ex);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
close(input);
}
}
/**
* Extracts a file from an archive.
*
* @param input the archives input stream
* @param file the file to extract
* @throws AnalysisException thrown if there is an error
*/
private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
LOGGER.debug("Extracting '{}'", file.getPath());
FileOutputStream fos = null;
try {
final File parent = file.getParentFile();
if (!parent.isDirectory() && !parent.mkdirs()) {
final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
throw new AnalysisException(msg);
}
fos = new FileOutputStream(file);
IOUtils.copy(input, fos);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
final String msg = String.format("Unable to find file '%s'.", file.getName());
throw new AnalysisException(msg, ex);
} catch (IOException ex) {
LOGGER.debug("", ex);
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
throw new AnalysisException(msg, ex);
} finally {
close(fos);
}
}
@@ -444,11 +449,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
FileOutputStream out = null;
try {
out = new FileOutputStream(outputFile);
final byte[] buffer = new byte[BUFFER_SIZE];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
out.write(buffer, 0, n);
}
IOUtils.copy(inputStream, out);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
throw new ArchiveExtractionException(ex);
@@ -456,12 +457,21 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
LOGGER.debug("", ex);
throw new ArchiveExtractionException(ex);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
close(out);
}
}
/**
* Close the given {@link Closeable} instance, ignoring nulls, and logging any thrown {@link IOException}.
*
* @param closeable to be closed
*/
private static void close(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
}
}

View File

@@ -17,15 +17,13 @@
*/
package org.owasp.dependencycheck.analyzer;
import ch.qos.cal10n.IMessageConveyor;
import ch.qos.cal10n.MessageConveyor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
@@ -45,7 +43,6 @@ import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Analyzer for getting company, product, and version information from a .NET assembly.
@@ -75,10 +72,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
* The DocumentBuilder for parsing the XML
*/
private DocumentBuilder builder;
/**
* Message Conveyer
*/
private static final IMessageConveyor MESSAGE_CONVERYOR = new MessageConveyor(Locale.getDefault());
/**
* Logger
*/
@@ -122,21 +115,19 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
final List<String> args = buildArgumentList();
args.add(dependency.getActualFilePath());
final ProcessBuilder pb = new ProcessBuilder(args);
BufferedReader rdr = null;
Document doc = null;
try {
final Process proc = pb.start();
// Try evacuating the error stream
rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8"));
String line = null;
// CHECKSTYLE:OFF
while (rdr.ready() && (line = rdr.readLine()) != null) {
LOGGER.warn("Error from GrokAssembly: {}", line);
}
// CHECKSTYLE:ON
int rc = 0;
doc = builder.parse(proc.getInputStream());
// Try evacuating the error stream
final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
if (null != errorStream && !errorStream.isEmpty()) {
LOGGER.warn("Error from GrokAssembly: {}", errorStream);
}
int rc = 0;
try {
rc = proc.waitFor();
} catch (InterruptedException ie) {
@@ -154,7 +145,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
// First, see if there was an error
final String error = xpath.evaluate("/assembly/error", doc);
if (error != null && !"".equals(error)) {
if (error != null && !error.isEmpty()) {
throw new AnalysisException(error);
}
@@ -183,14 +174,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
} catch (XPathExpressionException xpe) {
// This shouldn't happen
throw new AnalysisException(xpe);
} finally {
if (rdr != null) {
try {
rdr.close();
} catch (IOException ex) {
LOGGER.debug("ignore", ex);
}
}
}
}
@@ -207,11 +190,8 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
try {
fos = new FileOutputStream(tempFile);
is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
final byte[] buff = new byte[4096];
int bread = -1;
while ((bread = is.read(buff)) >= 0) {
fos.write(buff, 0, bread);
}
IOUtils.copy(is, fos);
grokAssemblyExe = tempFile;
// Set the temp file to get deleted when we're done
grokAssemblyExe.deleteOnExit();
@@ -239,21 +219,16 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
// Now, need to see if GrokAssembly actually runs from this location.
final List<String> args = buildArgumentList();
BufferedReader rdr = null;
try {
final ProcessBuilder pb = new ProcessBuilder(args);
final Process p = pb.start();
// Try evacuating the error stream
rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8"));
// CHECKSTYLE:OFF
while (rdr.ready() && rdr.readLine() != null) {
// We expect this to complain
}
// CHECKSTYLE:ON
IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
final XPath xpath = XPathFactory.newInstance().newXPath();
final String error = xpath.evaluate("/assembly/error", doc);
if (p.waitFor() != 1 || error == null || "".equals(error)) {
if (p.waitFor() != 1 || error == null || error.isEmpty()) {
LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
LOGGER.debug("GrokAssembly.exe is not working properly");
grokAssemblyExe = null;
@@ -270,14 +245,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
this.setEnabled(false);
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
}
} finally {
if (rdr != null) {
try {
rdr.close();
} catch (IOException ex) {
LOGGER.trace("ignore", ex);
}
}
}
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}

View File

@@ -173,10 +173,10 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
}
} else {
// copy, alter and set in case some other thread is iterating over
final List<Dependency> deps = new ArrayList<Dependency>(
final List<Dependency> dependencies = new ArrayList<Dependency>(
engine.getDependencies());
deps.remove(dependency);
engine.setDependencies(deps);
dependencies.remove(dependency);
engine.setDependencies(dependencies);
}
}
@@ -225,7 +225,7 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
contents = FileUtils.readFileToString(actualFile).trim();
} catch (IOException e) {
throw new AnalysisException(
"Problem occured while reading dependency file.", e);
"Problem occurred while reading dependency file.", e);
}
return contents;
}

View File

@@ -18,7 +18,7 @@
package org.owasp.dependencycheck.analyzer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
@@ -62,11 +62,19 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
private static final int REGEX_OPTIONS = Pattern.DOTALL
| Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
/**
* Regex to extract the product information.
*/
private static final Pattern PROJECT = Pattern.compile(
"^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
// Group 1: Product
// Group 2: Version
/**
* Regex to extract product and version information.
*
* Group 1: Product
*
* Group 2: Version
*/
private static final Pattern SET_VERSION = Pattern
.compile(
"^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
@@ -167,20 +175,28 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
dependency.getProductEvidence().addEvidence(name, "Project",
group, Confidence.HIGH);
}
LOGGER.debug(String.format("Found %d matches.", count));
LOGGER.debug("Found {} matches.", count);
analyzeSetVersionCommand(dependency, engine, contents);
}
}
/**
* Extracts the version information from the contents. If more then one version is found additional dependencies are added to
* the dependency list.
*
* @param dependency the dependency being analyzed
* @param engine the dependency-check engine
* @param contents the version information
*/
private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
final Dependency orig = dependency;
Dependency currentDep = dependency;
final Matcher m = SET_VERSION.matcher(contents);
int count = 0;
while (m.find()) {
count++;
LOGGER.debug(String.format(
"Found project command match with %d groups: %s",
m.groupCount(), m.group(0)));
LOGGER.debug("Found project command match with {} groups: {}",
m.groupCount(), m.group(0));
String product = m.group(1);
final String version = m.group(2);
LOGGER.debug("Group 1: " + product);
@@ -191,19 +207,19 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
}
if (count > 1) {
//TODO - refactor so we do not assign to the parameter (checkstyle)
dependency = new Dependency(orig.getActualFile());
dependency.setDisplayFileName(String.format("%s:%s", orig.getDisplayFileName(), product));
final String filePath = String.format("%s:%s", orig.getFilePath(), product);
dependency.setFilePath(filePath);
currentDep = new Dependency(dependency.getActualFile());
currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
currentDep.setFilePath(filePath);
// prevents coalescing into the dependency provided by engine
dependency.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes())));
engine.getDependencies().add(dependency);
currentDep.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes())));
engine.getDependencies().add(currentDep);
}
final String source = dependency.getDisplayFileName();
dependency.getProductEvidence().addEvidence(source, "Product",
final String source = currentDep.getDisplayFileName();
currentDep.getProductEvidence().addEvidence(source, "Product",
product, Confidence.MEDIUM);
dependency.getVersionEvidence().addEvidence(source, "Version",
currentDep.getVersionEvidence().addEvidence(source, "Version",
version, Confidence.MEDIUM);
}
LOGGER.debug(String.format("Found %d matches.", count));

View File

@@ -134,13 +134,14 @@ public class CPEAnalyzer implements Analyzer {
* process.
*/
public void open() throws IOException, DatabaseException {
LOGGER.debug("Opening the CVE Database");
cve = new CveDB();
cve.open();
LOGGER.debug("Creating the Lucene CPE Index");
cpe = CpeMemoryIndex.getInstance();
try {
LOGGER.info("Creating the CPE Index");
final long creationStart = System.currentTimeMillis();
cpe.open(cve);
LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart);
} catch (IndexException ex) {
LOGGER.debug("IndexException", ex);
throw new DatabaseException(ex);
@@ -334,11 +335,11 @@ public class CPEAnalyzer implements Analyzer {
* @return if the append was successful.
*/
private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
sb.append(" ").append(field).append(":( ");
sb.append(' ').append(field).append(":( ");
final String cleanText = cleanseText(searchText);
if ("".equals(cleanText)) {
if (cleanText.isEmpty()) {
return false;
}
@@ -348,20 +349,27 @@ public class CPEAnalyzer implements Analyzer {
final StringTokenizer tokens = new StringTokenizer(cleanText);
while (tokens.hasMoreElements()) {
final String word = tokens.nextToken();
String temp = null;
StringBuilder temp = null;
for (String weighted : weightedText) {
final String weightedStr = cleanseText(weighted);
if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
temp = LuceneUtils.escapeLuceneQuery(word) + WEIGHTING_BOOST;
temp = new StringBuilder(word.length() + 2);
LuceneUtils.appendEscapedLuceneQuery(temp, word);
temp.append(WEIGHTING_BOOST);
if (!word.equalsIgnoreCase(weightedStr)) {
temp += " " + LuceneUtils.escapeLuceneQuery(weightedStr) + WEIGHTING_BOOST;
temp.append(' ');
LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
temp.append(WEIGHTING_BOOST);
}
break;
}
}
sb.append(' ');
if (temp == null) {
temp = LuceneUtils.escapeLuceneQuery(word);
LuceneUtils.appendEscapedLuceneQuery(sb, word);
} else {
sb.append(temp);
}
sb.append(" ").append(temp);
}
}
sb.append(" ) ");
@@ -514,7 +522,7 @@ public class CPEAnalyzer implements Analyzer {
for (VulnerableSoftware vs : cpes) {
DependencyVersion dbVer;
if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getUpdate());
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
} else {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
}

View File

@@ -192,7 +192,7 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
for (MavenArtifact ma : mas) {
LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma.toString(), dependency.getFileName());
LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName());
dependency.addAsEvidence("central", ma, confidence);
boolean pomAnalyzed = false;
for (Evidence e : dependency.getVendorEvidence()) {

View File

@@ -0,0 +1,162 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.composer.ComposerDependency;
import org.owasp.dependencycheck.data.composer.ComposerException;
import org.owasp.dependencycheck.data.composer.ComposerLockParser;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.Checksum;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
/**
* Used to analyze a composer.lock file for a composer PHP app.
*
* @author colezlaw
*/
public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The logger
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
/**
* The analyzer name
*/
private static final String ANALYZER_NAME = "Composer.lock analyzer";
/**
* composer.json
*/
private static final String COMPOSER_LOCK = "composer.lock";
/**
* The FileFilter
*/
private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
/**
* Returns the FileFilter
*
* @return the FileFilter
*/
@Override
protected FileFilter getFileFilter() {
return FILE_FILTER;
}
/**
* Initializes the analyzer
*
* @throws Exception
*/
@Override
protected void initializeFileTypeAnalyzer() throws Exception {
sha1 = MessageDigest.getInstance("SHA1");
}
/**
* The MessageDigest for calculating a new digest for the new dependencies added
*/
private MessageDigest sha1 = null;
/**
* Entry point for the analyzer.
*
* @param dependency the dependency to analyze
* @param engine the engine scanning
* @throws AnalysisException if there's a failure during analysis
*/
@Override
protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
FileInputStream fis = null;
try {
fis = new FileInputStream(dependency.getActualFile());
final ComposerLockParser clp = new ComposerLockParser(fis);
LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
clp.process();
for (ComposerDependency dep : clp.getDependencies()) {
final Dependency d = new Dependency(dependency.getActualFile());
d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
d.setFilePath(filePath);
d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
LOGGER.info("Adding dependency {}", d);
engine.getDependencies().add(d);
}
} catch (FileNotFoundException fnfe) {
LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
} catch (ComposerException ce) {
LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
} finally {
if (fis != null) {
try {
fis.close();
} catch (Exception e) {
LOGGER.debug("Unable to close file", e);
}
}
}
}
/**
* Gets the key to determine whether the analyzer is enabled.
*
* @return the key specifying whether the analyzer is enabled
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
}
/**
* Returns the analyzer's name.
*
* @return the analyzer's name
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the phase this analyzer should run under.
*
* @return the analysis phase
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return AnalysisPhase.INFORMATION_COLLECTION;
}
}

View File

@@ -75,6 +75,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
@@ -84,6 +85,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
@@ -211,10 +213,8 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
//version check
final DependencyVersion version1 = DependencyVersionUtil.parseVersion(fileName1);
final DependencyVersion version2 = DependencyVersionUtil.parseVersion(fileName2);
if (version1 != null && version2 != null) {
if (!version1.equals(version2)) {
return false;
}
if (version1 != null && version2 != null && !version1.equals(version2)) {
return false;
}
//filename check

View File

@@ -69,6 +69,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
@@ -78,6 +79,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
@@ -111,7 +113,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
for (Identifier i : dependency.getIdentifiers()) {
if ("maven".contains(i.getType())) {
if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
final int endPoint = i.getValue().indexOf(":", 19);
final int endPoint = i.getValue().indexOf(':', 19);
if (endPoint >= 0) {
mustContain = i.getValue().substring(19, endPoint).toLowerCase();
break;
@@ -154,8 +156,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*/
@SuppressWarnings("null")
private void removeSpuriousCPE(Dependency dependency) {
final List<Identifier> ids = new ArrayList<Identifier>();
ids.addAll(dependency.getIdentifiers());
final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
Collections.sort(ids);
final ListIterator<Identifier> mainItr = ids.listIterator();
while (mainItr.hasNext()) {
@@ -379,18 +380,16 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*/
private void addFalseNegativeCPEs(Dependency dependency) {
//TODO move this to the hint analyzer
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) {
final Identifier i = itr.next();
if ("cpe".equals(i.getType()) && i.getValue() != null
&& (i.getValue().startsWith("cpe:/a:oracle:opensso:")
|| i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
|| i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
|| i.getValue().startsWith("cpe:/a:sun:opensso:"))) {
final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22));
final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22));
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22));
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22));
for (final Identifier identifier : dependency.getIdentifiers()) {
if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
&& (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
|| identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
|| identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
|| identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", identifier.getValue().substring(22));
final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", identifier.getValue().substring(22));
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", identifier.getValue().substring(22));
try {
dependency.addIdentifier("cpe",
newCpe,
@@ -473,8 +472,8 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*/
private String trimCpeToVendor(String value) {
//cpe:/a:jruby:jruby:1.0.8
final int pos1 = value.indexOf(":", 7); //right of vendor
final int pos2 = value.indexOf(":", pos1 + 1); //right of product
final int pos1 = value.indexOf(':', 7); //right of vendor
final int pos2 = value.indexOf(':', pos1 + 1); //right of product
if (pos2 < 0) {
return value;
} else {

View File

@@ -18,6 +18,7 @@
package org.owasp.dependencycheck.analyzer;
import java.io.File;
import org.apache.commons.io.FilenameUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
@@ -48,6 +49,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
@@ -57,6 +59,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
@@ -74,13 +77,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
//strip any path information that may get added by ArchiveAnalyzer, etc.
final File f = dependency.getActualFile();
String fileName = f.getName();
//remove file extension
final int pos = fileName.lastIndexOf(".");
if (pos > 0) {
fileName = fileName.substring(0, pos);
}
final String fileName = FilenameUtils.removeExtension(f.getName());
//add version evidence
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);

View File

@@ -104,6 +104,21 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
"spring-security-core",
Confidence.HIGH);
final Evidence symfony = new Evidence("composer.lock",
"vendor",
"symfony",
Confidence.HIGHEST);
final Evidence zendframeworkVendor = new Evidence("composer.lock",
"vendor",
"zendframework",
Confidence.HIGHEST);
final Evidence zendframeworkProduct = new Evidence("composer.lock",
"product",
"zendframework",
Confidence.HIGHEST);
//springsource/vware problem
final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
@@ -128,6 +143,18 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
}
if (vendor.contains(symfony)) {
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST);
}
if (vendor.contains(zendframeworkVendor)) {
dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST);
}
if (product.contains(zendframeworkProduct)) {
dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST);
}
//sun/oracle problem
final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
final List<Evidence> newEntries = new ArrayList<Evidence>();

View File

@@ -17,7 +17,6 @@
*/
package org.owasp.dependencycheck.analyzer;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
@@ -42,6 +41,8 @@ import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FilenameUtils;
import org.jsoup.Jsoup;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
@@ -69,10 +70,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
/**
* The buffer size to use when extracting files from the archive.
*/
private static final int BUFFER_SIZE = 4096;
/**
* The count of directories created during analysis. This is used for creating temporary directories.
*/
@@ -198,6 +195,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
@@ -272,8 +270,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
}
File externalPom = null;
if (pomEntries.isEmpty()) {
String pomPath = dependency.getActualFilePath();
pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom";
final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom";
externalPom = new File(pomPath);
if (externalPom.isFile()) {
pomEntries.add(pomPath);
@@ -396,26 +393,18 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
InputStream input = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
final File tmpDir = getNextTempDirectory();
final File file = new File(tmpDir, "pom.xml");
try {
final ZipEntry entry = jar.getEntry(path);
input = jar.getInputStream(entry);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
int count;
final byte[] data = new byte[BUFFER_SIZE];
while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
bos.write(data, 0, count);
}
bos.flush();
IOUtils.copy(input, fos);
dependency.setActualFilePath(file.getAbsolutePath());
} catch (IOException ex) {
LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
LOGGER.error("", ex);
} finally {
closeStream(bos);
closeStream(fos);
closeStream(input);
}

View File

@@ -104,7 +104,7 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
*/
boolean retval = false;
try {
if ((!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)))
if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
LOGGER.info("Enabling Nexus analyzer");
retval = true;
@@ -247,7 +247,7 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
}
} catch (IllegalArgumentException iae) {
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));
LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName());
} catch (FileNotFoundException fnfe) {
//dependency.addAnalysisException(new AnalysisException("Artifact not found on repository"));
LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName());

View File

@@ -0,0 +1,187 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Map;
import javax.json.Json;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonString;
import javax.json.JsonValue;
/**
* Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the
* associated CPE.
*
* @author Dale Visser <dvisser@ida.org>
*/
public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Node.js Package Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
/**
* The file name to scan.
*/
public static final String PACKAGE_JSON = "package.json";
/**
* Filter that detects files named "package.json".
*/
private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
.addFilenames(PACKAGE_JSON).build();
/**
* Returns the FileFilter
*
* @return the FileFilter
*/
@Override
protected FileFilter getFileFilter() {
return PACKAGE_JSON_FILTER;
}
@Override
protected void initializeFileTypeAnalyzer() throws Exception {
// NO-OP
}
/**
* Returns the name of the analyzer.
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the phase that the analyzer is intended to run in.
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* Returns the key used in the properties file to reference the analyzer's enabled property.
*
* @return the analyzer's enabled property setting key
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
}
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
final File file = dependency.getActualFile();
JsonReader jsonReader;
try {
jsonReader = Json.createReader(FileUtils.openInputStream(file));
} catch (IOException e) {
throw new AnalysisException(
"Problem occurred while reading dependency file.", e);
}
try {
final JsonObject json = jsonReader.readObject();
final EvidenceCollection productEvidence = dependency.getProductEvidence();
final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
if (json.containsKey("name")) {
final Object value = json.get("name");
if (value instanceof JsonString) {
final String valueString = ((JsonString) value).getString();
productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
} else {
LOGGER.warn("JSON value not string as expected: {}", value);
}
}
addToEvidence(json, productEvidence, "description");
addToEvidence(json, vendorEvidence, "author");
addToEvidence(json, dependency.getVersionEvidence(), "version");
dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
} catch (JsonException e) {
LOGGER.warn("Failed to parse package.json file.", e);
} finally {
jsonReader.close();
}
}
/**
* Adds information to an evidence collection from the node json configuration.
*
* @param json information from node.js
* @param collection a set of evidence about a dependency
* @param key the key to obtain the data from the json information
*/
private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
if (json.containsKey(key)) {
final JsonValue value = json.get(key);
if (value instanceof JsonString) {
collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
} else if (value instanceof JsonObject) {
final JsonObject jsonObject = (JsonObject) value;
for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
final String property = entry.getKey();
final JsonValue subValue = entry.getValue();
if (subValue instanceof JsonString) {
collection.addEvidence(PACKAGE_JSON,
String.format("%s.%s", key, property),
((JsonString) subValue).getString(),
Confidence.HIGHEST);
} else {
LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
}
}
} else {
LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
}
}
}
}

View File

@@ -126,7 +126,7 @@ public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
*/
@Override
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
LOGGER.debug("Checking Nuspec file {}", dependency.toString());
LOGGER.debug("Checking Nuspec file {}", dependency);
try {
final NuspecParser parser = new XPathNuspecParser();
NugetPackage np = null;

View File

@@ -73,7 +73,7 @@ public class NvdCveAnalyzer implements Analyzer {
* @return true or false.
*/
public boolean isOpen() {
return (cveDB != null);
return cveDB != null;
}
/**

View File

@@ -26,7 +26,7 @@ import java.io.FilenameFilter;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.input.AutoCloseInputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
@@ -53,7 +53,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils;
public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
/**
* Name of egg metatdata files to analyze.
* Name of egg metadata files to analyze.
*/
private static final String PKG_INFO = "PKG-INFO";
@@ -269,10 +269,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
*
* @param dependency the dependency being analyzed
* @param file a reference to the manifest/properties file
* @throws AnalysisException thrown when there is an error
*/
private static void collectWheelMetadata(Dependency dependency, File file)
throws AnalysisException {
private static void collectWheelMetadata(Dependency dependency, File file) {
final InternetHeaders headers = getManifestProperties(file);
addPropertyToEvidence(headers, dependency.getVersionEvidence(),
"Version", Confidence.HIGHEST);
@@ -352,7 +350,7 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
* Retrieves the next temporary destingation directory for extracting an archive.
* Retrieves the next temporary destination directory for extracting an archive.
*
* @return a directory
* @throws AnalysisException thrown if unable to create temporary directory

View File

@@ -28,13 +28,10 @@ import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.owasp.dependencycheck.utils.UrlStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -53,12 +50,6 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
private static final int REGEX_OPTIONS = Pattern.DOTALL
| Pattern.CASE_INSENSITIVE;
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory
.getLogger(PythonPackageAnalyzer.class);
/**
* Filename extensions for files to be analyzed.
*/
@@ -184,8 +175,11 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
final String parentName = parent.getName();
boolean found = false;
if (INIT_PY_FILTER.accept(file)) {
for (final File sourcefile : parent.listFiles(PY_FILTER)) {
found |= analyzeFileContents(dependency, sourcefile);
final File[] fileList = parent.listFiles(PY_FILTER);
if (fileList != null) {
for (final File sourceFile : fileList) {
found |= analyzeFileContents(dependency, sourceFile);
}
}
}
if (found) {
@@ -194,10 +188,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
"PackageName", parentName, Confidence.MEDIUM);
} else {
// copy, alter and set in case some other thread is iterating over
final List<Dependency> deps = new ArrayList<Dependency>(
final List<Dependency> dependencies = new ArrayList<Dependency>(
engine.getDependencies());
deps.remove(dependency);
engine.setDependencies(deps);
dependencies.remove(dependency);
engine.setDependencies(dependencies);
}
}
@@ -238,14 +232,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
.getVendorEvidence();
found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
try {
found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
source, "URL", contents);
found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
vendorEvidence, source, "HomePage", contents);
} catch (MalformedURLException e) {
LOGGER.warn(e.getMessage());
}
found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
source, "URL", contents);
found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
vendorEvidence, source, "HomePage", contents);
}
return found;
}
@@ -281,11 +271,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
* @param name the name of the evidence
* @param contents the home page URL
* @return true if evidence was collected; otherwise false
* @throws MalformedURLException thrown if the URL is malformed
*/
private boolean gatherHomePageEvidence(Pattern pattern,
EvidenceCollection evidence, String source, String name,
String contents) throws MalformedURLException {
String contents) {
final Matcher matcher = pattern.matcher(contents);
boolean found = false;
if (matcher.find()) {
@@ -299,7 +288,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
* Gather evidence from a Python source file usin the given string assignment regex pattern.
* Gather evidence from a Python source file using the given string assignment regex pattern.
*
* @param pattern to scan contents with
* @param contents of Python source file

View File

@@ -0,0 +1,326 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Reference;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
/**
* Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party bundle-audit tool.
*
* @author Dale Visser <dvisser@ida.org>
*/
public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
private static final FileFilter FILTER =
FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
public static final String NAME = "Name: ";
public static final String VERSION = "Version: ";
public static final String ADVISORY = "Advisory: ";
public static final String CRITICALITY = "Criticality: ";
/**
* @return a filter that accepts files named Gemfile.lock
*/
@Override
protected FileFilter getFileFilter() {
return FILTER;
}
/**
* Launch bundle-audit.
*
* @return a handle to the process
*/
private Process launchBundleAudit(File folder) throws AnalysisException {
if (!folder.isDirectory()) {
throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
}
final List<String> args = new ArrayList<String>();
final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath);
args.add("check");
args.add("--verbose");
final ProcessBuilder builder = new ProcessBuilder(args);
builder.directory(folder);
try {
return builder.start();
} catch (IOException ioe) {
throw new AnalysisException("bundle-audit failure", ioe);
}
}
/**
* Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
*
* @throws Exception if anything goes wrong
*/
@Override
public void initializeFileTypeAnalyzer() throws Exception {
// Now, need to see if bundle-audit actually runs from this location.
Process process = launchBundleAudit(Settings.getTempDirectory());
int exitValue = process.waitFor();
if (0 == exitValue) {
LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
setEnabled(false);
throw new AnalysisException("Unexpected exit code from bundle-audit process.");
} else {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
if (!reader.ready()) {
LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
setEnabled(false);
throw new AnalysisException("Bundle-audit error stream unexpectedly not ready.");
} else {
final String line = reader.readLine();
if (!line.contains("Errno::ENOENT")) {
LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line);
setEnabled(false);
throw new AnalysisException("Unexpected bundle-audit output.");
}
}
} finally {
if (null != reader) {
reader.close();
}
}
}
if (isEnabled()) {
LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " +
"occasionally to keep its database up to date.");
}
}
/**
* Returns the name of the analyzer.
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the phase that the analyzer is intended to run in.
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* Returns the key used in the properties file to reference the analyzer's enabled property.
*
* @return the analyzer's enabled property setting key
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED;
}
/**
* If {@link #analyzeFileType(Dependency, Engine)} is called, then we have successfully initialized, and it will
* be necessary to disable {@link RubyGemspecAnalyzer}.
*/
private boolean needToDisableGemspecAnalyzer = true;
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
if (needToDisableGemspecAnalyzer) {
boolean failed = true;
final String className = RubyGemspecAnalyzer.class.getName();
for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
if (analyzer instanceof RubyGemspecAnalyzer) {
((RubyGemspecAnalyzer) analyzer).setEnabled(false);
LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
failed = false;
}
}
if (failed) {
LOGGER.warn("Did not find" + className + '.');
}
needToDisableGemspecAnalyzer = false;
}
final File parentFile = dependency.getActualFile().getParentFile();
final Process process = launchBundleAudit(parentFile);
try {
process.waitFor();
} catch (InterruptedException ie) {
throw new AnalysisException("bundle-audit process interrupted", ie);
}
BufferedReader rdr = null;
try {
rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
processBundlerAuditOutput(dependency, engine, rdr);
} catch (IOException ioe) {
LOGGER.warn("bundle-audit failure", ioe);
} finally {
if (null != rdr) {
try {
rdr.close();
} catch (IOException ioe) {
LOGGER.warn("bundle-audit close failure", ioe);
}
}
}
}
private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException {
final String parentName = original.getActualFile().getParentFile().getName();
final String fileName = original.getFileName();
Dependency dependency = null;
Vulnerability vulnerability = null;
String gem = null;
final Map<String, Dependency> map = new HashMap<String, Dependency>();
boolean appendToDescription = false;
while (rdr.ready()) {
final String nextLine = rdr.readLine();
if (null == nextLine) {
break;
} else if (nextLine.startsWith(NAME)) {
appendToDescription = false;
gem = nextLine.substring(NAME.length());
if (!map.containsKey(gem)) {
map.put(gem, createDependencyForGem(engine, parentName, fileName, gem));
}
dependency = map.get(gem);
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
} else if (nextLine.startsWith(VERSION)) {
vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine);
} else if (nextLine.startsWith(ADVISORY)) {
setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
} else if (nextLine.startsWith(CRITICALITY)) {
addCriticalityToVulnerability(parentName, vulnerability, nextLine);
} else if (nextLine.startsWith("URL: ")) {
addReferenceToVulnerability(parentName, vulnerability, nextLine);
} else if (nextLine.startsWith("Description:")) {
appendToDescription = true;
if (null != vulnerability) {
vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 indicates unknown). See link below for full details. *** ");
}
} else if (appendToDescription) {
if (null != vulnerability) {
vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n");
}
}
}
}
private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) {
final String advisory = nextLine.substring((ADVISORY.length()));
if (null != vulnerability) {
vulnerability.setName(advisory);
}
if (null != dependency) {
dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
}
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
}
private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
final String url = nextLine.substring(("URL: ").length());
if (null != vulnerability) {
Reference ref = new Reference();
ref.setName(vulnerability.getName());
ref.setSource("bundle-audit");
ref.setUrl(url);
vulnerability.getReferences().add(ref);
}
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
}
private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
if (null != vulnerability) {
final String criticality = nextLine.substring(CRITICALITY.length()).trim();
if ("High".equals(criticality)) {
vulnerability.setCvssScore(8.5f);
} else if ("Medium".equals(criticality)) {
vulnerability.setCvssScore(5.5f);
} else if ("Low".equals(criticality)) {
vulnerability.setCvssScore(2.0f);
} else {
vulnerability.setCvssScore(-1.0f);
}
}
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
}
private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) {
if (null != dependency) {
final String version = nextLine.substring(VERSION.length());
dependency.getVersionEvidence().addEvidence(
"bundler-audit",
"Version",
version,
Confidence.HIGHEST);
vulnerability = new Vulnerability(); // don't add to dependency until we have name set later
vulnerability.setMatchedCPE(
String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version),
null);
vulnerability.setCvssAccessVector("-");
vulnerability.setCvssAccessComplexity("-");
vulnerability.setCvssAuthentication("-");
vulnerability.setCvssAvailabilityImpact("-");
vulnerability.setCvssConfidentialityImpact("-");
vulnerability.setCvssIntegrityImpact("-");
}
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
return vulnerability;
}
private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String gem) throws IOException {
final File tempFile = File.createTempFile("Gemfile-" + gem, ".lock", Settings.getTempDirectory());
final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
FileUtils.write(tempFile, displayFileName); // unique contents to avoid dependency bundling
final Dependency dependency = new Dependency(tempFile);
dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST);
dependency.setDisplayFileName(displayFileName);
engine.getDependencies().add(dependency);
return dependency;
}
}

View File

@@ -0,0 +1,161 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import java.io.FileFilter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE.
* Regular expressions are used to parse the well-defined Ruby syntax that forms the specification.
*
* @author Dale Visser <dvisser@ida.org>
*/
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
private static final String GEMSPEC = "gemspec";
private static final FileFilter FILTER =
FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
private static final String EMAIL = "email";
/**
* @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec
*/
@Override
protected FileFilter getFileFilter() {
return FILTER;
}
@Override
protected void initializeFileTypeAnalyzer() throws Exception {
// NO-OP
}
/**
* Returns the name of the analyzer.
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the phase that the analyzer is intended to run in.
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* Returns the key used in the properties file to reference the analyzer's enabled property.
*
* @return the analyzer's enabled property setting key
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
}
/**
* The capture group #1 is the block variable.
*/
private static final Pattern GEMSPEC_BLOCK_INIT =
Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
String contents;
try {
contents = FileUtils.readFileToString(dependency.getActualFile());
} catch (IOException e) {
throw new AnalysisException(
"Problem occurred while reading dependency file.", e);
}
final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
if (matcher.find()) {
contents = contents.substring(matcher.end());
final String blockVariable = matcher.group(1);
final EvidenceCollection vendor = dependency.getVendorEvidence();
addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST);
addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST);
final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
if (email.isEmpty()) {
addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
}
addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM);
final EvidenceCollection product = dependency.getProductEvidence();
final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST);
if (!name.isEmpty()) {
vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
}
addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW);
addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST);
}
}
private void addListEvidence(EvidenceCollection evidences, String contents,
String blockVariable, String field, Confidence confidence) {
final Matcher matcher = Pattern.compile(
String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents);
if (matcher.find()) {
final String value = matcher.group(1).replaceAll("['\"]", " ").trim();
evidences.addEvidence(GEMSPEC, field, value, confidence);
}
}
private String addStringEvidence(EvidenceCollection evidences, String contents,
String blockVariable, String field, Confidence confidence) {
final Matcher matcher = Pattern.compile(
String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents);
String value = "";
if (matcher.find()) {
value = matcher.group(2);
evidences.addEvidence(GEMSPEC, field, value, confidence);
}
return value;
}
}

View File

@@ -90,7 +90,7 @@ public class CentralSearch {
final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
LOGGER.debug("Searching Central url {}", url.toString());
LOGGER.debug("Searching Central url {}", url);
// Determine if we need to use a proxy. The rules:
// 1) If the proxy is set, AND the setting is set to true, use the proxy
@@ -116,7 +116,7 @@ public class CentralSearch {
if ("0".equals(numFound)) {
missing = true;
} else {
final ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>();
final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
for (int i = 0; i < docs.getLength(); i++) {
final String g = xpath.evaluate("./str[@name='g']", docs.item(i));

View File

@@ -0,0 +1,110 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.composer;
/**
* Reperesents a dependency (GAV, right now) from a Composer dependency.
*
* @author colezlaw
*/
public final class ComposerDependency {
/**
* The group
*/
private final String group;
/**
* The project
*/
private final String project;
/**
* The version
*/
private final String version;
/**
* Create a ComposerDependency from group, project, and version.
*
* @param group the group
* @param project the project
* @param version the version
*/
public ComposerDependency(String group, String project, String version) {
this.group = group;
this.project = project;
this.version = version;
}
/**
* Get the group.
*
* @return the group
*/
public String getGroup() {
return group;
}
/**
* Get the project.
*
* @return the project
*/
public String getProject() {
return project;
}
/**
* Get the version.
*
* @return the version
*/
public String getVersion() {
return version;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ComposerDependency)) {
return false;
}
final ComposerDependency that = (ComposerDependency) o;
if (group != null ? !group.equals(that.group) : that.group != null) {
return false;
}
if (project != null ? !project.equals(that.project) : that.project != null) {
return false;
}
return !(version != null ? !version.equals(that.version) : that.version != null);
}
@Override
public int hashCode() {
int result = group != null ? group.hashCode() : 0;
result = 31 * result + (project != null ? project.hashCode() : 0);
result = 31 * result + (version != null ? version.hashCode() : 0);
return result;
}
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.composer;
/**
* Represents an exception when handling a composer.json or composer.lock file. Generally used to wrap a downstream exception.
*
* @author colezlaw
*/
public class ComposerException extends RuntimeException {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a ComposerException with default message.
*/
public ComposerException() {
super();
}
/**
* Creates a ComposerException with the specified message.
*
* @param message the exception message
*/
public ComposerException(String message) {
super(message);
}
/**
* Creates a Composer exception with the specified message and cause.
*
* @param message the message
* @param cause the underlying cause
*/
public ComposerException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,124 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.composer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.stream.JsonParsingException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Parses a Composer.lock file from an input stream. In a separate class so it can hopefully be injected.
*
* @author colezlaw
*/
public class ComposerLockParser {
/**
* The JsonReader for parsing JSON
*/
private final JsonReader jsonReader;
/**
* The input stream we'll read
*/
private final InputStream inputStream; // NOPMD - it gets set in the constructor, read later
/**
* The List of ComposerDependencies found
*/
private final List<ComposerDependency> composerDependencies;
/**
* The LOGGER
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
/**
* Createas a ComposerLockParser from a JsonReader and an InputStream.
*
* @param inputStream the InputStream to parse
*/
public ComposerLockParser(InputStream inputStream) {
LOGGER.info("Creating a ComposerLockParser");
this.inputStream = inputStream;
this.jsonReader = Json.createReader(inputStream);
this.composerDependencies = new ArrayList<ComposerDependency>();
}
/**
* Process the input stream to create the list of dependencies.
*/
public void process() {
LOGGER.info("Beginning Composer lock processing");
try {
final JsonObject composer = jsonReader.readObject();
if (composer.containsKey("packages")) {
LOGGER.debug("Found packages");
final JsonArray packages = composer.getJsonArray("packages");
for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
if (pkg.containsKey("name")) {
final String groupName = pkg.getString("name");
if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
if (pkg.containsKey("version")) {
final String group = groupName.substring(0, groupName.indexOf('/'));
final String project = groupName.substring(groupName.indexOf('/') + 1);
String version = pkg.getString("version");
// Some version nubmers begin with v - which doesn't end up matching CPE's
if (version.startsWith("v")) {
version = version.substring(1);
}
LOGGER.debug("Got package {}/{}/{}", group, project, version);
composerDependencies.add(new ComposerDependency(group, project, version));
} else {
LOGGER.debug("Group/package {} does not have a version", groupName);
}
} else {
LOGGER.debug("Got a dependency with no name");
}
}
}
}
} catch (JsonParsingException jsonpe) {
throw new ComposerException("Error parsing stream", jsonpe);
} catch (JsonException jsone) {
throw new ComposerException("Error reading stream", jsone);
} catch (IllegalStateException ise) {
throw new ComposerException("Illegal state in composer stream", ise);
} catch (ClassCastException cce) {
throw new ComposerException("Not exactly composer lock", cce);
}
}
/**
* Gets the list of dependencies.
*
* @return the list of dependencies
*/
public List<ComposerDependency> getDependencies() {
return composerDependencies;
}
}

View File

@@ -0,0 +1,4 @@
/**
* Model elements for PHP Composer files
*/
package org.owasp.dependencycheck.data.composer;

View File

@@ -149,9 +149,8 @@ public final class CpeMemoryIndex {
*
* @return the CPE Analyzer.
*/
@SuppressWarnings("unchecked")
private Analyzer createIndexingAnalyzer() {
final Map fieldAnalyzers = new HashMap();
final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
}
@@ -161,7 +160,6 @@ public final class CpeMemoryIndex {
*
* @return the CPE Analyzer.
*/
@SuppressWarnings("unchecked")
private Analyzer createSearchingAnalyzer() {
final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
@@ -173,24 +171,6 @@ public final class CpeMemoryIndex {
return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
}
/**
* Saves a CPE IndexEntry into the Lucene index.
*
* @param vendor the vendor to index
* @param product the product to index
* @param indexWriter the index writer to write the entry into
* @throws CorruptIndexException is thrown if the index is corrupt
* @throws IOException is thrown if an IOException occurs
*/
public void saveEntry(String vendor, String product, IndexWriter indexWriter) throws CorruptIndexException, IOException {
final Document doc = new Document();
final Field v = new TextField(Fields.VENDOR, vendor, Field.Store.YES);
final Field p = new TextField(Fields.PRODUCT, product, Field.Store.YES);
doc.add(v);
doc.add(p);
indexWriter.addDocument(doc);
}
/**
* Closes the CPE Index.
*/
@@ -230,9 +210,20 @@ public final class CpeMemoryIndex {
final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
indexWriter = new IndexWriter(index, conf);
try {
// Tip: reuse the Document and Fields for performance...
// See "Re-use Document and Field instances" from
// http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
final Document doc = new Document();
final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
doc.add(v);
doc.add(p);
final Set<Pair<String, String>> data = cve.getVendorProductList();
for (Pair<String, String> pair : data) {
saveEntry(pair.getLeft(), pair.getRight(), indexWriter);
v.setStringValue(pair.getLeft());
p.setStringValue(pair.getRight());
indexWriter.addDocument(doc);
}
} catch (DatabaseException ex) {
LOGGER.debug("", ex);
@@ -287,8 +278,9 @@ public final class CpeMemoryIndex {
if (searchString == null || searchString.trim().isEmpty()) {
throw new ParseException("Query is null or empty");
}
LOGGER.debug(searchString);
final Query query = queryParser.parse(searchString);
return indexSearcher.search(query, maxQueryResults);
return search(query, maxQueryResults);
}
/**

View File

@@ -48,7 +48,7 @@ public class IndexEntry implements Serializable {
*/
public String getDocumentId() {
if (documentId == null && vendor != null && product != null) {
documentId = vendor + ":" + product;
documentId = vendor + ':' + product;
}
return documentId;
}

View File

@@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;
/**
*
@@ -45,21 +46,21 @@ public final class CweDB {
/**
* A HashMap of the CWE data.
*/
private static final HashMap<String, String> CWE = loadData();
private static final Map<String, String> CWE = loadData();
/**
* Loads a HashMap containing the CWE data from a resource found in the jar.
*
* @return a HashMap of CWE data
*/
private static HashMap<String, String> loadData() {
private static Map<String, String> loadData() {
ObjectInputStream oin = null;
try {
final String filePath = "data/cwe.hashmap.serialized";
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
oin = new ObjectInputStream(input);
@SuppressWarnings("unchecked")
final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject();
final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
return ret;
} catch (ClassNotFoundException ex) {
LOGGER.warn("Unable to load CWE data. This should not be an issue.");

View File

@@ -77,6 +77,7 @@ public final class LuceneUtils {
case '*':
case '?':
case ':':
case '/':
case '\\': //it is supposed to fall through here
buf.append('\\');
default:
@@ -93,17 +94,12 @@ public final class LuceneUtils {
* @return the escaped text.
*/
public static String escapeLuceneQuery(final CharSequence text) {
if (text == null) {
return null;
}
int size = text.length();
size = size >> 1;
final int size = text.length() << 1;
final StringBuilder buf = new StringBuilder(size);
appendEscapedLuceneQuery(buf, text);
return buf.toString();
}
}

View File

@@ -75,8 +75,8 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
}
/**
* Increments the underlying TokenStream and sets CharTermAttributes to construct an expanded set of tokens by
* concatenating tokens with the previous token.
* Increments the underlying TokenStream and sets CharTermAttributes to construct an expanded set of tokens by concatenating
* tokens with the previous token.
*
* @return whether or not we have hit the end of the TokenStream
* @throws IOException is thrown when an IOException occurs
@@ -112,8 +112,7 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
/**
* <p>
* Resets the Filter and clears any internal state data that may have been left-over from previous uses of the
* Filter.</p>
* Resets the Filter and clears any internal state data that may have been left-over from previous uses of the Filter.</p>
* <p>
* <b>If this Filter is re-used this method must be called between uses.</b></p>
*/
@@ -121,4 +120,46 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
previousWord = null;
words.clear();
}
/**
* Standard hash code implementation.
*
* @return the hash code
*/
@Override
public int hashCode() {
int hash = 3;
hash = 31 * hash + (this.termAtt != null ? this.termAtt.hashCode() : 0);
hash = 31 * hash + (this.previousWord != null ? this.previousWord.hashCode() : 0);
hash = 31 * hash + (this.words != null ? this.words.hashCode() : 0);
return hash;
}
/**
* Standard equals implementation.
*
* @param obj the object to compare
* @return true if the objects are equal; otherwise false.
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TokenPairConcatenatingFilter other = (TokenPairConcatenatingFilter) obj;
if (this.termAtt != other.termAtt && (this.termAtt == null || !this.termAtt.equals(other.termAtt))) {
return false;
}
if ((this.previousWord == null) ? (other.previousWord != null) : !this.previousWord.equals(other.previousWord)) {
return false;
}
if (this.words != other.words && (this.words == null || !this.words.equals(other.words))) {
return false;
}
return true;
}
}

View File

@@ -94,13 +94,13 @@ public class MavenArtifact {
}
if (jarAvailable) {
//org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
this.artifactUrl = base + groupId.replace('.', '/') + "/" + artifactId + "/"
+ version + "/" + artifactId + "-" + version + ".jar";
this.artifactUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
+ version + '/' + artifactId + '-' + version + ".jar";
}
if (pomAvailable) {
//org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
this.pomUrl = base + groupId.replace('.', '/') + "/" + artifactId + "/"
+ version + "/" + artifactId + "-" + version + ".pom";
this.pomUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
+ version + '/' + artifactId + '-' + version + ".pom";
}
}

View File

@@ -63,7 +63,7 @@ public class NexusSearch {
this.rootURL = rootURL;
try {
if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) {
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY)) {
useProxy = true;
LOGGER.debug("Using proxy");
} else {
@@ -132,10 +132,10 @@ public class NexusSearch {
"/org.sonatype.nexus.rest.model.NexusArtifact/pomLink",
doc);
final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
if (link != null && !"".equals(link)) {
if (link != null && !link.isEmpty()) {
ma.setArtifactUrl(link);
}
if (pomLink != null && !"".equals(pomLink)) {
if (pomLink != null && !pomLink.isEmpty()) {
ma.setPomUrl(pomLink);
}
return ma;

View File

@@ -17,11 +17,9 @@
*/
package org.owasp.dependencycheck.data.nvdcve;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Driver;
@@ -29,7 +27,10 @@ import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.io.IOUtils;
import org.owasp.dependencycheck.utils.DBUtils;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,6 +59,10 @@ public final class ConnectionFactory {
* Resource location for SQL file used to create the database schema.
*/
public static final String DB_STRUCTURE_UPDATE_RESOURCE = "data/upgrade_%s.sql";
/**
* The URL that discusses upgrading non-H2 databases.
*/
public static final String UPGRADE_HELP_URL = "http://jeremylong.github.io/DependencyCheck/data/upgrade.html";
/**
* The database driver used to connect to the database.
*/
@@ -243,22 +248,15 @@ public final class ConnectionFactory {
*/
private static void createTables(Connection conn) throws DatabaseException {
LOGGER.debug("Creating database structure");
InputStream is;
InputStreamReader reader;
BufferedReader in = null;
InputStream is = null;
try {
is = ConnectionFactory.class.getClassLoader().getResourceAsStream(DB_STRUCTURE_RESOURCE);
reader = new InputStreamReader(is, "UTF-8");
in = new BufferedReader(reader);
final StringBuilder sb = new StringBuilder(2110);
String tmp;
while ((tmp = in.readLine()) != null) {
sb.append(tmp);
}
final String dbStructure = IOUtils.toString(is, "UTF-8");
Statement statement = null;
try {
statement = conn.createStatement();
statement.execute(sb.toString());
statement.execute(dbStructure);
} catch (SQLException ex) {
LOGGER.debug("", ex);
throw new DatabaseException("Unable to create database statement", ex);
@@ -268,13 +266,7 @@ public final class ConnectionFactory {
} catch (IOException ex) {
throw new DatabaseException("Unable to create database schema", ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
}
IOUtils.closeQuietly(is);
}
}
@@ -288,48 +280,54 @@ public final class ConnectionFactory {
* @throws DatabaseException thrown if there is an exception upgrading the database schema
*/
private static void updateSchema(Connection conn, String schema) throws DatabaseException {
LOGGER.debug("Updating database structure");
InputStream is;
InputStreamReader reader;
BufferedReader in = null;
String updateFile = null;
final String databaseProductName;
try {
updateFile = String.format(DB_STRUCTURE_UPDATE_RESOURCE, schema);
is = ConnectionFactory.class.getClassLoader().getResourceAsStream(updateFile);
if (is == null) {
throw new DatabaseException(String.format("Unable to load update file '%s'", updateFile));
}
reader = new InputStreamReader(is, "UTF-8");
in = new BufferedReader(reader);
final StringBuilder sb = new StringBuilder(2110);
String tmp;
while ((tmp = in.readLine()) != null) {
sb.append(tmp);
}
Statement statement = null;
databaseProductName = conn.getMetaData().getDatabaseProductName();
} catch (SQLException ex) {
throw new DatabaseException("Unable to get the database product name");
}
if ("h2".equalsIgnoreCase(databaseProductName)) {
LOGGER.debug("Updating database structure");
InputStream is = null;
String updateFile = null;
try {
statement = conn.createStatement();
statement.execute(sb.toString());
} catch (SQLException ex) {
LOGGER.debug("", ex);
throw new DatabaseException("Unable to update database schema", ex);
} finally {
DBUtils.closeStatement(statement);
}
} catch (IOException ex) {
final String msg = String.format("Upgrade SQL file does not exist: %s", updateFile);
throw new DatabaseException(msg, ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
updateFile = String.format(DB_STRUCTURE_UPDATE_RESOURCE, schema);
is = ConnectionFactory.class.getClassLoader().getResourceAsStream(updateFile);
if (is == null) {
throw new DatabaseException(String.format("Unable to load update file '%s'", updateFile));
}
final String dbStructureUpdate = IOUtils.toString(is, "UTF-8");
Statement statement = null;
try {
statement = conn.createStatement();
final boolean success = statement.execute(dbStructureUpdate);
if (!success && statement.getUpdateCount() <= 0) {
throw new DatabaseException(String.format("Unable to upgrade the database schema to %s", schema));
}
} catch (SQLException ex) {
LOGGER.debug("", ex);
throw new DatabaseException("Unable to update database schema", ex);
} finally {
DBUtils.closeStatement(statement);
}
} catch (IOException ex) {
final String msg = String.format("Upgrade SQL file does not exist: %s", updateFile);
throw new DatabaseException(msg, ex);
} finally {
IOUtils.closeQuietly(is);
}
} else {
LOGGER.error("The database schema must be upgraded to use this version of dependency-check. Please see {} for more information.", UPGRADE_HELP_URL);
throw new DatabaseException("Database schema is out of date");
}
}
/**
* Counter to ensure that calls to ensureSchemaVersion does not end up in an endless loop.
*/
private static int callDepth = 0;
/**
* Uses the provided connection to check the specified schema version within the database.
*
@@ -344,10 +342,15 @@ public final class ConnectionFactory {
cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
rs = cs.executeQuery();
if (rs.next()) {
if (!DB_SCHEMA_VERSION.equals(rs.getString(1))) {
final DependencyVersion current = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION);
final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1));
if (current.compareTo(db) > 0) {
LOGGER.debug("Current Schema: " + DB_SCHEMA_VERSION);
LOGGER.debug("DB Schema: " + rs.getString(1));
updateSchema(conn, rs.getString(1));
if (++callDepth < 10) {
ensureSchemaVersion(conn);
}
}
} else {
throw new DatabaseException("Database schema is missing");

View File

@@ -18,12 +18,11 @@
package org.owasp.dependencycheck.data.nvdcve;
/**
* An exception used to indicate the db4o database is corrupt. This could be due to invalid data or a complete failure
* of the db.
* An exception used to indicate the db4o database is corrupt. This could be due to invalid data or a complete failure of the db.
*
* @author Jeremy Long
*/
class CorruptDatabaseException extends DatabaseException {
public class CorruptDatabaseException extends DatabaseException {
/**
* the serial version uid.
@@ -31,7 +30,7 @@ class CorruptDatabaseException extends DatabaseException {
private static final long serialVersionUID = 1L;
/**
* Creates an CorruptDatabaseException
* Creates an CorruptDatabaseException.
*
* @param msg the exception message
*/
@@ -40,7 +39,7 @@ class CorruptDatabaseException extends DatabaseException {
}
/**
* Creates an CorruptDatabaseException
* Creates an CorruptDatabaseException.
*
* @param msg the exception message
* @param ex the cause of the exception

View File

@@ -29,8 +29,10 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
@@ -74,9 +76,17 @@ public class CveDB {
*/
public CveDB() throws DatabaseException {
super();
statementBundle = ResourceBundle.getBundle("data/dbStatements");
try {
open();
try {
final String databaseProductName = conn.getMetaData().getDatabaseProductName();
LOGGER.debug("Database dialect: {}", databaseProductName);
final Locale dbDialect = new Locale(databaseProductName);
statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
} catch (SQLException se) {
LOGGER.warn("Problem loading database specific dialect!", se);
statementBundle = ResourceBundle.getBundle("data/dbStatements");
}
databaseProperties = new DatabaseProperties(this);
} catch (DatabaseException ex) {
throw ex;
@@ -252,44 +262,6 @@ public class CveDB {
return prop;
}
/**
* Saves a set of properties to the database.
*
* @param props a collection of properties
*/
void saveProperties(Properties props) {
PreparedStatement updateProperty = null;
PreparedStatement insertProperty = null;
try {
try {
updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
} catch (SQLException ex) {
LOGGER.warn("Unable to save properties to the database");
LOGGER.debug("Unable to save properties to the database", ex);
return;
}
for (Entry<Object, Object> entry : props.entrySet()) {
final String key = entry.getKey().toString();
final String value = entry.getValue().toString();
try {
updateProperty.setString(1, value);
updateProperty.setString(2, key);
if (updateProperty.executeUpdate() == 0) {
insertProperty.setString(1, key);
insertProperty.setString(2, value);
}
} catch (SQLException ex) {
LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
LOGGER.debug("", ex);
}
}
} finally {
DBUtils.closeStatement(updateProperty);
DBUtils.closeStatement(insertProperty);
}
}
/**
* Saves a property to the database.
*
@@ -297,38 +269,38 @@ public class CveDB {
* @param value the property value
*/
void saveProperty(String key, String value) {
PreparedStatement updateProperty = null;
PreparedStatement insertProperty = null;
try {
try {
updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
} catch (SQLException ex) {
LOGGER.warn("Unable to save properties to the database");
LOGGER.debug("Unable to save properties to the database", ex);
return;
}
try {
updateProperty.setString(1, value);
updateProperty.setString(2, key);
if (updateProperty.executeUpdate() == 0) {
try {
insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
} catch (SQLException ex) {
LOGGER.warn("Unable to save properties to the database");
LOGGER.debug("Unable to save properties to the database", ex);
return;
}
insertProperty.setString(1, key);
insertProperty.setString(2, value);
insertProperty.execute();
final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
try {
mergeProperty.setString(1, key);
mergeProperty.setString(2, value);
mergeProperty.executeUpdate();
} finally {
DBUtils.closeStatement(mergeProperty);
}
} catch (MissingResourceException mre) {
// No Merge statement, so doing an Update/Insert...
PreparedStatement updateProperty = null;
PreparedStatement insertProperty = null;
try {
updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
updateProperty.setString(1, value);
updateProperty.setString(2, key);
if (updateProperty.executeUpdate() == 0) {
insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
insertProperty.setString(1, key);
insertProperty.setString(2, value);
insertProperty.executeUpdate();
}
} finally {
DBUtils.closeStatement(updateProperty);
DBUtils.closeStatement(insertProperty);
}
} catch (SQLException ex) {
LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
LOGGER.debug("", ex);
}
} finally {
DBUtils.closeStatement(updateProperty);
DBUtils.closeStatement(insertProperty);
} catch (SQLException ex) {
LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
LOGGER.debug("", ex);
}
}
@@ -340,7 +312,6 @@ public class CveDB {
* @throws DatabaseException thrown if there is an exception retrieving data
*/
public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
ResultSet rs = null;
final VulnerableSoftware cpe = new VulnerableSoftware();
try {
cpe.parseName(cpeStr);
@@ -350,7 +321,8 @@ public class CveDB {
final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
PreparedStatement ps;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
ps.setString(1, cpe.getVendor());
@@ -384,12 +356,11 @@ public class CveDB {
v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
vulnerabilities.add(v);
}
DBUtils.closeResultSet(rs);
DBUtils.closeStatement(ps);
} catch (SQLException ex) {
throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
} finally {
DBUtils.closeResultSet(rs);
DBUtils.closeStatement(ps);
}
return vulnerabilities;
}
@@ -421,7 +392,7 @@ public class CveDB {
if (cwe != null) {
final String name = CweDB.getCweName(cwe);
if (name != null) {
cwe += " " + name;
cwe += ' ' + name;
}
}
final int cveId = rsV.getInt(1);
@@ -490,7 +461,7 @@ public class CveDB {
deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
String ids[] = {"id"};
final String[] ids = {"id"};
insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
//Statement.RETURN_GENERATED_KEYS);
ids);
@@ -767,9 +738,9 @@ public class CveDB {
* @return a dependency version
*/
private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
DependencyVersion cpeVersion;
final DependencyVersion cpeVersion;
if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
String versionText;
final String versionText;
if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
} else {
@@ -783,6 +754,8 @@ public class CveDB {
}
/**
* This method is only referenced in unused code.
*
* Deletes unused dictionary entries from the database.
*/
public void deleteUnusedCpe() {
@@ -798,6 +771,8 @@ public class CveDB {
}
/**
* This method is only referenced in unused code and will likely break on MySQL if ever used due to the MERGE statement.
*
* Merges CPE entries into the database.
*
* @param cpe the CPE identifier

View File

@@ -45,6 +45,10 @@ public class DatabaseProperties {
* updates)..
*/
public static final String MODIFIED = "Modified";
/**
* The properties file key for the last checked field - used to store the last check time of the Modified NVD CVE xml file.
*/
public static final String LAST_CHECKED = "NVD CVE Checked";
/**
* The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file.
*/

View File

@@ -63,15 +63,13 @@ public final class DriverLoader {
}
/**
* Loads the specified class by registering the supplied paths to the class loader and then registers the driver
* with the driver manager. The pathToDriver argument is added to the class loader so that an external driver can be
* loaded. Note, the pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added
* as needed. If a path in the pathToDriver argument is a directory all files in the directory are added to the
* class path.
* Loads the specified class by registering the supplied paths to the class loader and then registers the driver with the
* driver manager. The pathToDriver argument is added to the class loader so that an external driver can be loaded. Note, the
* pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added as needed. If a path in the
* pathToDriver argument is a directory all files in the directory are added to the class path.
*
* @param className the fully qualified name of the desired class
* @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list
* of paths
* @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list of paths
* @return the loaded Driver
* @throws DriverLoadException thrown if the driver cannot be loaded
*/
@@ -83,14 +81,15 @@ public final class DriverLoader {
final File file = new File(path);
if (file.isDirectory()) {
final File[] files = file.listFiles();
for (File f : files) {
try {
urls.add(f.toURI().toURL());
} catch (MalformedURLException ex) {
LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
className, f.getAbsoluteFile(), ex);
throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
if (files != null) {
for (File f : files) {
try {
urls.add(f.toURI().toURL());
} catch (MalformedURLException ex) {
LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
className, f.getAbsoluteFile(), ex);
throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
}
}
}
} else if (file.exists()) {
@@ -98,7 +97,7 @@ public final class DriverLoader {
urls.add(file.toURI().toURL());
} catch (MalformedURLException ex) {
LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
className, file.getAbsoluteFile(), ex);
className, file.getAbsoluteFile(), ex);
throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
}
}

View File

@@ -115,7 +115,7 @@ class DriverShim implements Driver {
* @throws SQLFeatureNotSupportedException thrown if the feature is not supported
* @see java.sql.Driver#getParentLogger()
*/
//@Override
@Override
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
//return driver.getParentLogger();
Method m = null;

View File

@@ -24,7 +24,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.zip.GZIPInputStream;
import javax.xml.parsers.ParserConfigurationException;
@@ -44,6 +43,9 @@ import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
/**
*
* This class is currently unused and if enabled will likely not work on MySQL as the MERGE statement is used.
*
* The CpeUpdater is designed to download the CPE data file from NIST and import the data into the database. However, as this
* currently adds no beneficial data, compared to what is in the CPE data contained in the CVE data files, this class is not
* currently used. The code is being kept as a future update may utilize more data from the CPE xml files.
@@ -69,8 +71,8 @@ public class CpeUpdater extends BaseUpdater implements CachedWebDataSource {
for (Cpe cpe : cpes) {
getCveDB().addCpe(cpe.getValue(), cpe.getVendor(), cpe.getProduct());
}
final Date now = new Date();
getProperties().save(LAST_CPE_UPDATE, Long.toString(now.getTime()));
final long now = System.currentTimeMillis();
getProperties().save(LAST_CPE_UPDATE, Long.toString(now));
LOGGER.info("CPE update complete");
}
} finally {
@@ -134,14 +136,14 @@ public class CpeUpdater extends BaseUpdater implements CachedWebDataSource {
* @return true if the CPE data should be refreshed
*/
private boolean updateNeeded() {
final Date now = new Date();
final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 30);
final long now = System.currentTimeMillis();
final int days = Settings.getInt(Settings.KEYS.CPE_MODIFIED_VALID_FOR_DAYS, 30);
long timestamp = 0;
final String ts = getProperties().getProperty(LAST_CPE_UPDATE);
if (ts != null && ts.matches("^[0-9]+$")) {
timestamp = Long.parseLong(ts);
}
return !DateUtil.withinDateRange(timestamp, now.getTime(), days);
return !DateUtil.withinDateRange(timestamp, now, days);
}
/**

View File

@@ -21,7 +21,6 @@ import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
@@ -88,7 +87,7 @@ public class EngineVersionCheck implements CachedWebDataSource {
LOGGER.debug("Begin Engine Version Check");
final DatabaseProperties properties = cveDB.getDatabaseProperties();
final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0"));
final long now = (new Date()).getTime();
final long now = System.currentTimeMillis();
updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, "");
final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0");
LOGGER.debug("Last checked: {}", lastChecked);

View File

@@ -19,7 +19,6 @@ package org.owasp.dependencycheck.data.update;
import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -67,9 +66,11 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
public void update() throws UpdateException {
try {
openDataStores();
final UpdateableNvdCve updateable = getUpdatesNeeded();
if (updateable.isUpdateNeeded()) {
performUpdate(updateable);
if (checkUpdate()) {
final UpdateableNvdCve updateable = getUpdatesNeeded();
if (updateable.isUpdateNeeded()) {
performUpdate(updateable);
}
}
} catch (MalformedURLException ex) {
LOGGER.warn(
@@ -88,6 +89,35 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
}
}
/**
* Checks if the NVD CVE XML files were last checked recently. As an optimization, we can avoid repetitive checks against the
* NVD. Setting CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before checking again. A database property
* stores the timestamp of the last check.
*
* @return true to proceed with the check, or false to skip.
* @throws UpdateException thrown when there is an issue checking for updates.
*/
private boolean checkUpdate() throws UpdateException {
boolean proceed = true;
// If the valid setting has not been specified, then we proceed to check...
final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0);
if (0 < validForHours) {
// ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec
final long msValid = validForHours * 60L * 60L * 1000L;
final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0"));
final long now = System.currentTimeMillis();
proceed = (now - lastChecked) > msValid;
if (proceed) {
getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(now));
} else {
LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours);
LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.",
lastChecked, now, msValid);
}
}
return proceed;
}
/**
* Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.
*
@@ -214,11 +244,11 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
if (!getProperties().isEmpty()) {
try {
final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
final Date now = new Date();
final long now = System.currentTimeMillis();
final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
updates.clear(); //we don't need to update anything.
} else if (DateUtil.withinDateRange(lastUpdated, now.getTime(), days)) {
} else if (DateUtil.withinDateRange(lastUpdated, now, days)) {
for (NvdCveInfo entry : updates) {
if (MODIFIED.equals(entry.getId())) {
entry.setNeedsUpdate(true);

View File

@@ -179,7 +179,7 @@ public class CPEHandler extends DefaultHandler {
/**
* A simple class to maintain information about the current element while parsing the CPE XML.
*/
protected class Element {
protected static final class Element {
/**
* A node type in the CPE Schema 2.2

View File

@@ -68,8 +68,8 @@ public class DownloadTask implements Callable<Future<ProcessTask>> {
final File file2;
try {
file1 = File.createTempFile("cve" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
file1 = File.createTempFile("cve" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
} catch (IOException ex) {
throw new UpdateException("Unable to create temporary files", ex);
}
@@ -185,6 +185,7 @@ public class DownloadTask implements Callable<Future<ProcessTask>> {
final URL url1 = new URL(nvdCveInfo.getUrl());
final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
final long startDownload = System.currentTimeMillis();
try {
Downloader.fetchFile(url1, first);
Downloader.fetchFile(url2, second);
@@ -204,7 +205,8 @@ public class DownloadTask implements Callable<Future<ProcessTask>> {
extractGzip(second);
}
LOGGER.info("Download Complete for NVD CVE - {}", nvdCveInfo.getId());
LOGGER.info("Download Complete for NVD CVE - {} ({} ms)", nvdCveInfo.getId(),
System.currentTimeMillis() - startDownload);
if (this.processorService == null) {
return null;
}

View File

@@ -114,10 +114,10 @@ public class NvdCve12Handler extends DefaultHandler {
in the nvd cve 2.0. */
String cpe = "cpe:/a:" + vendor + ":" + product;
if (num != null) {
cpe += ":" + num;
cpe += ':' + num;
}
if (edition != null) {
cpe += ":" + edition;
cpe += ':' + edition;
}
final VulnerableSoftware vs = new VulnerableSoftware();
vs.setCpe(cpe);

View File

@@ -157,6 +157,7 @@ public class ProcessTask implements Callable<ProcessTask> {
*/
private void processFiles() throws UpdateException {
LOGGER.info("Processing Started for NVD CVE - {}", filePair.getNvdCveInfo().getId());
final long startProcessing = System.currentTimeMillis();
try {
importXML(filePair.getFirst(), filePair.getSecond());
cveDB.commit();
@@ -178,6 +179,7 @@ public class ProcessTask implements Callable<ProcessTask> {
} finally {
filePair.cleanup();
}
LOGGER.info("Processing Complete for NVD CVE - {}", filePair.getNvdCveInfo().getId());
LOGGER.info("Processing Complete for NVD CVE - {} ({} ms)", filePair.getNvdCveInfo().getId(),
System.currentTimeMillis() - startProcessing);
}
}

View File

@@ -28,7 +28,8 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.utils.Checksum;
import org.slf4j.Logger;
@@ -43,6 +44,10 @@ import org.slf4j.LoggerFactory;
*/
public class Dependency implements Serializable, Comparable<Dependency> {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* The logger.
*/
@@ -336,7 +341,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
}
}
if (!found) {
LOGGER.debug("Adding new maven identifier {}", mavenArtifact.toString());
LOGGER.debug("Adding new maven identifier {}", mavenArtifact);
this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
}
}
@@ -692,6 +697,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
* @param o a dependency to compare
* @return an integer representing the natural ordering
*/
@Override
public int compareTo(Dependency o) {
return this.getFilePath().compareToIgnoreCase(o.getFilePath());
}
@@ -708,21 +714,24 @@ public class Dependency implements Serializable, Comparable<Dependency> {
return false;
}
final Dependency other = (Dependency) obj;
return ObjectUtils.equals(this.actualFilePath, other.actualFilePath)
&& ObjectUtils.equals(this.filePath, other.filePath)
&& ObjectUtils.equals(this.fileName, other.fileName)
&& ObjectUtils.equals(this.md5sum, other.md5sum)
&& ObjectUtils.equals(this.sha1sum, other.sha1sum)
&& ObjectUtils.equals(this.identifiers, other.identifiers)
&& ObjectUtils.equals(this.vendorEvidence, other.vendorEvidence)
&& ObjectUtils.equals(this.productEvidence, other.productEvidence)
&& ObjectUtils.equals(this.versionEvidence, other.versionEvidence)
&& ObjectUtils.equals(this.description, other.description)
&& ObjectUtils.equals(this.license, other.license)
&& ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities)
&& ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies)
&& ObjectUtils.equals(this.projectReferences, other.projectReferences)
&& ObjectUtils.equals(this.availableVersions, other.availableVersions);
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(this.actualFilePath, other.actualFilePath)
.append(this.filePath, other.filePath)
.append(this.fileName, other.fileName)
.append(this.md5sum, other.md5sum)
.append(this.sha1sum, other.sha1sum)
.append(this.identifiers, other.identifiers)
.append(this.vendorEvidence, other.vendorEvidence)
.append(this.productEvidence, other.productEvidence)
.append(this.versionEvidence, other.versionEvidence)
.append(this.description, other.description)
.append(this.license, other.license)
.append(this.vulnerabilities, other.vulnerabilities)
//.append(this.relatedDependencies, other.relatedDependencies)
.append(this.projectReferences, other.projectReferences)
.append(this.availableVersions, other.availableVersions)
.isEquals();
}
/**
@@ -732,14 +741,23 @@ public class Dependency implements Serializable, Comparable<Dependency> {
*/
@Override
public int hashCode() {
int hash = MAGIC_HASH_INIT_VALUE;
for (Object field : new Object[]{this.actualFilePath, this.filePath, this.fileName, this.md5sum,
this.sha1sum, this.identifiers, this.vendorEvidence, this.productEvidence, this.versionEvidence,
this.description, this.license, this.vulnerabilities, this.relatedDependencies, this.projectReferences,
this.availableVersions}) {
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(field);
}
return hash;
return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
.append(actualFilePath)
.append(filePath)
.append(fileName)
.append(md5sum)
.append(sha1sum)
.append(identifiers)
.append(vendorEvidence)
.append(productEvidence)
.append(versionEvidence)
.append(description)
.append(license)
.append(vulnerabilities)
//.append(relatedDependencies)
.append(projectReferences)
.append(availableVersions)
.toHashCode();
}
/**

View File

@@ -17,8 +17,9 @@
*/
package org.owasp.dependencycheck.dependency;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.io.Serializable;
@@ -29,6 +30,10 @@ import java.io.Serializable;
*/
public class Evidence implements Serializable, Comparable<Evidence> {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Used as starting point for generating the value in {@link #hashCode()}.
*/
@@ -194,12 +199,12 @@ public class Evidence implements Serializable, Comparable<Evidence> {
*/
@Override
public int hashCode() {
int hash = MAGIC_HASH_INIT_VALUE;
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.name));
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.source));
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.value));
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(this.confidence);
return hash;
return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
.append(StringUtils.lowerCase(name))
.append(StringUtils.lowerCase(source))
.append(StringUtils.lowerCase(value))
.append(confidence)
.toHashCode();
}
/**
@@ -230,6 +235,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
* @param o the evidence being compared
* @return an integer indicating the ordering of the two objects
*/
@Override
public int compareTo(Evidence o) {
if (o == null) {
return 1;

View File

@@ -24,7 +24,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.utils.DependencyVersion;
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
import org.owasp.dependencycheck.utils.Filter;
@@ -39,6 +39,10 @@ import org.slf4j.LoggerFactory;
*/
public class EvidenceCollection implements Serializable, Iterable<Evidence> {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* The logger.
*/
@@ -47,6 +51,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
* Used to iterate over highest confidence evidence contained in the collection.
*/
private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
@Override
public boolean passes(Evidence evidence) {
return evidence.getConfidence() == Confidence.HIGHEST;
}
@@ -55,6 +60,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
* Used to iterate over high confidence evidence contained in the collection.
*/
private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
@Override
public boolean passes(Evidence evidence) {
return evidence.getConfidence() == Confidence.HIGH;
}
@@ -63,6 +69,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
* Used to iterate over medium confidence evidence contained in the collection.
*/
private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
@Override
public boolean passes(Evidence evidence) {
return evidence.getConfidence() == Confidence.MEDIUM;
}
@@ -71,6 +78,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
* Used to iterate over low confidence evidence contained in the collection.
*/
private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
@Override
public boolean passes(Evidence evidence) {
return evidence.getConfidence() == Confidence.LOW;
}
@@ -79,6 +87,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
* Used to iterate over evidence that has was used (aka read) from the collection.
*/
private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
@Override
public boolean passes(Evidence evidence) {
return evidence.isUsed();
}
@@ -218,6 +227,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
*
* @return an Iterator<Evidence>.
*/
@Override
public Iterator<Evidence> iterator() {
return list.iterator();
}

View File

@@ -25,6 +25,11 @@ import java.io.Serializable;
*/
public class Identifier implements Serializable, Comparable<Identifier> {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Default constructor. Should only be used for automatic class
* creation as is the case with many XML parsers (for the parsing
@@ -216,6 +221,7 @@ public class Identifier implements Serializable, Comparable<Identifier> {
* @param o the object being compared
* @return an integer indicating the ordering
*/
@Override
public int compareTo(Identifier o) {
if (o == null) {
return -1;

View File

@@ -133,6 +133,7 @@ public class Reference implements Serializable, Comparable<Reference> {
* @param o the Reference being compared
* @return an integer indicating the ordering of the two objects
*/
@Override
public int compareTo(Reference o) {
if (source.equals(o.source)) {
if (name.equals(o.name)) {

View File

@@ -390,6 +390,7 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
* @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
* the specified vulnerability
*/
@Override
public int compareTo(Vulnerability v) {
return v.getName().compareTo(this.getName());
}

View File

@@ -39,6 +39,7 @@ public class VulnerabilityComparator implements Comparator<Vulnerability>, Seria
* @param o2 a second vulnerability
* @return the comparison
*/
@Override
public int compare(Vulnerability o1, Vulnerability o2) {
return o2.getName().compareTo(o1.getName());
}

View File

@@ -19,13 +19,13 @@ package org.owasp.dependencycheck.reporting;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An extremely simple wrapper around various escape utils to perform URL and HTML encoding within the reports. This
* class was created to simplify the velocity configuration and avoid using the "built-in" escape tool.
* An extremely simple wrapper around various escape utils to perform URL and HTML encoding within the reports. This class was
* created to simplify the velocity configuration and avoid using the "built-in" escape tool.
*
* @author Jeremy Long
*/
@@ -43,6 +43,9 @@ public class EscapeTool {
* @return the URL encoded text
*/
public String url(String text) {
if (text == null || text.isEmpty()) {
return text;
}
try {
return URLEncoder.encode(text, "UTF-8");
} catch (UnsupportedEncodingException ex) {
@@ -59,7 +62,10 @@ public class EscapeTool {
* @return the HTML encoded text
*/
public String html(String text) {
return StringEscapeUtils.escapeHtml(text);
if (text == null || text.isEmpty()) {
return text;
}
return StringEscapeUtils.escapeHtml4(text);
}
/**
@@ -69,6 +75,9 @@ public class EscapeTool {
* @return the XML encoded text
*/
public String xml(String text) {
return StringEscapeUtils.escapeXml(text);
if (text == null || text.isEmpty()) {
return text;
}
return StringEscapeUtils.escapeXml11(text);
}
}

View File

@@ -46,6 +46,7 @@ public class VelocityLoggerRedirect implements LogChute {
*
* @param rsvc the RuntimeServices
*/
@Override
public void init(RuntimeServices rsvc) {
// do nothing
}
@@ -57,6 +58,7 @@ public class VelocityLoggerRedirect implements LogChute {
* @param level the logging level
* @param message the message to be logged
*/
@Override
public void log(int level, String message) {
switch (level) {
case TRACE_ID:
@@ -87,6 +89,7 @@ public class VelocityLoggerRedirect implements LogChute {
* @param message the message to be logged
* @param t a throwable to log
*/
@Override
public void log(int level, String message, Throwable t) {
switch (level) {
case TRACE_ID:
@@ -115,6 +118,7 @@ public class VelocityLoggerRedirect implements LogChute {
* @param level the logging level
* @return true
*/
@Override
public boolean isLevelEnabled(int level) {
return true;
}

View File

@@ -86,7 +86,7 @@ public class SuppressionHandler extends DefaultHandler {
/**
* The current node text being extracted from the element.
*/
private StringBuffer currentText;
private StringBuilder currentText;
/**
* Handles the start element event.
@@ -100,7 +100,7 @@ public class SuppressionHandler extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentAttributes = attributes;
currentText = new StringBuffer();
currentText = new StringBuilder();
if (SUPPRESS.equals(qName)) {
rule = new SuppressionRule();
final String base = currentAttributes.getValue("base");

View File

@@ -26,6 +26,11 @@ import java.io.IOException;
*/
public class SuppressionParseException extends IOException {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new SuppressionParseException.
*/

View File

@@ -20,6 +20,7 @@ package org.owasp.dependencycheck.suppression;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Vulnerability;
@@ -381,30 +382,7 @@ public class SuppressionRule {
* @return true if the property type does not specify a version; otherwise false
*/
boolean cpeHasNoVersion(PropertyType c) {
if (c.isRegex()) {
return false;
}
if (countCharacter(c.getValue(), ':') == 3) {
return true;
}
return false;
}
/**
* Counts the number of occurrences of the character found within the string.
*
* @param str the string to check
* @param c the character to count
* @return the number of times the character is found in the string
*/
int countCharacter(String str, char c) {
int count = 0;
int pos = str.indexOf(c) + 1;
while (pos > 0) {
count += 1;
pos = str.indexOf(c, pos) + 1;
}
return count;
return !c.isRegex() && StringUtils.countMatches(c.getValue(), ':') == 3;
}
/**
@@ -442,43 +420,43 @@ public class SuppressionRule {
final StringBuilder sb = new StringBuilder();
sb.append("SuppressionRule{");
if (filePath != null) {
sb.append("filePath=").append(filePath).append(",");
sb.append("filePath=").append(filePath).append(',');
}
if (sha1 != null) {
sb.append("sha1=").append(sha1).append(",");
sb.append("sha1=").append(sha1).append(',');
}
if (gav != null) {
sb.append("gav=").append(gav).append(",");
sb.append("gav=").append(gav).append(',');
}
if (cpe != null && !cpe.isEmpty()) {
sb.append("cpe={");
for (PropertyType pt : cpe) {
sb.append(pt).append(",");
sb.append(pt).append(',');
}
sb.append("}");
sb.append('}');
}
if (cwe != null && !cwe.isEmpty()) {
sb.append("cwe={");
for (String s : cwe) {
sb.append(s).append(",");
sb.append(s).append(',');
}
sb.append("}");
sb.append('}');
}
if (cve != null && !cve.isEmpty()) {
sb.append("cve={");
for (String s : cve) {
sb.append(s).append(",");
sb.append(s).append(',');
}
sb.append("}");
sb.append('}');
}
if (cvssBelow != null && !cvssBelow.isEmpty()) {
sb.append("cvssBelow={");
for (Float s : cvssBelow) {
sb.append(s).append(",");
sb.append(s).append(',');
}
sb.append("}");
sb.append('}');
}
sb.append("}");
sb.append('}');
return sb.toString();
}
}

View File

@@ -36,11 +36,12 @@ public final class DateUtil {
*
* @param date the date to be checked.
* @param compareTo the date to compare to.
* @param range the range in days to be considered valid.
* @param dayRange the range in days to be considered valid.
* @return whether or not the date is within the range.
*/
public static boolean withinDateRange(long date, long compareTo, int range) {
final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0;
return differenceInDays < range;
public static boolean withinDateRange(long date, long compareTo, int dayRange) {
// ms = dayRange x 24 hours/day x 60 min/hour x 60 sec/min x 1000 ms/sec
final long msRange = dayRange * 24L * 60L * 60L * 1000L;
return (compareTo - date) < msRange;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* <p>
@@ -37,7 +37,7 @@ import org.apache.commons.lang.StringUtils;
*
* @author Jeremy Long
*/
public class DependencyVersion implements Iterable, Comparable<DependencyVersion> {
public class DependencyVersion implements Iterable<String>, Comparable<DependencyVersion> {
/**
* Constructor for a empty DependencyVersion.
@@ -103,7 +103,8 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
*
* @return an iterator for the version parts
*/
public Iterator iterator() {
@Override
public Iterator<String> iterator() {
return versionParts.iterator();
}
@@ -114,7 +115,7 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
*/
@Override
public String toString() {
return StringUtils.join(versionParts.toArray(), ".");
return StringUtils.join(versionParts, '.');
}
/**

View File

@@ -18,7 +18,6 @@
package org.owasp.dependencycheck.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
@@ -26,13 +25,13 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException;
@@ -50,10 +49,6 @@ public final class ExtractionUtil {
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
/**
* The buffer size to use when extracting files from the archive.
*/
private static final int BUFFER_SIZE = 4096;
/**
* Private constructor for a utility class.
@@ -108,12 +103,10 @@ public final class ExtractionUtil {
} else {
final File file = new File(extractTo, entry.getName());
if (engine == null || engine.accept(file)) {
BufferedOutputStream bos = null;
FileOutputStream fos;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
transferUsingBuffer(zis, bos);
IOUtils.copy(zis, fos);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
final String msg = String.format("Unable to find file '%s'.", file.getName());
@@ -123,7 +116,7 @@ public final class ExtractionUtil {
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
throw new ExtractionException(msg, ex);
} finally {
closeStream(bos);
closeStream(fos);
}
}
}
@@ -189,13 +182,11 @@ public final class ExtractionUtil {
while ((entry = input.getNextEntry()) != null) {
if (entry.isDirectory()) {
final File dir = new File(destination, entry.getName());
if (!dir.exists()) {
if (!dir.mkdirs()) {
final String msg = String.format(
"Unable to create directory '%s'.",
dir.getAbsolutePath());
throw new AnalysisException(msg);
}
if (!dir.exists() && !dir.mkdirs()) {
final String msg = String.format(
"Unable to create directory '%s'.",
dir.getAbsolutePath());
throw new AnalysisException(msg);
}
} else {
extractFile(input, destination, filter, entry);
@@ -225,13 +216,11 @@ public final class ExtractionUtil {
if (filter.accept(file.getParentFile(), file.getName())) {
LOGGER.debug("Extracting '{}'",
file.getPath());
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
createParentFile(file);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
transferUsingBuffer(input, bos);
IOUtils.copy(input, fos);
} catch (FileNotFoundException ex) {
LOGGER.debug("", ex);
final String msg = String.format("Unable to find file '%s'.",
@@ -244,29 +233,11 @@ public final class ExtractionUtil {
file.getName());
throw new ExtractionException(msg, ex);
} finally {
closeStream(bos);
closeStream(fos);
}
}
}
/**
* Transfers data from one stream to another using a buffer.
*
* @param input the input stream
* @param bos the output stream
* @throws IOException thrown if there is an error reading/writing to the streams
*/
private static void transferUsingBuffer(InputStream input,
BufferedOutputStream bos) throws IOException {
int count;
final byte[] data = new byte[BUFFER_SIZE];
while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
bos.write(data, 0, count);
}
bos.flush();
}
/**
* Closes the stream.
*
@@ -291,13 +262,11 @@ public final class ExtractionUtil {
private static void createParentFile(final File file)
throws ExtractionException {
final File parent = file.getParentFile();
if (!parent.isDirectory()) {
if (!parent.mkdirs()) {
final String msg = String.format(
"Unable to build directory '%s'.",
parent.getAbsolutePath());
throw new ExtractionException(msg);
}
if (!parent.isDirectory() && !parent.mkdirs()) {
final String msg = String.format(
"Unable to build directory '%s'.",
parent.getAbsolutePath());
throw new ExtractionException(msg);
}
}
}

View File

@@ -23,6 +23,7 @@ public abstract class Filter<T> {
public Iterable<T> filter(final Iterable<T> iterable) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return filter(iterable.iterator());
}
@@ -39,10 +40,12 @@ public abstract class Filter<T> {
toNext();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public T next() {
if (next == null) {
throw new NoSuchElementException();
@@ -52,6 +55,7 @@ public abstract class Filter<T> {
return returnValue;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}

View File

@@ -1,47 +0,0 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.FilterInputStream;
import java.io.InputStream;
/**
* NonClosingStream is a stream filter which prevents another class that processes the stream from closing it. This is
* necessary when dealing with things like JAXB and zipInputStreams.
*
* @author Jeremy Long
*/
public class NonClosingStream extends FilterInputStream {
/**
* Constructs a new NonClosingStream.
*
* @param in an input stream.
*/
public NonClosingStream(InputStream in) {
super(in);
}
/**
* Prevents closing of the stream.
*/
@Override
public void close() {
// don't close the stream.
}
}

View File

@@ -21,6 +21,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor;
/**
* A simple pojo to hold data related to a Maven POM file.
*
@@ -307,33 +310,41 @@ public class Model {
* @return the interpolated text.
*/
public static String interpolateString(String text, Properties properties) {
final Properties props = properties;
if (text == null) {
if (null == text || null == properties) {
return text;
}
if (props == null) {
return text;
}
final int pos = text.indexOf("${");
if (pos < 0) {
return text;
}
final int end = text.indexOf("}");
if (end < pos) {
return text;
}
final String propName = text.substring(pos + 2, end);
String propValue = interpolateString(props.getProperty(propName), props);
if (propValue == null) {
propValue = "";
}
final StringBuilder sb = new StringBuilder(propValue.length() + text.length());
sb.append(text.subSequence(0, pos));
sb.append(propValue);
sb.append(text.substring(end + 1));
return interpolateString(sb.toString(), props); //yes yes, this should be a loop...
final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties));
return substitutor.replace(text);
}
/**
* Utility class that can provide values from a Properties object to a StrSubstitutor.
*/
private static class PropertyLookup extends StrLookup {
/**
* Reference to the properties to lookup.
*/
private final Properties props;
/**
* Constructs a new property lookup.
*
* @param props the properties to wrap.
*/
PropertyLookup(Properties props) {
this.props = props;
}
/**
* Looks up the given property.
*
* @param key the key to the property
* @return the value of the property specified by the key
*/
@Override
public String lookup(String key) {
return props.getProperty(key);
}
}
}

View File

@@ -100,7 +100,7 @@ public class PomHandler extends DefaultHandler {
/**
* The current node text being extracted from the element.
*/
private StringBuffer currentText;
private StringBuilder currentText;
/**
* Handles the start element event.
@@ -113,7 +113,7 @@ public class PomHandler extends DefaultHandler {
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentText = new StringBuffer();
currentText = new StringBuilder();
stack.push(qName);
if (LICENSE.equals(qName)) {
license = new License();

View File

@@ -26,6 +26,11 @@ import java.io.IOException;
*/
public class PomParseException extends IOException {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new SuppressionParseException.
*/

View File

@@ -16,4 +16,8 @@ org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer
org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer
org.owasp.dependencycheck.analyzer.AutoconfAnalyzer
org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer
org.owasp.dependencycheck.analyzer.CMakeAnalyzer
org.owasp.dependencycheck.analyzer.CMakeAnalyzer
org.owasp.dependencycheck.analyzer.NodePackageAnalyzer
org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer
org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer
org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer

Some files were not shown because too many files have changed in this diff Show More