Compare commits

..

278 Commits

Author SHA1 Message Date
Jeremy Long
f333ef76d9 version 1.2.6
Former-commit-id: d32ff0d840fc1d1a3153da73158adc125a589efc
2014-11-16 09:44:11 -05:00
Jeremy Long
af5ba6854e minor format change
Former-commit-id: 138be9fe55a362d21021b428b36ac65e621fd88a
2014-11-16 09:43:26 -05:00
Jeremy Long
8b7ce06793 initial version
Former-commit-id: efb4fec83ee9d788b3a5b21c683f52dd91113ec0
2014-11-16 08:25:13 -05:00
Jeremy Long
297a5e516f switched to using commons.io.FileUtils to delete files
Former-commit-id: e63309f20e7af759233db5486acc85f2c5c6806d
2014-11-16 08:24:55 -05:00
Jeremy Long
92b11526be updated log messages
Former-commit-id: 4f58ed64efbee2a2d604bdc5bd51394e152bd408
2014-11-16 08:24:17 -05:00
Jeremy Long
299350f655 correctly closed streams when extracting a gzip archive
Former-commit-id: 0a0c917cc3e4c4a004823fba9b7f8ab53f90d557
2014-11-16 06:21:02 -05:00
Jeremy Long
127eafc9b3 removed unused field
Former-commit-id: f44e6398f946abe2faa8ab1b2e3813a6831b9c66
2014-11-16 06:20:27 -05:00
Jeremy Long
ad1ad3a997 turned off checkstyle for a few lines
Former-commit-id: 62bf63649427363c0d86bd72acbb76a9772d1da3
2014-11-16 06:20:07 -05:00
Jeremy Long
82151c5b3f initial version of the test for DownloadTask
Former-commit-id: 5c82a5dda739525be25eed5ee763effe839758d0
2014-11-15 08:23:54 -05:00
Jeremy Long
90457c89ff updated NVD CVE URLs to use gzipped files
Former-commit-id: ca3c5ec40458f200a19cfcda36d518cf4de5a65a
2014-11-15 08:23:13 -05:00
Jeremy Long
3f3ac86d38 minor change to test cases
Former-commit-id: bbfc241e7576b508af819f7fe66892da0511e549
2014-11-15 08:22:43 -05:00
Jeremy Long
aa126039e5 updated NVD CVE URLs to use gzipped files
Former-commit-id: 25c0c2e5df3a6626fae5401209fac93b105b3392
2014-11-15 08:21:44 -05:00
Jeremy Long
662815b1ee added an extract phase if the downloaded file is a .gz
Former-commit-id: 0385e9a7922bc18eccb3b3075cc866c462ae6f2b
2014-11-15 08:21:03 -05:00
Jeremy Long
243c36849c noop
Former-commit-id: e155fa37527c62925bdb7e52d539329e3f9ebabe
2014-11-15 08:20:15 -05:00
Jeremy Long
52d5baaf3f reformated and added checkstyle corrections
Former-commit-id: c68e06287fdd09768c9fade7e534ca421899c9c5
2014-11-12 16:04:23 -05:00
Jeremy Long
89217f778e added package-info
Former-commit-id: 78bd4ce6243fadc58524ec48bb0d964205e044cd
2014-11-12 15:44:43 -05:00
Jeremy Long
9bc9bc9169 made enabled final
Former-commit-id: ded2d5de559091d8383ec26941f166018c33bb7a
2014-11-12 15:44:18 -05:00
Jeremy Long
6b73430473 added javadoc and changes suggested by checkstyle
Former-commit-id: 5f216b873b2d1845747fa4a77159399e818aef5a
2014-11-12 15:43:36 -05:00
Jeremy Long
5ca5bca3df updated javadoc
Former-commit-id: 7b00991a0cf90ca34c8c54b8297014b01e676b04
2014-11-11 15:13:01 -05:00
Jeremy Long
89ab382a18 added additional tests for compareto(version)
Former-commit-id: 0a02681251a30e6b675461b7487198a1cc7eb850
2014-11-11 14:43:47 -05:00
Jeremy Long
bad425c0d7 added test for isAffected
Former-commit-id: 36a6d28ff03e41307574ee40381b0833c5c4ab01
2014-11-11 14:43:15 -05:00
Jeremy Long
cdbbb1b94c made isAffected protected instead of private so that tests could be added
Former-commit-id: e7fd58900b4c8ebbaf06d476870defa4fc921628
2014-11-11 14:42:34 -05:00
Jeremy Long
0a9d8a9b22 reformated and changed logging level from info to fine
Former-commit-id: 035ca7c4d83322734f16f0b51f695bf7e4caa7b0
2014-11-11 14:41:40 -05:00
Jeremy Long
e662041d06 reformated and changed isEnabled to a getter by adding checkEnabled that is called during initialization
Former-commit-id: 3bfb0dd2da37d718708d047e425fb8b125dddf34
2014-11-11 14:41:08 -05:00
Jeremy Long
155464bc87 reformated and changed isEnabled to a getter by adding checkEnabled that is called during initialization
Former-commit-id: d5c1224709469fccacfad7e22cf5a44eecdcab36
2014-11-11 14:40:48 -05:00
Jeremy Long
06cd811ae4 fixed xlint unchecked call warnings
Former-commit-id: b74ee0e63568b7b222f0459ad66a7e281b2f2e2f
2014-11-11 13:41:20 -05:00
Jeremy Long
1b31268f59 Merge branch 'colezlaw-master'
Former-commit-id: fdb3a7414550752692ed807d71782f54cabbdac6
2014-11-10 05:41:10 -05:00
Will Stranathan
b57ef7291f No more separate proxy configuration for Central search. Renamed everything to do with Solr to Central.
Former-commit-id: 4bcee86abf4415bfafc386d10018d9fcb2f6cec4
2014-11-09 21:07:26 -05:00
Jeremy Long
c3bf6aa3f8 updated documentation to reflect change with NexusAnalyzer
Former-commit-id: 6a16bb3fc9f45a77d030d4d0f9999b764fd6fa12
2014-11-09 20:07:22 -05:00
Jeremy Long
d2fa14bbe2 updated documentation to reflect change with NexusAnalyzer
Former-commit-id: bbe1286d3ff9e4886b2eb52fe0ff04962922dd06
2014-11-09 20:06:32 -05:00
Jeremy Long
9b6e55e90c Merge branch 'colezlaw-master'
Former-commit-id: 80adf73356e1a2d24a53cf0f20af1356638084d8
2014-11-09 19:54:03 -05:00
Jeremy Long
afb07b651f Merge branch 'master' of github.com:colezlaw/DependencyCheck into colezlaw-master
Former-commit-id: 1158591ef47032ceed72654ebde6ef5f20782f75
2014-11-09 19:53:26 -05:00
Jeremy Long
e6806fdf2b patch to resolve issue #137 - the output path can be a file name if the format is not ALL
Former-commit-id: 05c638b21f09842781e105259ff58819e4bd3e8c
2014-11-09 19:52:42 -05:00
Will Stranathan
e5ff2cff4e Squashed commits for the new Solr/Central Search capability
Former-commit-id: 28ca3ca0ff5de4e097082f6f73003c0a67455efd
2014-11-08 10:54:02 -05:00
Will Stranathan
17d7d47b9a Renamed Solr to Central search
Former-commit-id: b8bdca6be89497f9baf29c8762803b4652e4974b
2014-11-08 10:53:17 -05:00
Will Stranathan
64e32061ab Re-making due to merge conflict from origin
Former-commit-id: 34a9f3410131b51048ee7f89e8aed2189dafe7fb
2014-11-08 08:50:53 -05:00
Will Stranathan
931110ba6c Initial checkin of work on a Solr analyzer which will replace Nexus on Internet checks
Former-commit-id: 09337f6416fa3140c00413426e17e39c4a1fadc6
2014-11-08 08:47:42 -05:00
Jeremy Long
d90e7820cd improved file path validation and error handling
Former-commit-id: 20d4011b031ac956e9803e807de75e7e505172ae
2014-11-08 06:08:21 -05:00
Jeremy Long
824898dba5 patch for issue #155
Former-commit-id: 57b144d94354c48c9bebabae2cc3d0c120fd2138
2014-11-07 06:42:54 -05:00
Jeremy Long
761dd61ed4 added additional test jar for issue #155
Former-commit-id: 0f8bf0a058eb263f13bd5d0d4262255153201eb5
2014-11-07 06:42:00 -05:00
Jeremy Long
89c63e6d87 checkstyle corrections
Former-commit-id: 77b519236f1afe7ad8eab0407d055e7f9ab4745f
2014-11-05 21:52:52 -05:00
Jeremy Long
a2361f9327 checkstyle corrections
Former-commit-id: b0ad94a8b1ce31891f788fd44e1a9df59775a691
2014-11-05 21:42:32 -05:00
Jeremy Long
ea15205be8 pmd corrections
Former-commit-id: 7cdc5b009285b9b428d4e731cb4b493a24453a9f
2014-11-05 21:31:00 -05:00
Jeremy Long
0a45048535 checkstyle corrections
Former-commit-id: 8807237a0a38f390298a19507ed55d9df156663f
2014-11-05 21:24:34 -05:00
Jeremy Long
1c51655ce3 checkstyle corrections
Former-commit-id: b7acf0b29d86a17f03f996d8d4b7a47e3a9f5eb9
2014-11-05 21:08:34 -05:00
Jeremy Long
7749f0da7c updated to exclude apache ant code from checkstyle
Former-commit-id: 06ab2cb9c3b15c182dac3cd1d0580f6002d607f8
2014-11-05 21:07:08 -05:00
Jeremy Long
5695238f95 updated to exclude apache ant code from PMD and findbugs
Former-commit-id: ce8b95e5f7ba4a98036cce46edc066ff2f2afb79
2014-11-05 21:06:23 -05:00
Jeremy Long
e1feeb7e21 removed failing test case
Former-commit-id: ab7f81d133a7c8cbfed52300e3f31a92121206b7
2014-11-05 19:18:41 -05:00
Jeremy Long
84fecaf040 updated documentation to show that Ant style paths and excludes can now be used
Former-commit-id: be99efc13478905e282d292986821a1851d0f389
2014-11-05 06:26:58 -05:00
Jeremy Long
da77727673 changes to support Ant style paths to resolve issue #153
Former-commit-id: b1666d6652891c4b012457fd5de7f8230938fb45
2014-11-05 06:20:15 -05:00
Jeremy Long
f8c913a3e8 small modification to warnings
Former-commit-id: 1ee729d27fdd7f394df0ea00efcb9f5e2bf663cd
2014-11-05 06:19:43 -05:00
Jeremy Long
2024881ee1 fixed logging level when files cannot be deleted
Former-commit-id: d62acbe447b5cc78b992d910c9431c006e658b2e
2014-11-05 06:19:14 -05:00
Jeremy Long
35ed3a51e5 initial version of InvalidScanPathException
Former-commit-id: a1f909f4e3988ae2f5f00fe72033bfdd7ef89676
2014-11-05 06:17:27 -05:00
Jeremy Long
24b1c4d0a4 removed wild card pattern matching during scan
Former-commit-id: 183963237c378641467f7277f68ba74156442485
2014-11-04 05:50:58 -05:00
Jeremy Long
7ec2458fb5 moved CliParser
Former-commit-id: 69ea743196109849d078df8f7071af0a3027fe99
2014-11-04 05:33:18 -05:00
Jeremy Long
175feaea23 added a modified copy of DirectoryScanner from Apache Ant to resolve issue #153
Former-commit-id: e37eb42cc574e4255533a0e7fbe78f5ed0c83146
2014-11-04 05:27:46 -05:00
Jeremy Long
dda6cf728b added suppression for opendj-ldap-sdk to fix issue #165
Former-commit-id: e8dc84bea2350eb5539475cf77650fafb118f3a4
2014-11-01 07:08:00 -04:00
Jeremy Long
a7fd410b01 stopped trimming org and com off of the groupid so it is consistent with other analyzers
Former-commit-id: c22d3b7af9af00c28ee0df80ba706f70399b80ef
2014-11-01 06:51:05 -04:00
Jeremy Long
d281c36733 updated suppression rule for jersey-client
Former-commit-id: 81920e19da3c29de46207c2132f225cb8c77a840
2014-11-01 06:35:28 -04:00
Jeremy Long
dc91e44c0a added jersey-client 1.11.1 as an optional test dependency
Former-commit-id: d837418656cbfd857adb90662a4d2604fd77a78e
2014-11-01 06:35:05 -04:00
Jeremy Long
7967a858f4 Merge branch 'ctrl-alt-dev-master'
Former-commit-id: 18b9ce0c578195a3275c4cb54ed14f6aff953d2b
2014-10-25 08:10:14 -04:00
Jeremy Long
2081407e38 added pom evidence to dependency - yes, this moves some analysis to the plugin; but in this case that is okay and will allow future enhancements
Former-commit-id: f69fd0701a8db1ab729199c4090dee1cd023d114
2014-10-25 08:09:45 -04:00
Jeremy Long
976eabd527 noop
Former-commit-id: 8c867c80dfb8180ba308837a09b33ac17fd8273a
2014-10-25 08:08:26 -04:00
Jeremy Long
b6d6a5de2b minor changes to clean up test cases
Former-commit-id: 62d409fa6f50d3bbec881277a4604acca7278faa
2014-10-25 08:07:56 -04:00
Jeremy Long
2d58cfe0ce fixed link to the NVD
Former-commit-id: 73ca530e569d4376999c155a8bc1256d935209bf
2014-10-25 08:07:20 -04:00
Jeremy Long
9df8bdff5f cleaned up code to use isEmpty instead of "".equals(string)
Former-commit-id: 8469f91a948ab2ab5b0ce61865a0b11cd6d11717
2014-10-25 08:06:56 -04:00
Jeremy Long
c86b821951 suppressed warning on unchecked cast
Former-commit-id: 633151a31b613071c7bd3e939c6a5c16864b8b88
2014-10-25 08:06:15 -04:00
Jeremy Long
4def086bf9 removed comments
Former-commit-id: 2c48f5b93a97a0642fbc37edd603b0d0baca4368
2014-10-25 08:05:26 -04:00
Jeremy Long
885c890d7d changed the analyzer to use the actual file name rather then the display name
Former-commit-id: 9cc348aaef8fac5e6c64220d94428f168ea8855b
2014-10-25 08:05:01 -04:00
Jeremy Long
06060a6694 improved error handling of invalid search strings
Former-commit-id: 97250e44b27e009b2480d25f8c2ebb7566038086
2014-10-25 08:04:33 -04:00
Jeremy Long
70667814f6 changed display name of files contained in archives so that it doesn't look like an invalid path
Former-commit-id: db3a7edadef81dd7e66c68cf0f4cdf43e12936b6
2014-10-25 08:03:47 -04:00
Jeremy Long
766b7a940c changed scan methods to return a list of dependencies instead of void
Former-commit-id: f0fd1e06708de3159acff0147968b5508a54fc05
2014-10-25 08:02:36 -04:00
Jeremy Long
0c37586357 added Xlint:unchecked
Former-commit-id: e26970bf2cd4606b777bddfc806ba74227da9cba
2014-10-25 08:00:11 -04:00
Jeremy Long
b4aa55ce1f Merge branch 'master' of github.com:ctrl-alt-dev/DependencyCheck into ctrl-alt-dev-master
Former-commit-id: 4d1ab5ecacf0ca7354f57d3a49accd5a173e0a26
2014-10-24 05:36:40 -04:00
Jeremy Long
109443ce77 changed the name property of dependencies identified within an archive
Former-commit-id: 5d778afea68c881efea628d9ecc28596d3cbc9d6
2014-10-23 06:09:39 -04:00
Will Stranathan
5f38741831 Initial checkin of work on a Solr analyzer which will replace Nexus on Internet checks
Former-commit-id: 7b51d0cb1d23122bc73261424b66df24f72370cd
2014-10-22 22:35:03 -04:00
Jeremy Long
c6f391501d added test case for patch to issue #156
Former-commit-id: 8fa1de0566760a41d65614921f4bb764178151f8
2014-10-22 21:43:23 -04:00
Jeremy Long
d1f3105fbd added appropriate sorting to resolve issue #156
Former-commit-id: b5d0dd3e9d337417ea3483b491035009269eaa5c
2014-10-22 21:42:51 -04:00
Jeremy Long
8f88ca9d3d corrected compareTo to use file path, not just file name
Former-commit-id: 98e19c402cd5824aed4b3b4923b7ef72359752cf
2014-10-22 21:12:40 -04:00
Erik Hooijmeijer
f9e4ca0cc2 corrected javadoc
Former-commit-id: 3e0533a8a36afcacb647610f352bfd854e505272
2014-10-22 19:10:54 +02:00
Erik Hooijmeijer
5caf023677 added excludeInternalGroupIds configuration parameter that allows the exclusion of groupIds of internal projects. This is to speed up analysis as internal projects have no public vulnerabilites nor a sonatype listing but do frequently have names that collide with other libraries. The parameter can have multiple values, e.g. <excludeInternalGroupIds><groupId>nl.someinteral.project</groupId><groupId>org.another.one</groupId></excludeInternalGroupIds>
Former-commit-id: ffa0716366c6c7b65d1181f2bd945472b75b5483
2014-10-22 19:08:33 +02:00
Erik Hooijmeijer
35c2f4873c values from the project pom.xml are now taken into account as well
Former-commit-id: ca6c5b40f09959f162b337f2cb4268a57ce46d3d
2014-10-21 20:09:54 +02:00
Jeremy Long
1ed7bab375 additional updates for issue #162, if no pom is present in the jar, but it exists in the repo the pom from the repo will be used
Former-commit-id: 0d1603f45420b57b00149764acca1fe5bd3f3c83
2014-10-17 20:55:58 -04:00
Jeremy Long
f0d1bfb777 added an additional suppression for issue #162
Former-commit-id: 9c3403814b15cbcdebdc9e0d43253016548efb23
2014-10-16 06:57:24 -04:00
Jeremy Long
42519ac843 version 1.2.6-SNAPSHOT
Former-commit-id: 0b301bfa4a942e43976a34195a32982000f34d12
2014-10-14 06:28:14 -04:00
Jeremy Long
8869e13385 Merge pull request #161 from hansjoachim/exceptionTests
Uses ExpectedException to test for exceptions

Former-commit-id: 38f9b007311032db7edec0e1c345130409518855
2014-10-13 05:47:54 -04:00
Hans Joachim Desserud
8f9cbfe806 Unrelated: remove unused before/after
Former-commit-id: 68524208b8c0a197e9682aceec25cff0bc30ff56
2014-10-12 18:29:27 +02:00
Hans Joachim Desserud
6481938626 Test for exceptions with ExpectedException
Former-commit-id: 47c6c559196b4c10a5deb3698805ff7276f0aa83
2014-10-12 18:27:03 +02:00
Jeremy Long
9c7cc2acbf corrected the documentation
Former-commit-id: 428b6b3e07ed250ac11fb6c917c90888c0d20246
2014-10-10 20:03:36 -04:00
Jeremy Long
89a57d4ed3 removed velocity-tools to close issue #160
Former-commit-id: 5ca46405a5aa7521bd0a0de54500d848156491a6
2014-10-10 06:36:47 -04:00
Jeremy Long
732378592b corrected link to the unfortunate realities pdf
Former-commit-id: 285bcfd78f00fa514d3f96b5dcbac2fd18384177
2014-10-08 06:47:27 -04:00
Jeremy Long
19dc46660b corrected link to the unfortunate realities pdf
Former-commit-id: 75332bd18e6ac3ecac5dddda2f3945ae4003bd06
2014-10-08 06:21:55 -04:00
Jeremy Long
4aad3471af fixed javadoc
Former-commit-id: 2402251f2157864ee3c51dd571cb9d21e17856e6
2014-10-08 06:21:20 -04:00
Jeremy Long
92bd305b00 version 1.2.5
Former-commit-id: b3fe4ea80c4286684eda15a3b9f46cebc4f09ee8
2014-09-16 19:47:17 -04:00
Jeremy Long
f71eb09f74 updated sample report
Former-commit-id: 1de33769f71be8c86116b4a17d8282c69e0abed6
2014-09-16 19:47:07 -04:00
Jeremy Long
83d4a7bc18 moved test case dependency,jersey client, to the allTests profile
Former-commit-id: 58da4d9c21803362133f74c168aea256c51a5824
2014-09-16 05:24:43 -04:00
Jeremy Long
29595324c4 added suppression rules for jersey-client
Former-commit-id: cb8f4081c6d0fc2128a3a3dfda294a541c16adec
2014-09-13 07:10:17 -04:00
Jeremy Long
f9064e526f added test jar to the extended profile test dependencies
Former-commit-id: b24966e3936afd9337dbea5476a696ddf46efc65
2014-09-13 07:09:54 -04:00
Jeremy Long
93ec2e8639 fixed javadoc
Former-commit-id: d06907a74a6fd4cf9ac5e5774af63eda5aba02b3
2014-09-13 05:50:49 -04:00
Jeremy Long
0e2a31709a added test cases to ensure setting the base flag will prevent the identifier from being added to the suppressedIdentifiers collection
Former-commit-id: d369797a3b14fc2c42621d273d6f314e968848b9
2014-09-13 05:45:05 -04:00
Jeremy Long
c785b39eda added assertion to validate that the base flag is being processed
Former-commit-id: 0364e57af8f548d010f17f948492e9472433c675
2014-09-13 05:44:09 -04:00
Jeremy Long
8fab2f58da added the base property and skipped adding the vulnerability or identifier to the suppressed collection if this is a base suppression rule
Former-commit-id: a668d7d8b9345b6ad44bfff1ced4ab783a1f90d8
2014-09-13 05:43:16 -04:00
Jeremy Long
e44ee3bfe1 added parsing of the base flag
Former-commit-id: 02f533177846bcd4a98b31f851e91f438e1ddeaa
2014-09-13 05:42:01 -04:00
Jeremy Long
62065c9d28 corrected the removal of an identifier so that iterator.remove was correctly used
Former-commit-id: 252507772242cc7ff42ef9f310cfca3bec7cb075
2014-09-13 05:41:26 -04:00
Jeremy Long
c76275275f added the base=true flag to all base suppressions
Former-commit-id: ac77f3fc4ff80c182b7736554a1960e186e67d69
2014-09-13 05:40:37 -04:00
Jeremy Long
257f78879d added base attribute to suppression rules
Former-commit-id: bcadbd75b99471a56d604c2f158570305e9b4010
2014-09-13 05:40:06 -04:00
Jeremy Long
894263809c added base flag to one suppression entry
Former-commit-id: 7d6bbf36e5e35c2ee2fe8c901281996a34706036
2014-09-13 05:39:38 -04:00
Jeremy Long
c503935d6a updated to correctly close the ObjectOutputStream based on guidance from the CERT Java Secure Coding Standard
Former-commit-id: 1c7b929055f273d49b1203c117d7bb12162cfdb2
2014-09-12 06:36:00 -04:00
Jeremy Long
d4756c9eb8 updated base suppression list to include sandbox:sandbox - a php app
Former-commit-id: 087a4c5af2afd03a1d4703d2e1e5a1607a2e7ac9
2014-09-12 06:34:23 -04:00
Jeremy Long
0004767775 added fix for issue #147 to address springsource, non-core spring, jars being idenified as cpe://a:springsource:springframwork
Former-commit-id: 0a3182123be78a3f450cdef0bcc395907d27730a
2014-09-10 17:55:04 -04:00
Jeremy Long
74908642c7 added test dependency
Former-commit-id: fa4846dfa384639114f32ed3b7a0d91347b8dabf
2014-09-10 17:39:31 -04:00
Jeremy Long
aadfb71c98 fixed test case by removing a temporary test entry in DetermineCPE_full
Former-commit-id: 0f91c7b8e1d536c9d15176dc2d9a439da4e8ccdc
2014-09-10 17:37:54 -04:00
Jeremy Long
1244af649d updated to improve CPE matching so that if a broad match occured (cpe with no version number) we use the highest confidence version when generating the CPE identifier
Former-commit-id: 6e8c87a71522b1ca7cfa9d72ca419a792d1b17e7
2014-09-09 15:10:08 -04:00
Jeremy Long
7bd48cc811 updated version analysis to reduce false positives and increase accurate detection
Former-commit-id: 6097160434b7e98182738706790d82cdbd867175
2014-09-09 15:07:28 -04:00
Jeremy Long
8f3ce38418 re-ordered operations so that a new lucene index is no longer created on each call to calDetermineCPE_full
Former-commit-id: e2af1d893b47afe1ed36d1ab1e6840d47757b509
2014-09-07 08:28:44 -04:00
Jeremy Long
1b2d9b4245 fixed minor display bug
Former-commit-id: 65e1adcdc7677490907ee6eca68bf1174d355a3c
2014-09-07 07:20:45 -04:00
Jeremy Long
c6b2b34fde removed duplicative test of downloading XML
Former-commit-id: 97d1371609af2cc9583b0ac071a8606c93a34fbe
2014-09-07 06:59:50 -04:00
Jeremy Long
e58fc13fdb additional looping corrections in determineCPE() to break early if an identifier is found
Former-commit-id: 4ec4ffe598d9870a793da8980bb863633c1967d7
2014-09-06 19:09:38 -04:00
Jeremy Long
922d53d2e4 Increased the confidence on the pom artifact and groupid
Former-commit-id: b052b50353197e0f7cb419e6f618f2320da11183
2014-09-06 19:08:22 -04:00
Jeremy Long
fec53b3951 corrected looping in determineCPE()
Former-commit-id: 329f20687223f38273b2e23601b05fcea2b9122f
2014-09-06 06:37:12 -04:00
Jeremy Long
e72e2c6a02 corrected documention error with the reporting sets
Former-commit-id: ab503e5a710a69624a3216edea880e614b003ba8
2014-09-01 08:19:46 -04:00
Jeremy Long
08d001ee05 checkstyle corrections
Former-commit-id: ecc262c75890ef4c8760cb41e7948cb6decdf5d5
2014-09-01 08:13:53 -04:00
Jeremy Long
99d8a07f4a updated documentation as part of resolution for issue #144
Former-commit-id: f47171e52e22e75c582bed47c9d0e9df3945e148
2014-09-01 08:13:34 -04:00
Jeremy Long
eef565134b update to correct issue #79 - the internal report format is no longer supported
Former-commit-id: 4dc9a83008a75d97f3838aa1a41f1d93eb39f2de
2014-09-01 07:39:54 -04:00
Jeremy Long
9d78293437 fix for issue #128 - the application will no longer throw an exception on large files when generating the hash digest
Former-commit-id: aae811e5d10ca0ee5ac7316fa992b5c45e43d2be
2014-09-01 07:30:04 -04:00
Jeremy Long
fc0a556e5f checkstyle and findbugs corrections
Former-commit-id: 2bf90876b7c88bccb93135a0be43f01e49c3cd30
2014-08-30 15:51:24 -04:00
Jeremy Long
b6b070584f checkstyle corrections, added javadoc, etc.
Former-commit-id: 2b806cb8527a627d400644465bcf9f04d687d729
2014-08-30 15:19:52 -04:00
Jeremy Long
e13225eee6 initial version of aggreation completed for issue #19 - some cleanup still needs to happen before final release
Former-commit-id: 98c9af3004e2c725d0dca5d6847b65a4646c6a73
2014-08-30 07:50:27 -04:00
Jeremy Long
da20fb2922 added velocity-tools to base suppression as it should not be reported as struts
Former-commit-id: 4649d95a091def05ae249da42aa7d6f845b14d59
2014-08-30 07:48:02 -04:00
Jeremy Long
459c2beb12 noop
Former-commit-id: a51d953d0c60c39d845d69d66c87db8b904382c4
2014-08-29 05:41:31 -04:00
Jeremy Long
f1cc44dead removed the externalReport option
Former-commit-id: 4cc3ec2638140f8320eb8946d2154dae330786b0
2014-08-29 05:38:40 -04:00
Jeremy Long
d24cfdc382 resolved merge conflict
Former-commit-id: 4806c0c99bd35d64135ee22a12018e6a92c54059
2014-08-16 07:41:55 -04:00
Jeremy Long
ae4cc543f6 corrected outputFile name to correctly use the target directory from project.getBuild().getDirectory()
Former-commit-id: 7ef2ca45e502e945e7356f9c63845eb4e7b532fc
2014-08-16 07:30:34 -04:00
Jeremy Long
abdb3d17f9 added initial plumbing to support report aggregation per issue #19 - report aggregation is still not complete
Former-commit-id: df248d0c1a7f3628653717029f034a46afde742b
2014-08-16 07:29:35 -04:00
Jeremy Long
4095c5da38 made serializable
Former-commit-id: 27d8084ea981766791df05c5e9ef61dbe40ba32c
2014-08-16 07:27:28 -04:00
Jeremy Long
78fab728e4 added an additional generate method
Former-commit-id: 44b78b525da45918f3b4bc77b368f88e49361c95
2014-08-15 06:22:54 -04:00
Jeremy Long
52097a6867 initial version of the ReportAggregationMojo
Former-commit-id: e15575413d625c6b5c5f3d73f5a739e1890eec27
2014-08-15 06:02:04 -04:00
Jeremy Long
cb990b55b5 added the apache 2.0 license to the header
Former-commit-id: f7d5558f565abe9c3e1a04f79666137e4f67e017
2014-08-15 06:00:30 -04:00
Jeremy Long
5070fe303a added the configuration value mavenSettingsProxyId to inform users that if you have multiple proxies defined in settings.xml you can choose which one should be used
Former-commit-id: 20fa4a92d446fd30a882e07c37897907fb1638b1
2014-08-15 05:59:39 -04:00
Jeremy Long
b4405ebf3e minor changes to the TOC table - removed # of related dependencies and renamed CVE Impact to Highest Severity to clear up ambiguity
Former-commit-id: b8b14ab120d889057864eb6f93cadad9773b9171
2014-08-15 05:58:10 -04:00
Jeremy Long
d9e6bf5068 Merge pull request #145 from erik-wramner/fix-maven-proxy-bug
Modified Maven plugin to use proxy host as is, not as an URL. This works...

Former-commit-id: 53e28e6799ef13ca3d88ed00aaa1e0c3f24aa04b
2014-08-15 05:37:14 -04:00
erik-wramner
6822188f52 Modified Maven plugin to use proxy host as is, not as an URL. This works correctly for our proxy server with Maven 3.
Former-commit-id: 02e97e359b1c5d6d9f1dc9149c9fbed510d31559
2014-08-10 12:15:00 +02:00
Jeremy Long
15858d03ff moved reporting functions from the core maven plugin to a utility class
Former-commit-id: d63d2a7a5031038b9f86bbe94fc4a198374bd9f3
2014-08-08 14:44:26 -04:00
Jeremy Long
814a733258 moved reporting functions from the core maven plugin to a utility class
Former-commit-id: 0d8507b8534320189ea5f36d0fc1cac7d0843c0f
2014-08-08 14:43:00 -04:00
Jeremy Long
3ce85d8ca9 rework of report generation and added fix for proxy (patch for proxy was from Erik Wramner) to close issue #136
Former-commit-id: afc81123b31189618ade397b830bf421db2918f8
2014-08-08 14:42:23 -04:00
Jeremy Long
d3bff2f39d version 1.2.5-SNAPSHOT
Former-commit-id: 85ed1238022348f1e9496ffe3c95d4ff8e3d09c3
2014-08-05 18:55:30 -04:00
Jeremy Long
f2272730ac version 1.2.4
Former-commit-id: 4de7e508eb1885bb72e866960fa5402f72bf8e49
2014-08-05 18:45:36 -04:00
Jeremy Long
fe19c97d86 corrected link syntax
Former-commit-id: 01b9ea03864248a9c5427af6d7238c435c0a4fa7
2014-08-05 18:45:25 -04:00
Jeremy Long
56b447493e added additional error messages about the proxy if the download fails per issue #136
Former-commit-id: 7a5dcc58ab959a70b7e086a984f5d9289d749b99
2014-08-05 10:58:43 -04:00
Jeremy Long
e45b68eda7 fixed issue #140 - false positive is now suppressed
Former-commit-id: 4b584884e1eb5efa214b1af87d555e6866db917a
2014-08-05 10:44:33 -04:00
Jeremy Long
8df1ef5986 removed unused values for variables and fixed javadoc
Former-commit-id: 1fb0be5d88301c5a1043d88b93c052edcebe3c5c
2014-08-05 09:26:04 -04:00
Jeremy Long
dac34cda82 checkstyle corrections
Former-commit-id: a888649ce7d75b721e053d305a406ecddbdcdbc4
2014-08-05 09:25:08 -04:00
Jeremy Long
9925e30c8b removed useless parens
Former-commit-id: 00ddea8b437494cc32e47e3066a448015d95467b
2014-08-05 09:24:48 -04:00
Jeremy Long
dc5566b5ae updated the exclusion list for generated code
Former-commit-id: eeaccab472347cc5fcfe21552c7fc1e9ab8ea1de
2014-08-05 09:24:16 -04:00
Jeremy Long
8132ee651a added documentation for issue #139
Former-commit-id: 95fdcf4d95cbe50ba884be561fbec0e9977578a0
2014-08-05 09:23:47 -04:00
Jeremy Long
f49a134a3d updated sample report
Former-commit-id: 7f312fec5ffbd8daa609299efdc53b83e83e6bd6
2014-08-05 09:22:54 -04:00
Jeremy Long
bd955cda06 improved TOC per issue #138
Former-commit-id: 7cc7ccb9d0dd8257588438220bf61d78caa2bcec
2014-08-05 09:22:28 -04:00
Jeremy Long
c6dbc01912 ensured FileInputStream is correctly closed
Former-commit-id: 6e0362476f456e5af07e686fdccf04e600a97de8
2014-08-05 09:19:35 -04:00
Jeremy Long
fabe1aa940 checkstyle corrections
Former-commit-id: d23c5d17629f8484c1c07d328c9c1b74a678e062
2014-08-05 09:19:00 -04:00
Jeremy Long
ba5dbb94b8 removed fully qualified class name from jaxb instantiation
Former-commit-id: 15d5f9e2013daba62f7e32618958743e87e8ea79
2014-08-05 09:18:35 -04:00
Jeremy Long
6ccc053d7e added more documentation
Former-commit-id: 87a761ffe89d36fb2011d5a38d607c35178d70ec
2014-08-05 09:16:38 -04:00
Jeremy Long
cf21dfaa3a changed warning log message
Former-commit-id: 9a7fd59cd15e627ed103a6e797bc47518805276b
2014-08-04 08:05:31 -04:00
Jeremy Long
54ceb630de fixed project descriptions and corrected site deployment issues
Former-commit-id: 39373b0805b84b99c3e84dbad1c8a2301f277221
2014-08-04 06:24:00 -04:00
Jeremy Long
0a0c302cb2 re-orered the module listing
Former-commit-id: 1ec7ccbc98463c5b2af09c973a1bc83319630ec8
2014-08-04 06:22:11 -04:00
Jeremy Long
f6eef54566 added fix for issue #136
Former-commit-id: c259a419769b41e138d3cbb3811f1c24652601d5
2014-08-01 15:09:41 -04:00
Jeremy Long
a69804f84d updated documentation
Former-commit-id: e8b6c86e47cff66f72ffb53ccba4bef18479b43e
2014-08-01 14:31:19 -04:00
Jeremy Long
0b06b194b0 added XmlRootElement attribute
Former-commit-id: a3263e63c8c7b12c90ad388c8eda1ab09e43786c
2014-08-01 14:22:40 -04:00
Jeremy Long
73f6ce304c corrected jaxb newInstance
Former-commit-id: 32a1b759ad1e127784ae9bff902cca01c6faaad7
2014-08-01 14:21:55 -04:00
Jeremy Long
195818a432 minor changes to logger and added a catch for throwable
Former-commit-id: 0ca337442a3f60db9655c3527711ba16af3096a6
2014-08-01 06:02:22 -04:00
Jeremy Long
47c817de1c performance improvement for checksum calculations - using MappedByteBuffer
Former-commit-id: 5024926737f1abbae47da5e95615dd2f2bddbcc6
2014-07-20 07:54:54 -04:00
Jeremy Long
8b3894f213 removed version from maven usage
Former-commit-id: 234d0bc0e147cdb9ebf7d1c59e5ef53421589d42
2014-07-20 06:49:31 -04:00
Jeremy Long
a411252f07 Merge branch 'bkimminich-patch-1'
Former-commit-id: abe645b3693a6a387de9b36ffedf32382bd24f58
2014-07-20 06:39:13 -04:00
Jeremy Long
d7626aeb3f Merge branch 'patch-1' of github.com:bkimminich/DependencyCheck into bkimminich-patch-1
Former-commit-id: aa6a0fc0a9352a1a2d3d4a0dfceb428242b455fd
2014-07-20 06:38:58 -04:00
Jeremy Long
3565098650 converted abstract class to a final class with a private constructor
Former-commit-id: 582a421e69eac2bfc008ca8ee2fe88c7734c9a31
2014-07-20 06:36:33 -04:00
Jeremy Long
803fcf146b minor fix to test case
Former-commit-id: bf20319aed4f100d124cdeb7abeafe6598778891
2014-07-19 13:58:30 -04:00
Jeremy Long
d9d646c5fb fixed connection string property
Former-commit-id: 951cf212c80a52909cc2dd66e843b63b35991045
2014-07-19 13:57:36 -04:00
Jeremy Long
034a274b07 fixed copy paste error
Former-commit-id: 83c51cb5b43c635088025a2076121911af32a7ec
2014-07-19 13:57:15 -04:00
Jeremy Long
718d7af8bc updated to use the new getConnectionString implementation
Former-commit-id: c5bd68b3d2fb4c2470d6c50dc5f8f9f6036b9fce
2014-07-19 07:38:51 -04:00
Jeremy Long
860d3d9c8b made the ensureDBExists method perform a correct check rather then the previous hack
Former-commit-id: 5fae859fa7531761e78022eb2e8c4c41e6d5d150
2014-07-19 07:38:08 -04:00
Jeremy Long
f28b566992 added data.file_name and data.version
Former-commit-id: e692a13a216ec6808e3fd92397fd3c50854cfa56
2014-07-19 07:37:11 -04:00
Jeremy Long
1c261c7463 added more tests
Former-commit-id: 75a4e44d06838221b060c0569716e85e1c6fc996
2014-07-19 07:36:35 -04:00
Jeremy Long
226b2482b1 added data.file_name and data.version
Former-commit-id: 6f33c306170f96f344bb85aa7820cc94cd4d5eeb
2014-07-19 07:36:16 -04:00
Jeremy Long
ff346dc429 changed getConnectionString to allow a more dynamically constructed string based on more setting keys
Former-commit-id: 1fb18720ab1a1c6d947bc94366b8ee2ca9cb711e
2014-07-19 07:35:48 -04:00
Jeremy Long
2dcef25175 performance improvements for large files
Former-commit-id: 6a49a7066cb01c613b5c6f07c8497601a88e7f8d
2014-07-19 07:34:50 -04:00
Jeremy Long
46702bbb5c moved checkSumTest.file, checksum.java, and checksumTest.java to dependency-check-utils
Former-commit-id: 0c05e466b5fe071ca55552660d471431572c0558
2014-07-17 06:03:21 -04:00
Jeremy Long
5600c9bc69 removed commented out property
Former-commit-id: 2a07ced007c986d3ab127d8ff216f49c332f41c3
2014-07-17 06:01:59 -04:00
Jeremy Long
d7e46b1693 corrected the connection string in the test properties
Former-commit-id: 1c37d4bd4de49cddc34b92a27875e0a07eee600f
2014-07-17 06:00:59 -04:00
Jeremy Long
fe8c60ade1 added additional setting keys and methods getDataDirectory and getConnectionString
Former-commit-id: 5e8a55c498fa7ae5331ba4fbeb86cd68b9fd8eda
2014-07-17 06:00:06 -04:00
Jeremy Long
288892441f corrected javadoc
Former-commit-id: c0c7d8da486a08dfc3e9232b57166d4c496bb798
2014-07-17 05:59:10 -04:00
Jeremy Long
e1179a8e22 moved getConnectionString to the Settings class
Former-commit-id: d35df6d103505888ac4d87f964d8d615996ce614
2014-07-13 06:56:40 -04:00
Jeremy Long
4b06d0fd87 upgraded version on commons-compress to 1.8.1
Former-commit-id: 2dc8698035e18764e101b36b11faf9e5c7188c5b
2014-07-13 06:54:59 -04:00
Jeremy Long
464d91f45a fixed resource leaks found by coverity
Former-commit-id: 0e2d3b866853e2b906b9683e27602fd244298e55
2014-07-08 06:17:36 -04:00
Björn Kimminich
5cc7aa25cc Update README.md
- set version in POM snippet from 1.0.2 to 1.2.3
- set URL to Ant Task docs to http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html

Former-commit-id: 8a2176aee9948b5bfd0c1f08c6c7bb9fdadc45a1
2014-07-04 14:17:57 +02:00
Jeremy Long
20ec224070 updated version to 1.2.4-SNAPSHOT
Former-commit-id: 65d0e1ba5ed781e9f70ec7fd0c115a027e3bbc00
2014-06-28 08:14:49 -04:00
Jeremy Long
9cbcc29ddb added utils to the parent site
Former-commit-id: 2a80ad86f5ab94fb21131786d9dce3439269f8cb
2014-06-28 08:14:35 -04:00
Jeremy Long
0badbfc4a0 version 1.2.3
Former-commit-id: c355adf9813220c4b3dac3450e80a83a245209a6
2014-06-28 06:06:33 -04:00
Jeremy Long
e042148c62 Merge branch 'colezlaw-master'
Former-commit-id: 5654a0e5cd8b8524ac317a55a2af5a52408bc8ca
2014-06-26 20:33:45 -04:00
Jeremy Long
d8ba04ae7f Merge branch 'master' of github.com:colezlaw/DependencyCheck into colezlaw-master
Former-commit-id: 27bac793e5284df49c0804361c07d4ef559cb251
2014-06-26 20:33:35 -04:00
Jeremy Long
314d5fdad2 Merge branch 'colezlaw-suppression-fix'
Former-commit-id: 1e7d9df774347ea043fef8ef3f5d6ca4aebaa15a
2014-06-26 20:32:07 -04:00
Will Stranathan
5c874cafd1 Fixed suppression analyzer to load from input stream fixing failure
Former-commit-id: 4e6f8d7fddcf7ed26ad60b7aa8bc3a6b22ae19cc
2014-06-26 15:14:55 -04:00
Will Stranathan
8cafc14d09 Updated to 1.1 of GrokAssembly.exe to deal with exceptions
Former-commit-id: 8c1d6ad04e378f2a19e2fcdc9ebc1eab12be9aef
2014-06-24 10:16:53 -04:00
Jeremy Long
25ac5033fc snapshot version 1.2.3
Former-commit-id: 58f96e7ef71987a53626287f95b332f04b60a6f6
2014-06-22 21:33:58 -04:00
Jeremy Long
848be0db6c version 1.2.2
Former-commit-id: 8da06e1a2f4b41bccc22105d7bc758442bb14e57
2014-06-22 21:31:58 -04:00
Jeremy Long
0f9da0731e updated text
Former-commit-id: 7749b9ec6b0ce9502e1c7129bdec902ce5b43595
2014-06-22 21:22:32 -04:00
Jeremy Long
8bc2364cce added site information to the dependency-check utils
Former-commit-id: 7d8c4c3c2b98e0d492f4447e5f1dc1f071a2241a
2014-06-22 19:56:14 -04:00
Jeremy Long
b64916ce3f added file analyzer documentation
Former-commit-id: c0c29021cd1197f26942ff36c8b63220d1267c21
2014-06-22 19:55:21 -04:00
Jeremy Long
452955667c checkstyle correction
Former-commit-id: e5a891ea5b438e64e8a3aa5e697cb859d1a1f09a
2014-06-22 19:54:25 -04:00
Jeremy Long
f38bbf4cc7 minor javadoc correction
Former-commit-id: 45e621682304820fe17c17e92bd0aa5ac5dfd023
2014-06-22 19:53:59 -04:00
Jeremy Long
25eaa11a52 updated description
Former-commit-id: c8cb8b041ce351c2d33a3621f772e75d02950193
2014-06-22 19:53:38 -04:00
Jeremy Long
4b4da8d467 checkstyle/pmd/etc. corrections
Former-commit-id: 59883bd0b03c8690ce9a20120eafefe7c61384cd
2014-06-22 19:03:33 -04:00
Jeremy Long
13116c5381 added support for suppression by GAV (issue #124), created base suppression.xml (issue #123), and fixed false positives related to spring security (issue #130)
Former-commit-id: 330134211d022fec336dc1ca39205a94a088ee84
2014-06-22 16:34:39 -04:00
Jeremy Long
d2cd406a62 added additional test resources
Former-commit-id: b788c7420b82d8a108cd2335c536be667c2ab293
2014-06-22 16:32:48 -04:00
Jeremy Long
acbce05fbf updated to support suppression by maven coordinates (GAV) per issue #124
Former-commit-id: 3cff74ded9b0c352fb1d45e784d89c3c20f55467
2014-06-20 06:47:46 -04:00
Jeremy Long
bee4d3a338 fixed bug that left false positive, previously fixed, due to the file name modifications that the archive analyzer makes - regex needed updating to not just look for the start of the filename
Former-commit-id: 922a9edaf9123524585b97e6cb9f8efd4a389031
2014-06-14 07:04:02 -04:00
Jeremy Long
bce226002b added data.zip back after cleaning up history
Former-commit-id: 6d227bf38e8023eeb134c965f48fbf859aeb9600
2014-06-01 11:31:09 -04:00
Jeremy Long
a417db7c7a updated documentation to replace deprecated proxyUrl with proxyServer
Former-commit-id: 165e14fcb6b57d8a522875eaa65f5ee766c9b1af
2014-05-31 06:43:07 -04:00
Jeremy Long
0ffef12a8b deprecated the proxyUrl field replacing it with proxyServer; getter and setter for proxyUrl now just wrap proxyServer
Former-commit-id: 5f1fbdf2eda6f05252f81dd8bf7acd44c01b7b6f
2014-05-31 06:42:27 -04:00
Jeremy Long
4539b040e0 deprecated proxyUrl and replaced it with proxyServer
Former-commit-id: 3330de9b2c36742a0b93d478b7dadaccea00cd4a
2014-05-31 06:39:36 -04:00
Jeremy Long
f85014a86d deprecated proxyUrl and replaced it with proxyServer - using the deprecated configuration will still work but will generate a warning
Former-commit-id: d9ff32d6b6e2f4d088f95d52ee33f1d0df3457fd
2014-05-31 06:38:50 -04:00
Jeremy Long
d90d07c68b added code to disable the analyzer if initialization fails
Former-commit-id: 202baa329f07fb24921ce83660d596d46b71b663
2014-05-30 05:26:03 -04:00
Jeremy Long
ce292b84fa fixed spelling error in property name
Former-commit-id: 106e8e9128bc371ff78f3a73c3f0da6012761cba
2014-05-30 05:25:20 -04:00
Jeremy Long
01690860db renamed PROXY_URL to PROXY_SERVER to avoid confusion
Former-commit-id: 1fbc025fba68aff644a8b8582657e5ef30024a24
2014-05-24 07:06:59 -04:00
Jeremy Long
89fb2d4915 fixed error messages and added status code checks
Former-commit-id: d21ff11466908f07ca02a50269f08d76f16a243e
2014-05-24 07:06:46 -04:00
Jeremy Long
5cc3a42832 renamed PROXY_URL to PROXY_SERVER to avoid confusion
Former-commit-id: 730eebed21baddfbd90c42a95769f8781de95b56
2014-05-24 07:05:05 -04:00
Jeremy Long
60b0145e04 added a new initialize method that accepts a properties file path to load to make the class more versatile
Former-commit-id: 00ec19b51a20c4ce3329a7c3c075a1f3ba16859e
2014-05-21 06:42:43 -04:00
Jeremy Long
ce48823d38 Moved some of the utility classes from core to a new utils module
Former-commit-id: 2e6ff9631ff4c843f10db1e022e41e728394e420
2014-05-21 06:29:46 -04:00
Jeremy Long
d43fee5585 renamed CallableDownloadTask to DownloadTask
Former-commit-id: 4ed8987945722d99e0f23b2f379321a652f76348
2014-05-20 21:08:15 -04:00
Jeremy Long
5dc9e51dd4 fixed test cases
Former-commit-id: 081ea17023cef3313ce59dbf8ce7f2a8cff706eb
2014-05-17 08:04:20 -04:00
Jeremy Long
235fcccbd7 if maven identifier already exists we now update it with a hyperlink instead of adding a new one - the Jar analyzer may add a maven identifier based on the pom.xml
Former-commit-id: db0ae1145d000089fb10e0357566f03632a559b9
2014-05-17 08:04:03 -04:00
Jeremy Long
91c971b8fd cleaned up pom evidence collection and added a maven identifier if the GAV is available from the pom.xml
Former-commit-id: 0400863fea2cfe86a5601b3ae134e7e98a4b29c7
2014-05-17 08:03:04 -04:00
Jeremy Long
e43003cadc fixed false positives related to Apache POI and MS Office CPE/CVE per issue #126
Former-commit-id: cfde8d86cb339a9f2cf0b8c1f72f5ca198efab8a
2014-05-14 19:17:47 -04:00
Jeremy Long
9a96165655 Update JarAnalyze to resolve issue #127
Updated JarAnalyzer to resolve issue #127 - duplicate package and package name evidence in the report.

Former-commit-id: 067643f7e99a7a4f36438b18c07e92a5e8544089
2014-05-14 18:01:12 -04:00
Jeremy Long
994aef411c updated version to 1.2.2-SNAPSHOT
Former-commit-id: e1b07457515dcab0f00c6a0b36fadb58ecc3deeb
2014-05-10 08:41:37 -04:00
Jeremy Long
094a180935 updated to release version 1.2.1
Former-commit-id: d908eed4538f0928c8b108348d9d46ce6d2f57e0
2014-05-10 08:32:34 -04:00
Jeremy Long
74e9de6370 updated sample report
Former-commit-id: c55ddb623e21f046c90493b0724f7eb34225ea29
2014-05-10 07:25:42 -04:00
Jeremy Long
c7f31b3d79 fixed typo in log statement
Former-commit-id: 08192210f3c5bb322160fba678a56acb36af3198
2014-05-10 07:23:18 -04:00
Jeremy Long
98d0239d03 pmd correction to logger
Former-commit-id: 3c3b26ec8fbf4d2602c681ff02f460fe7e712914
2014-05-10 07:16:50 -04:00
Jeremy Long
ffeab147ce checkstyle corrections
Former-commit-id: f9ae61d41ba01b6931892a339a9b701ae3c91ce2
2014-05-10 07:13:07 -04:00
Jeremy Long
90bdbd6b84 updated version of presentation
Former-commit-id: ec47594f35f5cca92888e6c8578b0d123d31b898
2014-05-10 07:12:56 -04:00
Jeremy Long
e29dd3cd33 added additional test file
Former-commit-id: 8487a2f4ba7287f54f0b5f69bc39e63bee455172
2014-05-10 07:01:24 -04:00
Jeremy Long
23b95178ff updated to remove archive files from the list of dependencies - additionally, if a zip file appears to be a jar it will now make a copy of the zip and scan it as a jar
Former-commit-id: d927daea530abad2d578dbe0ff38b97d044b4775
2014-05-10 07:00:43 -04:00
Jeremy Long
9bde80357f patch to remove additional false positives due to SCM entries in the pom
Former-commit-id: 6101fae1b5957254ddbece5afc2db8edeb7bf9b8
2014-05-10 06:59:34 -04:00
Jeremy Long
1485733715 updated to use displayFileName field instead of FileName when writing information about dependencies
Former-commit-id: bd3383ac4831bc44db6b63083e47802cce04b520
2014-05-10 06:58:51 -04:00
Jeremy Long
d125a7f09d added displayFileName field to the dependency class
Former-commit-id: 248f5397d37ea6e2f333dc0fe357188865bdb446
2014-05-10 06:57:44 -04:00
Jeremy Long
77486dffd4 removed additional false positives as part of patch for issue #93 and #119
Former-commit-id: 86f48b30150f2ba4db99dfc2eb15a0ac50a6e383
2014-05-10 06:56:53 -04:00
Jeremy Long
c84bcb433f fixed spelling error
Former-commit-id: d3aed24d6691b58ef132e00f9827e27fceb9fc73
2014-05-07 19:33:59 -04:00
Jeremy Long
f1e5221257 Merge pull request #122 from colezlaw/master
Fixed logging order of GrokAssembly for bad assemblies. Using resources ...

Former-commit-id: 65a41d23df6ccfa8c4f05235da3d7c613e4290a0
2014-05-07 19:31:59 -04:00
Jeremy Long
b8bf01acc3 added checks before warning that a file could not be deleted
Former-commit-id: 098ea1889b49ade0c73385919906398c86627ab2
2014-05-07 19:31:21 -04:00
Jeremy Long
65aa7bd1de fixed display bug when only one CPE exists for a given CVE
Former-commit-id: 18535dc408a51e516626ec4c43a3e72b01fd28f0
2014-05-07 19:30:45 -04:00
Jeremy Long
6f511444a7 fixed display bug when only one CPE exists for a given CVE
Former-commit-id: 3b791d0a0fbe2587390e048cffc4453567ddf74a
2014-05-07 19:29:52 -04:00
Jeremy Long
ef5174d89f fixed bug causing vulnerabilities to be missed
Former-commit-id: 5c6421ea8475db16f7184340fa5b8b2033d53b29
2014-05-07 07:05:37 -04:00
Jeremy Long
e2a97e75d8 moved duplicated code to a method
Former-commit-id: f6cb80dc56ef86294f2490729bb84658d98e6c9a
2014-05-07 07:03:38 -04:00
Jeremy Long
9fc6e265eb fixed off by one string truncation issue
Former-commit-id: f25894627402e9e2d310b25163dae7d7db1457d9
2014-05-07 07:03:02 -04:00
Will Stranathan
f81c42b1fd Fixed logging order of GrokAssembly for bad assemblies. Using resources for logging
Former-commit-id: 611d665c7f5312462c19c8dcf8e87dc672184f67
2014-05-03 19:12:39 -04:00
Jeremy Long
8594e146eb updates to help resolve issue 119
Former-commit-id: c8778008b91b7999cb8d88382efe8a83ebe87102
2014-05-03 14:46:48 -04:00
Jeremy Long
cda0dfdafe updated test case and related data
Former-commit-id: 513602f48b6d599b43848f0a88537190084e9cbf
2014-05-03 12:30:29 -04:00
Jeremy Long
363568b02c updated to begin fixes for issue #90 and #119
Former-commit-id: 1ceae6236ecd83e15f91ddab549027082e269e0b
2014-05-03 12:30:07 -04:00
Jeremy Long
443ab02788 added local copies of the NVD CVE data to speed up some of the test cases
Former-commit-id: 54a264872bf151034706f6ed52de3a99ed961b04
2014-05-03 11:02:23 -04:00
Jeremy Long
65784d6dc4 updated to use local copy of data files to speedup the test case
Former-commit-id: 5bb1d67156500ba74124ced18bcae599e4c5dc7a
2014-05-03 11:01:31 -04:00
Jeremy Long
da805d037f removed duplicative test
Former-commit-id: e403e85cef541416ccb3cf13704d019f4c2b5f92
2014-05-03 11:00:48 -04:00
Jeremy Long
d383776245 added additional informational log statements
Former-commit-id: 9dfe02f737cffc05838dcffeec1cfca77c3100e1
2014-05-03 11:00:21 -04:00
Jeremy Long
51eba8da73 updated settings cleanup to prevent issue with the update process
Former-commit-id: e883b7d37c583b581b41da368dbe9b8d1bafae89
2014-05-03 10:59:47 -04:00
Jeremy Long
14b4d64244 updated the URL for the NVD CVE external link
Former-commit-id: 18cd71abd7a1f0d94dde8dba2a3076b28405ab00
2014-05-03 10:58:41 -04:00
Jeremy Long
7cb7f68cda updated the URL for the NVD CVE external link
Former-commit-id: 83ad77fb9fe6029fdb95ba7ffc96663d88234631
2014-05-03 10:58:16 -04:00
Jeremy Long
83300d028b updated the URL for the NVD CVE external link
Former-commit-id: 7527c31dab810145d8aebc1225ba302aca9fc80e
2014-05-03 10:57:44 -04:00
Jeremy Long
e891ce39c0 updated settings cleanup to prevent issue with the update process
Former-commit-id: 3452aec55b778224e10879175e1aba8060da4e42
2014-05-03 10:55:56 -04:00
Jeremy Long
e58b7782ac updated settings cleanup to prevent issue with the update process
Former-commit-id: 07122c535d47f3f414659013555fa826ce0e9b9c
2014-05-03 10:55:15 -04:00
Jeremy Long
1ddb468a08 applied part of PR for issue #121 - classpath issue with some invocations of the ant client
Former-commit-id: 129a5fd9cd55c8a0abf393d0ae8405ddec412d51
2014-05-03 09:54:11 -04:00
Jeremy Long
95e3f0e0d9 added additional dependencies for testing
Former-commit-id: 99be1ef0f35f040ca13b204e2a1689cbaa3cf41a
2014-05-03 09:52:57 -04:00
Jeremy Long
0edf017ddc patched for issue #120 - duplicate evidence listed in reports
Former-commit-id: 3cdc1854af586029911b70fb4b8ff54669bac022
2014-05-03 08:52:45 -04:00
Jeremy Long
ad601fd1ee Merge branch 'bkimminich-master'
Former-commit-id: d4f3bd1ebe5237060251b1f81111b26b5f653f65
2014-04-30 19:23:23 -04:00
Jeremy Long
e7eaccb5e0 Merge branch 'master' of github.com:bkimminich/DependencyCheck into bkimminich-master
Former-commit-id: 7fe67ea5fa1b94824d2f2c8df5bd099d89dbaf85
2014-04-30 19:23:13 -04:00
Jeremy Long
6b201da3ff version 1.2.1-SNAPSHOT
Former-commit-id: 62ed08de9077505ef8e5350b0470eb5c61089dc3
2014-04-30 18:30:46 -04:00
Jeremy Long
a85a47bc20 fixed issue #118
Former-commit-id: dceb807f182be921c2d85338c1d8192361dc2c1f
2014-04-30 18:13:04 -04:00
Jeremy Long
69b8f51319 fixed issue #118
Former-commit-id: 6f7b38b0945c6bcf47ffae0b8a6be53b144269cc
2014-04-30 18:10:56 -04:00
Björn Kimminich
0d943ba805 Update AbstractSuppressionAnalyzerTest.java
Former-commit-id: 640d50086e6b5cd9302ca4a24ffed881c614fd54
2014-04-29 14:37:52 +02:00
Björn Kimminich
56fe3b5892 simplified exception testing
Former-commit-id: f43f211c4cc3133e5dfc466a4badfb3606a3be0c
2014-04-29 14:29:46 +02:00
Björn Kimminich
c177f12e1d added test case for classpath suppression file and missing file
Former-commit-id: 975cbe1f480ad52b0e527148c4fd30b76d5baa0e
2014-04-29 11:48:07 +02:00
175 changed files with 39123 additions and 8604 deletions

3
.gitignore vendored
View File

@@ -7,6 +7,9 @@
# Eclipse project files
.classpath
.project
.settings
maven-eclipse.xml
.externalToolBuilders
# Netbeans configuration
nb-configuration.xml
/target/

View File

@@ -40,7 +40,6 @@ The plugin can be configured using the following:
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<goals>
@@ -59,7 +58,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-maven/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/installation.html).
Development Usage
-------------
@@ -106,4 +105,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://github.com/jeremylong/DependencyCheck/blob/master/NOTICES.txt

View File

@@ -15,20 +15,19 @@ limitations under the License.
Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.2.0</version>
<version>1.2.6</version>
</parent>
<artifactId>dependency-check-ant</artifactId>
<packaging>jar</packaging>
<name>Dependency-Check Ant Task</name>
<description>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.</description>
<description>dependency-check-ant is an Ant Task that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the project's dependencies. The task will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.</description>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
@@ -324,6 +323,9 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<bottom>Copyright© 2012-14 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
@@ -439,6 +441,11 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-core</artifactId>

View File

@@ -285,26 +285,50 @@ public class DependencyCheckTask extends Task {
this.reportFormat = reportFormat.getValue();
}
/**
* The Proxy URL.
* The Proxy Server.
*/
private String proxyUrl;
private String proxyServer;
/**
* Get the value of proxyUrl.
* Get the value of proxyServer.
*
* @return the value of proxyUrl
* @return the value of proxyServer
*/
public String getProxyUrl() {
return proxyUrl;
public String getProxyServer() {
return proxyServer;
}
/**
* Set the value of proxyUrl.
* Set the value of proxyServer.
*
* @param proxyUrl new value of proxyUrl
* @param server new value of proxyServer
*/
public void setProxyServer(String server) {
this.proxyServer = server;
}
/**
* Get the value of proxyServer.
*
* @return the value of proxyServer
* @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#getProxyServer()} instead
*/
@Deprecated
public String getProxyUrl() {
return proxyServer;
}
/**
* Set the value of proxyServer.
*
* @param proxyUrl new value of proxyServer
* @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#setProxyServer(java.lang.String)}
* instead
*/
@Deprecated
public void setProxyUrl(String proxyUrl) {
this.proxyUrl = proxyUrl;
LOGGER.warning("A deprecated configuration option 'proxyUrl' was detected; use 'proxyServer' instead.");
this.proxyServer = proxyUrl;
}
/**
* The Proxy Port.
@@ -866,7 +890,7 @@ public class DependencyCheckTask extends Task {
Engine engine = null;
try {
engine = new Engine();
engine = new Engine(DependencyCheckTask.class.getClassLoader());
for (Resource resource : path) {
final FileProvider provider = resource.as(FileProvider.class);
@@ -912,7 +936,7 @@ public class DependencyCheckTask extends Task {
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
LOGGER.log(Level.FINE, "", ex);
} finally {
Settings.cleanup();
Settings.cleanup(true);
if (engine != null) {
engine.cleanup();
}
@@ -935,7 +959,7 @@ public class DependencyCheckTask extends Task {
/**
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
* properties required to change the proxy url, port, and connection timeout.
* properties required to change the proxy server, port, and connection timeout.
*/
private void populateSettings() {
Settings.initialize();
@@ -967,8 +991,8 @@ public class DependencyCheckTask extends Task {
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
if (proxyUrl != null && !proxyUrl.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
if (proxyServer != null && !proxyServer.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
}
if (proxyPort != null && !proxyPort.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);

View File

@@ -32,7 +32,7 @@ failBuildOnCVSS | Specifies if the build should be failed if a CVSS score a
format | 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
logFile | The file path to write verbose logging information. | &nbsp;
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) | &nbsp;
proxyUrl | The Proxy URL. | &nbsp;
proxyServer | The Proxy Server. | &nbsp;
proxyPort | The Proxy Port. | &nbsp;
proxyUsername | Defines the proxy user name. | &nbsp;
proxyPassword | Defines the proxy password. | &nbsp;
@@ -46,17 +46,17 @@ 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
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 Jar Analyzer will be used. | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
nexusUrl | Defines the Nexus Pro URL. 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;
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
====================

View File

@@ -3,7 +3,20 @@ 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.
the taskdef to you build.xml and add the task to a new or existing target:
```xml
<taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask"/>
```
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 20 minutes or more as it downloads and processes the data from the National

View File

@@ -1,11 +1,19 @@
Usage
====================
First, add the dependency-check-ant taskdef to your build.xml:
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

View File

@@ -45,7 +45,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
public void tearDown() {
//no cleanup...
//executeTarget("cleanup");
Settings.cleanup();
Settings.cleanup(true);
}
/**

View File

@@ -15,20 +15,19 @@ limitations under the License.
Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.2.0</version>
<version>1.2.6</version>
</parent>
<artifactId>dependency-check-cli</artifactId>
<packaging>jar</packaging>
<name>Dependency-Check Command Line</name>
<description>Dependency-Check-Maven is a Maven Plugin 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.</description>
<description>dependency-check-cli is an command line tool that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.</description>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
@@ -174,6 +173,9 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<bottom>Copyright© 2012-14 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
@@ -284,12 +286,12 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.7</version>
<version>1.8.1</version>
<configuration>
<programs>
<program>
<mainClass>org.owasp.dependencycheck.App</mainClass>
<name>dependency-check</name>
<id>dependency-check</id>
</program>
</programs>
<assembleDirectory>${project.build.directory}/release</assembleDirectory>
@@ -341,5 +343,10 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -2,10 +2,8 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd
"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd"
>
<id>release</id>
<formats>

View File

@@ -21,15 +21,19 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.cli.ParseException;
import org.owasp.dependencycheck.cli.CliParser;
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.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.LogUtils;
import org.owasp.dependencycheck.utils.Settings;
@@ -57,8 +61,13 @@ public class App {
* @param args the command line arguments
*/
public static void main(String[] args) {
final App app = new App();
app.run(args);
try {
Settings.initialize();
final App app = new App();
app.run(args);
} finally {
Settings.cleanup(true);
}
}
/**
@@ -67,8 +76,8 @@ public class App {
* @param args the command line arguments
*/
public void run(String[] args) {
final CliParser cli = new CliParser();
try {
cli.parse(args);
} catch (FileNotFoundException ex) {
@@ -88,7 +97,11 @@ public class App {
cli.printVersionInfo();
} else if (cli.isRunScan()) {
populateSettings(cli);
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles());
try {
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(), cli.getExcludeList());
} catch (InvalidScanPathException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "An invalid scan path was detected; unable to scan '//*' paths");
}
} else {
cli.printHelp();
}
@@ -101,18 +114,71 @@ public class App {
* @param outputFormat the output format of the report
* @param applicationName the application name for the report
* @param files the files/directories to scan
* @param excludes the patterns for files/directories to exclude
*
* @throws InvalidScanPathException thrown if the path to scan starts with "//"
*/
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
Engine scanner = null;
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
String[] excludes) throws InvalidScanPathException {
Engine engine = null;
try {
scanner = new Engine();
for (String file : files) {
scanner.scan(file);
engine = new Engine();
List<String> antStylePaths = new ArrayList<String>();
if (excludes == null || excludes.length == 0) {
for (String file : files) {
if (file.contains("*") || file.contains("?")) {
antStylePaths.add(file);
} else {
engine.scan(file);
}
}
} else {
antStylePaths = Arrays.asList(files);
}
scanner.analyzeDependencies();
final List<Dependency> dependencies = scanner.getDependencies();
final Set<File> paths = new HashSet<File>();
for (String file : antStylePaths) {
final DirectoryScanner scanner = new DirectoryScanner();
String include = file.replace('\\', '/');
File baseDir;
if (include.startsWith("//")) {
throw new InvalidScanPathException("Unable to scan paths specified by //");
} else if (include.startsWith("./")) {
baseDir = new File(".");
include = include.substring(2);
} else if (include.startsWith("/")) {
baseDir = new File("/");
include = include.substring(1);
} else if (include.contains("/")) {
final int pos = include.indexOf('/');
final String tmp = include.substring(0, pos);
if (tmp.contains("*") || tmp.contains("?")) {
baseDir = new File(".");
} else {
baseDir = new File(tmp);
include = include.substring(pos + 1);
}
} else { //no path info - must just be a file in the working directory
baseDir = new File(".");
}
scanner.setBasedir(baseDir);
scanner.setIncludes(include);
if (excludes != null && excludes.length > 0) {
scanner.addExcludes(excludes);
}
scanner.scan();
if (scanner.getIncludedFilesCount() > 0) {
for (String s : scanner.getIncludedFiles()) {
final File f = new File(baseDir, s);
paths.add(f);
}
}
}
engine.scan(paths);
engine.analyzeDependencies();
final List<Dependency> dependencies = engine.getDependencies();
DatabaseProperties prop = null;
CveDB cve = null;
try {
@@ -126,7 +192,7 @@ public class App {
cve.close();
}
}
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {
@@ -140,9 +206,8 @@ public class App {
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
LOGGER.log(Level.FINE, "", ex);
} finally {
Settings.cleanup();
if (scanner != null) {
scanner.cleanup();
if (engine != null) {
engine.cleanup();
}
}
}
@@ -155,11 +220,9 @@ public class App {
*/
private void populateSettings(CliParser cli) {
Settings.initialize();
final boolean autoUpdate = cli.isAutoUpdate();
final String connectionTimeout = cli.getConnectionTimeout();
final String proxyUrl = cli.getProxyUrl();
final String proxyServer = cli.getProxyServer();
final String proxyPort = cli.getProxyPort();
final String proxyUser = cli.getProxyUsername();
final String proxyPass = cli.getProxyPassword();
@@ -210,8 +273,8 @@ public class App {
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
}
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
if (proxyUrl != null && !proxyUrl.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
if (proxyServer != null && !proxyServer.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
}
if (proxyPort != null && !proxyPort.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);

View File

@@ -15,10 +15,11 @@
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.cli;
package org.owasp.dependencycheck;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.logging.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
@@ -39,6 +40,10 @@ import org.owasp.dependencycheck.utils.Settings;
*/
public final class CliParser {
/**
* The logger.
*/
private static final Logger LOGGER = Logger.getLogger(CliParser.class.getName());
/**
* The command line.
*/
@@ -85,16 +90,16 @@ public final class CliParser {
*/
private void validateArgs() throws FileNotFoundException, ParseException {
if (isRunScan()) {
validatePathExists(getScanFiles(), ArgumentName.SCAN);
validatePathExists(getReportDirectory(), ArgumentName.OUT);
validatePathExists(getScanFiles(), ARGUMENT.SCAN);
validatePathExists(getReportDirectory(), ARGUMENT.OUT);
if (getPathToMono() != null) {
validatePathExists(getPathToMono(), ArgumentName.PATH_TO_MONO);
validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
}
if (!line.hasOption(ArgumentName.APP_NAME)) {
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(ArgumentName.OUTPUT_FORMAT)) {
final String format = line.getOptionValue(ArgumentName.OUTPUT_FORMAT);
if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
try {
Format.valueOf(format);
} catch (IllegalArgumentException ex) {
@@ -129,14 +134,33 @@ public final class CliParser {
* @throws FileNotFoundException is thrown if the path being validated does not exist.
*/
private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
if (!path.contains("*.")) {
if (path == null) {
isValid = false;
final String msg = String.format("Invalid '%s' argument: null", argumentName);
throw new FileNotFoundException(msg);
} else if (!path.contains("*") && !path.contains("?")) {
final File f = new File(path);
if (!f.exists()) {
isValid = false;
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
throw new FileNotFoundException(msg);
if ("o".equals(argumentName.substring(0, 1).toLowerCase()) && !"ALL".equals(this.getReportFormat().toUpperCase())) {
final String checkPath = path.toLowerCase();
if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
if (!f.getParentFile().isDirectory()) {
isValid = false;
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
throw new FileNotFoundException(msg);
}
}
} else {
if (!f.exists()) {
isValid = false;
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
throw new FileNotFoundException(msg);
}
}
} // else { // TODO add a validation for *.zip extensions rather then relying on the engine to validate it.
} else if (path.startsWith("//") || path.startsWith("\\\\")) {
isValid = false;
final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
throw new FileNotFoundException(msg);
}
}
/**
@@ -146,11 +170,10 @@ public final class CliParser {
*/
@SuppressWarnings("static-access")
private Options createCommandLineOptions() {
final Options options = new Options();
addStandardOptions(options);
addAdvancedOptions(options);
addDeprecatedOptions(options);
return options;
}
@@ -162,44 +185,50 @@ public final class CliParser {
*/
@SuppressWarnings("static-access")
private void addStandardOptions(final Options options) throws IllegalArgumentException {
final Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
"Print this message.");
final Option advancedHelp = OptionBuilder.withLongOpt(ArgumentName.ADVANCED_HELP)
final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
.withDescription("Print the advanced help message.").create();
final Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
false, "Print the version information.");
final Option noUpdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE,
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(ArgumentName.APP_NAME)
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(ArgumentName.APP_NAME_SHORT);
.create(ARGUMENT.APP_NAME_SHORT);
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
.withDescription("The path to scan - this option can be specified multiple times. To limit the scan"
+ " to specific file types *.[ext] can be added to the end of the path.")
.create(ArgumentName.SCAN_SHORT);
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
.withDescription("The path to scan - this option can be specified multiple times. Ant style"
+ " paths are supported (e.g. path/**/*.jar).")
.create(ARGUMENT.SCAN_SHORT);
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
.withDescription("Specify and exclusion pattern. This option can be specified multiple times"
+ " and it accepts Ant style excludsions.")
.create();
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
.withDescription("A property file to load.")
.create(ArgumentName.PROP_SHORT);
.create(ARGUMENT.PROP_SHORT);
final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT)
.withDescription("The folder to write reports to. This defaults to the current directory.")
.create(ArgumentName.OUT_SHORT);
final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
.withDescription("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);
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ArgumentName.OUTPUT_FORMAT)
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(ArgumentName.OUTPUT_FORMAT_SHORT);
.create(ARGUMENT.OUTPUT_FORMAT_SHORT);
final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.VERBOSE_LOG)
final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
.withDescription("The file path to write verbose logging information.")
.create(ArgumentName.VERBOSE_LOG_SHORT);
.create(ARGUMENT.VERBOSE_LOG_SHORT);
final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.SUPPRESSION_FILE)
final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
.withDescription("The file path to the suppression XML file.")
.create();
@@ -207,7 +236,11 @@ public final class CliParser {
final OptionGroup og = new OptionGroup();
og.addOption(path);
final OptionGroup exog = new OptionGroup();
exog.addOption(excludes);
options.addOptionGroup(og)
.addOptionGroup(exog)
.addOption(out)
.addOption(outputFormat)
.addOption(appName)
@@ -230,87 +263,87 @@ public final class CliParser {
@SuppressWarnings("static-access")
private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DATA_DIRECTORY)
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(ArgumentName.DATA_DIRECTORY_SHORT);
.create(ARGUMENT.DATA_DIRECTORY_SHORT);
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ArgumentName.CONNECTION_TIMEOUT)
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
.withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
.create(ArgumentName.CONNECTION_TIMEOUT_SHORT);
.create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
final Option proxyUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.PROXY_URL)
.withDescription("The proxy url to use when downloading resources.")
.create(ArgumentName.PROXY_URL_SHORT);
final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
.withDescription("The proxy server to use when downloading resources.")
.create();
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ArgumentName.PROXY_PORT)
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
.withDescription("The proxy port to use when downloading resources.")
.create(ArgumentName.PROXY_PORT_SHORT);
.create();
final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.PROXY_USERNAME)
final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
.withDescription("The proxy username to use when downloading resources.")
.create();
final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ArgumentName.PROXY_PASSWORD)
final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
.withDescription("The proxy password to use when downloading resources.")
.create();
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ArgumentName.CONNECTION_STRING)
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
.withDescription("The connection string to the database.")
.create();
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.DB_NAME)
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
.withDescription("The username used to connect to the database.")
.create();
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ArgumentName.DB_PASSWORD)
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
.withDescription("The password for connecting to the database.")
.create();
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ArgumentName.DB_DRIVER)
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
.withDescription("The database driver name.")
.create();
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DB_DRIVER_PATH)
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 disableJarAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_JAR)
final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
.withDescription("Disable the Jar Analyzer.")
.create();
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ARCHIVE)
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
.withDescription("Disable the Archive Analyzer.")
.create();
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NUSPEC)
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
.withDescription("Disable the Nuspec Analyzer.")
.create();
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ASSEMBLY)
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
.withDescription("Disable the .NET Assembly Analyzer.")
.create();
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NEXUS)
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
.withDescription("Disable the Nexus Analyzer.")
.create();
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.NEXUS_URL)
.withDescription("The url to the Nexus Server.")
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
.withDescription("The url to the Nexus Pro Server. If not set the Nexus Analyzer will be disabled.")
.create();
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ArgumentName.NEXUS_USES_PROXY)
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 additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
.withLongOpt(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS)
.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 pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.PATH_TO_MONO)
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();
options.addOption(proxyPort)
.addOption(proxyUrl)
.addOption(proxyServer)
.addOption(proxyUsername)
.addOption(proxyPassword)
.addOption(connectionTimeout)
@@ -331,13 +364,30 @@ public final class CliParser {
.addOption(pathToMono);
}
/**
* Adds the deprecated command line options to the given options collection. These are split out for purposes of not
* including them in the help message. We need to add the deprecated options so as not to break existing scripts.
*
* @param options a collection of command line arguments
* @throws IllegalArgumentException thrown if there is an exception
*/
@SuppressWarnings("static-access")
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();
options.addOption(proxyServer);
}
/**
* Determines if the 'version' command line argument was passed in.
*
* @return whether or not the 'version' command line argument was passed in
*/
public boolean isGetVersion() {
return (line != null) && line.hasOption(ArgumentName.VERSION);
return (line != null) && line.hasOption(ARGUMENT.VERSION);
}
/**
@@ -346,7 +396,7 @@ public final class CliParser {
* @return whether or not the 'help' command line argument was passed in
*/
public boolean isGetHelp() {
return (line != null) && line.hasOption(ArgumentName.HELP);
return (line != null) && line.hasOption(ARGUMENT.HELP);
}
/**
@@ -355,7 +405,7 @@ public final class CliParser {
* @return whether or not the 'scan' command line argument was passed in
*/
public boolean isRunScan() {
return (line != null) && isValid && line.hasOption(ArgumentName.SCAN);
return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
}
/**
@@ -364,7 +414,7 @@ public final class CliParser {
* @return true if the disableJar command line argument was specified; otherwise false
*/
public boolean isJarDisabled() {
return (line != null) && line.hasOption(ArgumentName.DISABLE_JAR);
return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
}
/**
@@ -373,7 +423,7 @@ public final class CliParser {
* @return true if the disableArchive command line argument was specified; otherwise false
*/
public boolean isArchiveDisabled() {
return (line != null) && line.hasOption(ArgumentName.DISABLE_ARCHIVE);
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
}
/**
@@ -382,7 +432,7 @@ public final class CliParser {
* @return true if the disableNuspec command line argument was specified; otherwise false
*/
public boolean isNuspecDisabled() {
return (line != null) && line.hasOption(ArgumentName.DISABLE_NUSPEC);
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
}
/**
@@ -391,7 +441,7 @@ public final class CliParser {
* @return true if the disableAssembly command line argument was specified; otherwise false
*/
public boolean isAssemblyDisabled() {
return (line != null) && line.hasOption(ArgumentName.DISABLE_ASSEMBLY);
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
}
/**
@@ -400,7 +450,7 @@ public final class CliParser {
* @return true if the disableNexus command line argument was specified; otherwise false
*/
public boolean isNexusDisabled() {
return (line != null) && line.hasOption(ArgumentName.DISABLE_NEXUS);
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
}
/**
@@ -409,10 +459,10 @@ public final class CliParser {
* @return the url to the nexus server; if none was specified this will return null;
*/
public String getNexusUrl() {
if (line == null || !line.hasOption(ArgumentName.NEXUS_URL)) {
if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
return null;
} else {
return line.getOptionValue(ArgumentName.NEXUS_URL);
return line.getOptionValue(ARGUMENT.NEXUS_URL);
}
}
@@ -425,14 +475,14 @@ public final class CliParser {
public boolean isNexusUsesProxy() {
// If they didn't specify whether Nexus needs to use the proxy, we should
// still honor the property if it's set.
if (line == null || !line.hasOption(ArgumentName.NEXUS_USES_PROXY)) {
if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
try {
return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
} catch (InvalidSettingException ise) {
return true;
}
} else {
return Boolean.parseBoolean(line.getOptionValue(ArgumentName.NEXUS_USES_PROXY));
return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
}
}
@@ -443,7 +493,7 @@ public final class CliParser {
final HelpFormatter formatter = new HelpFormatter();
final Options options = new Options();
addStandardOptions(options);
if (line != null && line.hasOption(ArgumentName.ADVANCED_HELP)) {
if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
addAdvancedOptions(options);
}
final String helpMsg = String.format("%n%s"
@@ -457,7 +507,6 @@ public final class CliParser {
options,
"",
true);
}
/**
@@ -466,7 +515,16 @@ public final class CliParser {
* @return the file paths specified on the command line for scan
*/
public String[] getScanFiles() {
return line.getOptionValues(ArgumentName.SCAN);
return line.getOptionValues(ARGUMENT.SCAN);
}
/**
* Retrieves the list of excluded file patterns specified by the 'exclude' argument.
*
* @return the excluded file patterns
*/
public String[] getExcludeList() {
return line.getOptionValues(ARGUMENT.EXCLUDE);
}
/**
@@ -475,7 +533,7 @@ public final class CliParser {
* @return the path to the reports directory.
*/
public String getReportDirectory() {
return line.getOptionValue(ArgumentName.OUT, ".");
return line.getOptionValue(ARGUMENT.OUT, ".");
}
/**
@@ -484,7 +542,7 @@ public final class CliParser {
* @return the path to Mono
*/
public String getPathToMono() {
return line.getOptionValue(ArgumentName.PATH_TO_MONO);
return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
}
/**
@@ -493,7 +551,7 @@ public final class CliParser {
* @return the output format name.
*/
public String getReportFormat() {
return line.getOptionValue(ArgumentName.OUTPUT_FORMAT, "HTML");
return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
}
/**
@@ -502,7 +560,7 @@ public final class CliParser {
* @return the application name.
*/
public String getApplicationName() {
return line.getOptionValue(ArgumentName.APP_NAME);
return line.getOptionValue(ARGUMENT.APP_NAME);
}
/**
@@ -511,16 +569,24 @@ public final class CliParser {
* @return the connection timeout
*/
public String getConnectionTimeout() {
return line.getOptionValue(ArgumentName.CONNECTION_TIMEOUT);
return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
}
/**
* Returns the proxy url.
* Returns the proxy server.
*
* @return the proxy url
* @return the proxy server
*/
public String getProxyUrl() {
return line.getOptionValue(ArgumentName.PROXY_URL);
public String getProxyServer() {
String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
if (server == null) {
server = line.getOptionValue(ARGUMENT.PROXY_URL);
if (server != null) {
LOGGER.warning("An old command line argument 'proxyurl' was detected; use proxyserver instead");
}
}
return server;
}
/**
@@ -529,7 +595,7 @@ public final class CliParser {
* @return the proxy port
*/
public String getProxyPort() {
return line.getOptionValue(ArgumentName.PROXY_PORT);
return line.getOptionValue(ARGUMENT.PROXY_PORT);
}
/**
@@ -538,7 +604,7 @@ public final class CliParser {
* @return the proxy username
*/
public String getProxyUsername() {
return line.getOptionValue(ArgumentName.PROXY_USERNAME);
return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
}
/**
@@ -547,7 +613,7 @@ public final class CliParser {
* @return the proxy password
*/
public String getProxyPassword() {
return line.getOptionValue(ArgumentName.PROXY_PASSWORD);
return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
}
/**
@@ -556,7 +622,7 @@ public final class CliParser {
* @return the value of dataDirectory
*/
public String getDataDirectory() {
return line.getOptionValue(ArgumentName.DATA_DIRECTORY);
return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
}
/**
@@ -565,7 +631,7 @@ public final class CliParser {
* @return the properties file specified on the command line
*/
public File getPropertiesFile() {
final String path = line.getOptionValue(ArgumentName.PROP);
final String path = line.getOptionValue(ARGUMENT.PROP);
if (path != null) {
return new File(path);
}
@@ -578,7 +644,7 @@ public final class CliParser {
* @return the path to the verbose log file
*/
public String getVerboseLog() {
return line.getOptionValue(ArgumentName.VERBOSE_LOG);
return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
}
/**
@@ -587,7 +653,7 @@ public final class CliParser {
* @return the path to the suppression file
*/
public String getSuppressionFile() {
return line.getOptionValue(ArgumentName.SUPPRESSION_FILE);
return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
}
/**
@@ -610,7 +676,7 @@ public final class CliParser {
* @return if auto-update is allowed.
*/
public boolean isAutoUpdate() {
return (line == null) || !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE);
return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
}
/**
@@ -619,7 +685,7 @@ public final class CliParser {
* @return the database driver name if specified; otherwise null is returned
*/
public String getDatabaseDriverName() {
return line.getOptionValue(ArgumentName.DB_DRIVER);
return line.getOptionValue(ARGUMENT.DB_DRIVER);
}
/**
@@ -628,7 +694,7 @@ public final class CliParser {
* @return the database driver name if specified; otherwise null is returned
*/
public String getDatabaseDriverPath() {
return line.getOptionValue(ArgumentName.DB_DRIVER_PATH);
return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
}
/**
@@ -637,7 +703,7 @@ public final class CliParser {
* @return the database connection string if specified; otherwise null is returned
*/
public String getConnectionString() {
return line.getOptionValue(ArgumentName.CONNECTION_STRING);
return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
}
/**
@@ -646,7 +712,7 @@ public final class CliParser {
* @return the database database user name if specified; otherwise null is returned
*/
public String getDatabaseUser() {
return line.getOptionValue(ArgumentName.DB_NAME);
return line.getOptionValue(ARGUMENT.DB_NAME);
}
/**
@@ -655,7 +721,7 @@ public final class CliParser {
* @return the database database password if specified; otherwise null is returned
*/
public String getDatabasePassword() {
return line.getOptionValue(ArgumentName.DB_PASSWORD);
return line.getOptionValue(ARGUMENT.DB_PASSWORD);
}
/**
@@ -664,13 +730,13 @@ public final class CliParser {
* @return the additional Extensions; otherwise null is returned
*/
public String getAdditionalZipExtensions() {
return line.getOptionValue(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS);
return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
}
/**
* A collection of static final strings that represent the possible command line arguments.
*/
public static class ArgumentName {
public static class ARGUMENT {
/**
* The long CLI argument name specifying the directory/file to scan.
@@ -732,21 +798,20 @@ public final class CliParser {
* The short CLI argument name asking for the version.
*/
public static final String VERSION = "version";
/**
* The short CLI argument name indicating the proxy port.
*/
public static final String PROXY_PORT_SHORT = "p";
/**
* The CLI argument name indicating the proxy port.
*/
public static final String PROXY_PORT = "proxyport";
/**
* The short CLI argument name indicating the proxy url.
* The CLI argument name indicating the proxy server.
*/
public static final String PROXY_URL_SHORT = "u";
public static final String PROXY_SERVER = "proxyserver";
/**
* The CLI argument name indicating the proxy url.
*
* @deprecated use {@link org.owasp.dependencycheck.cli.CliParser.ArgumentName#PROXY_SERVER} instead
*/
@Deprecated
public static final String PROXY_URL = "proxyurl";
/**
* The CLI argument name indicating the proxy username.
@@ -848,5 +913,9 @@ public final class CliParser {
* The CLI argument name for setting extra extensions.
*/
public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
/**
* Exclude path argument.
*/
public static final String EXCLUDE = "exclude";
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2014 OWASP.
*
* 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.
*/
package org.owasp.dependencycheck;
/**
* Thrown if an invalid path is encountered.
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
class InvalidScanPathException extends Exception {
/**
* Creates a new InvalidScanPathException.
*/
public InvalidScanPathException() {
super();
}
/**
* Creates a new InvalidScanPathException.
*
* @param msg a message for the exception
*/
public InvalidScanPathException(String msg) {
super(msg);
}
/**
* Creates a new InvalidScanPathException.
*
* @param ex the cause of the exception
*/
public InvalidScanPathException(Throwable ex) {
super(ex);
}
/**
* Creates a new InvalidScanPathException.
*
* @param msg a message for the exception
* @param ex the cause of the exception
*/
public InvalidScanPathException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -1,12 +0,0 @@
/**
* <html>
* <head>
* <title>org.owasp.dependencycheck.cli</title>
* </head>
* <body>
* Includes utility classes such as the CLI Parser,
* </body>
* </html>
*/
package org.owasp.dependencycheck.cli;

View File

@@ -3,11 +3,12 @@ Command Line Arguments
The following table lists the command line arguments:
Short | Argument Name | Parameter | Description | Requirement
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
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify specific file types that should be scanned by supplying a scan path of '[path]/[to]/[scan]/*.zip'. The wild card can only be used to denote any file-name with a specific extension. | Required
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
\-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
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
\-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
@@ -18,26 +19,25 @@ Short | Argument Name | Parameter | Description | Requirement
Advanced Options
================
Short | Argument Name | Parameter | Description | Default Value
-------|-----------------------|-----------------|-------------|---------------
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
Short | Argument&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Parameter | Description | Default&nbsp;Value
-------|-----------------------|-----------------|-----------------------------------------------------------------------------|---------------
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | 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 Jar Analyzer will be used. | false
| \-\-disableNexus | | Sets whether Nexus Analyzer will be used. | false
| \-\-disableNexus | | Disable the Nexus Analyzer. | &nbsp;
| \-\-nexus | \<url\> | The url to the Nexus Server. | https://repository.sonatype.org/service/local/
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
| \-\-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
| \-\-pathToMono | \<path\> | The path to Mono for .NET Assembly analysis on non-windows systems. | &nbsp;
| \-\-proxyurl | \<url\> | The proxy url to use when downloading resources. | &nbsp;
| \-\-proxyport | \<port\> | The proxy port to use when downloading resources. | &nbsp;
| \-\-disableJar | | Sets whether Jar Analyzer will be used. | false
| \-\-disableNexus | | Sets whether Nexus Analyzer will be used. | false
| \-\-nexus | \<url\> | The url to the Nexus Pro Server. If not set the Nexus Analyzer will be disabled. | &nbsp;
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
| \-\-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
| \-\-pathToMono | \<path\> | The path to Mono for .NET Assembly analysis on non-windows systems. | &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;
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. | &nbsp;
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. | &nbsp;
| \-\-connectionString | \<connStr\> | The connection string to the database. | &nbsp;
| \-\-dbDriverName | \<driver\> | The database driver name. | &nbsp;
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. | &nbsp;
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. | &nbsp;
| \-\-connectionString | \<connStr\> | The connection string to the database. | &nbsp;
| \-\-dbDriverName | \<driver\> | The database driver name. | &nbsp;
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. | &nbsp;
| \-\-dbPassword | \<password\> | The password for connecting to the database. | &nbsp;
| \-\-dbUser | \<user\> | The username used to connect to the database. | &nbsp;
| \-\-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;

View File

@@ -15,8 +15,9 @@
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.cli;
package org.owasp.dependencycheck;
import org.owasp.dependencycheck.CliParser;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
@@ -44,7 +45,7 @@ public class CliParserTest {
@AfterClass
public static void tearDownClass() throws Exception {
Settings.cleanup();
Settings.cleanup(true);
}
@Before

View File

@@ -15,19 +15,19 @@ limitations under the License.
Copyright (c) 2012 Jeremy Long. All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.2.0</version>
<version>1.2.6</version>
</parent>
<artifactId>dependency-check-core</artifactId>
<packaging>jar</packaging>
<name>Dependency-Check Core</name>
<description>dependency-check-core is the engine and reporting tool used to identify and report if there are any known, publicly disclosed vulnerabilities in the scanned project's dependencies. The engine extracts meta-data from the dependencies and uses this to do fuzzy key-word matching against the Common Platfrom Enumeration (CPE), if any CPE identifiers are found the associated Common Vulnerability and Exposure (CVE) entries are added to the generated report.</description>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
@@ -220,6 +220,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<name>data.directory</name>
<value>${project.build.directory}/data</value>
</property>
<property>
<name>temp.directory</name>
<value>${project.build.directory}/temp</value>
</property>
</systemProperties>
<includes>
<include>**/*IntegrationTest.java</include>
@@ -267,6 +272,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<bottom>Copyright© 2012-14 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
@@ -392,6 +400,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<version>3.1</version>
<configuration>
<showDeprecation>false</showDeprecation>
<compilerArgument>-Xlint:unchecked</compilerArgument>
<source>1.6</source>
<target>1.6</target>
</configuration>
@@ -399,12 +408,23 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<!--dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.12</version>
<scope>test</scope>
</dependency-->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
@@ -419,7 +439,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.8</version>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
@@ -451,50 +471,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
<!-- very limited use of the velocity-tools, not all of the dependencies are needed-->
<exclusions>
<exclusion>
<groupId>commons-chain</groupId>
<artifactId>commons-chain</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</exclusion>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
<exclusion>
<groupId>sslext</groupId>
<artifactId>sslext</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.struts</groupId>
<artifactId>struts-core</artifactId>
</exclusion>
<exclusion>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.struts</groupId>
<artifactId>struts-taglib</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.struts</groupId>
<artifactId>struts-tiles</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -521,6 +497,13 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.0.RELEASE</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
@@ -601,6 +584,13 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.0.RELEASE</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
<profiles>
<profile>
@@ -662,11 +652,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
Additionally, these are only added when using "allTests" to
make the build slightly faster in most cases. -->
<id>False Positive Tests</id>
<!--activation>
<activation>
<property>
<name>allTests</name>
</property>
</activation-->
</activation>
<dependencies>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
@@ -689,6 +679,56 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.ganyo</groupId>
<artifactId>gcm-server</artifactId>
<version>1.0.2</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7-b1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.7.4</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.12</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.11.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.8-02</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
</profile>
</profiles>

View File

@@ -18,6 +18,7 @@
package org.owasp.dependencycheck;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
@@ -52,7 +53,7 @@ import org.owasp.dependencycheck.utils.Settings;
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class Engine {
public class Engine implements Serializable {
/**
* The list of dependencies.
@@ -61,19 +62,19 @@ public class Engine {
/**
* A Map of analyzers grouped by Analysis phase.
*/
private final EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
private final transient EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
/**
* A Map of analyzers grouped by Analysis phase.
*/
private final Set<FileTypeAnalyzer> fileTypeAnalyzers;
private final transient Set<FileTypeAnalyzer> fileTypeAnalyzers;
/**
* The ClassLoader to use when dynamically loading Analyzer and Update services.
*/
private ClassLoader serviceClassLoader;
private transient ClassLoader serviceClassLoader;
/**
* The Logger for use throughout the class.
*/
private static final Logger LOGGER = Logger.getLogger(Engine.class.getName());
private static final transient Logger LOGGER = Logger.getLogger(Engine.class.getName());
/**
* Creates a new Engine.
@@ -167,142 +168,171 @@ public class Engine {
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
* dependencies identified are added to the dependency collection.
*
* @since v0.3.2.5
* @param paths an array of paths to files or directories to be analyzed
* @return the list of dependencies scanned
*
* @param paths an array of paths to files or directories to be analyzed.
* @since v0.3.2.5
*/
public void scan(String[] paths) {
public List<Dependency> scan(String[] paths) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (String path : paths) {
final File file = new File(path);
scan(file);
final List<Dependency> d = scan(file);
if (d != null) {
deps.addAll(d);
}
}
return deps;
}
/**
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
* identified are added to the dependency collection.
*
* @param path the path to a file or directory to be analyzed.
* @param path the path to a file or directory to be analyzed
* @return the list of dependencies scanned
*/
public void scan(String path) {
if (path.matches("^.*[\\/]\\*\\.[^\\/:*|?<>\"]+$")) {
final String[] parts = path.split("\\*\\.");
final String[] ext = new String[]{parts[parts.length - 1]};
final File dir = new File(path.substring(0, path.length() - ext[0].length() - 2));
if (dir.isDirectory()) {
final List<File> files = (List<File>) org.apache.commons.io.FileUtils.listFiles(dir, ext, true);
scan(files);
} else {
final String msg = String.format("Invalid file path provided to scan '%s'", path);
LOGGER.log(Level.SEVERE, msg);
}
} else {
final File file = new File(path);
scan(file);
}
public List<Dependency> scan(String path) {
final File file = new File(path);
return scan(file);
}
/**
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
* dependencies identified are added to the dependency collection.
*
* @since v0.3.2.5
*
* @param files an array of paths to files or directories to be analyzed.
* @return the list of dependencies
*
* @since v0.3.2.5
*/
public void scan(File[] files) {
public List<Dependency> scan(File[] files) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (File file : files) {
scan(file);
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.
*
* @since v0.3.2.5
* @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned
*
* @param files a set of paths to files or directories to be analyzed.
* @since v0.3.2.5
*/
public void scan(Set<File> files) {
public List<Dependency> scan(Set<File> files) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (File file : files) {
scan(file);
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.
*
* @since v0.3.2.5
* @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned
*
* @param files a set of paths to files or directories to be analyzed.
* @since v0.3.2.5
*/
public void scan(List<File> files) {
public List<Dependency> scan(List<File> files) {
final List<Dependency> deps = new ArrayList<Dependency>();
for (File file : files) {
scan(file);
final List<Dependency> d = scan(file);
if (d != null) {
deps.addAll(d);
}
}
return deps;
}
/**
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
* identified are added to the dependency collection.
*
* @param file the path to a file or directory to be analyzed
* @return the list of dependencies scanned
*
* @since v0.3.2.4
*
* @param file the path to a file or directory to be analyzed.
*/
public void scan(File file) {
public List<Dependency> scan(File file) {
if (file.exists()) {
if (file.isDirectory()) {
scanDirectory(file);
return scanDirectory(file);
} else {
scanFile(file);
final Dependency d = scanFile(file);
if (d != null) {
final List<Dependency> deps = new ArrayList<Dependency>();
deps.add(d);
return deps;
}
}
}
return null;
}
/**
* Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
*
* @param dir the directory to scan.
* @param dir the directory to scan
* @return the list of Dependency objects scanned
*/
protected void scanDirectory(File dir) {
protected List<Dependency> scanDirectory(File dir) {
final File[] files = dir.listFiles();
final List<Dependency> deps = new ArrayList<Dependency>();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
scanDirectory(f);
final List<Dependency> d = scanDirectory(f);
if (d != null) {
deps.addAll(d);
}
} else {
scanFile(f);
final Dependency d = scanFile(f);
deps.add(d);
}
}
}
return deps;
}
/**
* Scans a specified file. If a dependency is identified it is added to the dependency collection.
*
* @param file The file to scan.
* @param file The file to scan
* @return the scanned dependency
*/
protected void scanFile(File file) {
protected Dependency scanFile(File file) {
if (!file.isFile()) {
final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString());
LOGGER.log(Level.FINE, msg);
return;
return null;
}
final String fileName = file.getName();
final String extension = FileUtils.getFileExtension(fileName);
Dependency dependency = null;
if (extension != null) {
if (supportsExtension(extension)) {
final Dependency dependency = new Dependency(file);
dependency = new Dependency(file);
dependencies.add(dependency);
}
} else {
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.",
file.toString());
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.", file.toString());
LOGGER.log(Level.FINEST, msg);
}
return dependency;
}
/**
@@ -438,8 +468,7 @@ public class Engine {
} catch (UpdateException ex) {
LOGGER.log(Level.WARNING,
"Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
LOGGER.log(Level.FINE,
String.format("Unable to update details for %s", source.getClass().getName()), ex);
LOGGER.log(Level.FINE, String.format("Unable to update details for %s", source.getClass().getName()), ex);
}
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
* Copyright (c) 2014 Steve Springett. All Rights Reserved.
*/
package org.owasp.dependencycheck.agent;
@@ -234,26 +234,49 @@ public class DependencyCheckScanAgent {
}
/**
* The Proxy URL.
* The Proxy Server.
*/
private String proxyUrl;
private String proxyServer;
/**
* Get the value of proxyUrl.
* Get the value of proxyServer.
*
* @return the value of proxyUrl
* @return the value of proxyServer
*/
public String getProxyUrl() {
return proxyUrl;
public String getProxyServer() {
return proxyServer;
}
/**
* Set the value of proxyUrl.
* Set the value of proxyServer.
*
* @param proxyUrl new value of proxyUrl
* @param proxyServer new value of proxyServer
*/
public void setProxyServer(String proxyServer) {
this.proxyServer = proxyServer;
}
/**
* Get the value of proxyServer.
*
* @return the value of proxyServer
* @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead
*/
@Deprecated
public String getProxyUrl() {
return proxyServer;
}
/**
* Set the value of proxyServer.
*
* @param proxyUrl new value of proxyServer
* @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String)
* } instead
*/
@Deprecated
public void setProxyUrl(String proxyUrl) {
this.proxyUrl = proxyUrl;
this.proxyServer = proxyUrl;
}
/**
@@ -792,7 +815,7 @@ public class DependencyCheckScanAgent {
/**
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
* properties required to change the proxy url, port, and connection timeout.
* properties required to change the proxy server, port, and connection timeout.
*/
private void populateSettings() {
Settings.initialize();
@@ -808,8 +831,8 @@ public class DependencyCheckScanAgent {
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
if (proxyUrl != null && !proxyUrl.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
if (proxyServer != null && !proxyServer.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
}
if (proxyPort != null && !proxyPort.isEmpty()) {
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
@@ -888,7 +911,7 @@ public class DependencyCheckScanAgent {
"Unable to connect to the dependency-check database; analysis has stopped");
LOGGER.log(Level.FINE, "", ex);
} finally {
Settings.cleanup();
Settings.cleanup(true);
if (engine != null) {
engine.cleanup();
}

View File

@@ -98,11 +98,17 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
* @throws SuppressionParseException thrown if the XML cannot be parsed.
*/
private void loadSuppressionData() throws SuppressionParseException {
final SuppressionParser parser = new SuppressionParser();
File file = null;
try {
rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
} catch (SuppressionParseException ex) {
LOGGER.log(Level.FINE, "Unable to parse the base suppression data file", ex);
}
final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
if (suppressionFilePath == null) {
return;
}
File file = null;
boolean deleteTempFile = false;
try {
final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
@@ -132,9 +138,9 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
}
if (file != null) {
final SuppressionParser parser = new SuppressionParser();
try {
rules = parser.parseSuppressionRules(file);
//rules = parser.parseSuppressionRules(file);
rules.addAll(parser.parseSuppressionRules(file));
LOGGER.log(Level.FINE, rules.size() + " suppression rules were loaded.");
} catch (SuppressionParseException ex) {
final String msg = String.format("Unable to parse suppression xml file '%s'", file.getPath());

View File

@@ -27,6 +27,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -35,7 +36,9 @@ import java.util.logging.Logger;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
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.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipUtils;
@@ -99,10 +102,15 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
*/
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
/**
* The set of file extensions to remove from the engine's collection of dependencies.
*/
private static final Set<String> REMOVE_FROM_ANALYSIS = newHashSet("zip", "tar", "gz", "tgz"); //TODO add nupkg, apk, sar?
static {
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
if (additionalZipExt != null) {
final HashSet ext = new HashSet<String>(Arrays.asList(additionalZipExt));
final HashSet<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt));
ZIPPABLES.addAll(ext);
}
EXTENSIONS.addAll(ZIPPABLES);
@@ -178,7 +186,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
if (tempFileLocation != null && tempFileLocation.exists()) {
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
final boolean success = FileUtils.delete(tempFileLocation);
if (!success) {
if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) {
LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
}
}
@@ -199,9 +207,9 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
extractFiles(f, tmpDir, engine);
//make a copy
final List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
engine.scan(tmpDir);
final List<Dependency> newDependencies = engine.getDependencies();
List<Dependency> newDependencies = engine.getDependencies();
if (dependencies.size() != newDependencies.size()) {
//get the new dependencies
final Set<Dependency> dependencySet = new HashSet<Dependency>();
@@ -213,9 +221,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
final String displayPath = String.format("%s%s",
dependency.getFilePath(),
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
final String displayName = String.format("%s%s%s",
final String displayName = String.format("%s: %s",
dependency.getFileName(),
File.separator,
d.getFileName());
d.setFilePath(displayPath);
d.setFileName(displayName);
@@ -229,6 +236,40 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
}
}
}
if (this.REMOVE_FROM_ANALYSIS.contains(dependency.getFileExtension())) {
if ("zip".equals(dependency.getFileExtension()) && 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) {
final String msg = String.format("Unable to perform deep copy on '%s'", dependency.getActualFile().getPath());
LOGGER.log(Level.FINE, msg, ex);
}
}
engine.getDependencies().remove(dependency);
}
Collections.sort(engine.getDependencies());
}
@@ -411,4 +452,38 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
}
}
}
/**
* Attempts to determine if a zip file is actually a JAR file.
*
* @param dependency the dependency to check
* @return true if the dependency appears to be a JAR file; otherwise false
*/
private boolean isZipFileActuallyJarFile(Dependency dependency) {
boolean isJar = false;
ZipFile zip = null;
try {
zip = new ZipFile(dependency.getActualFilePath());
if (zip.getEntry("META-INF/MANIFEST.MF") != null
|| zip.getEntry("META-INF/maven") != null) {
final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
final ZipArchiveEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
final String name = entry.getName().toLowerCase();
if (name.endsWith(".class")) {
isJar = true;
break;
}
}
}
}
} catch (IOException ex) {
LOGGER.log(Level.FINE, String.format("Unable to unzip zip file '%s'", dependency.getFilePath()), ex);
} finally {
ZipFile.closeQuietly(zip);
}
return isJar;
}
}

View File

@@ -73,7 +73,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
/**
* Logger
*/
private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName());
private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName(), "dependencycheck-resources");
/**
* Builds the beginnings of a List for ProcessBuilder
@@ -106,7 +106,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
public void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
if (grokAssemblyExe == null) {
LOGGER.warning("GrokAssembly didn't get deployed");
LOGGER.warning("analyzer.AssemblyAnalyzer.notdeployed");
return;
}
@@ -114,16 +114,32 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
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:VisibilityModifier OFF
while (rdr.ready() && (line = rdr.readLine()) != null) {
LOGGER.log(Level.WARNING, "Error from GrokAssembly: {0}", line);
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.stderr", line);
}
// CheckStyle:VisibilityModifier ON
int rc = 0;
final Document doc = builder.parse(proc.getInputStream());
doc = builder.parse(proc.getInputStream());
try {
rc = proc.waitFor();
} catch (InterruptedException ie) {
return;
}
if (rc == 3) {
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.notassembly", dependency.getActualFilePath());
return;
} else if (rc != 0) {
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.rc", rc);
}
final XPath xpath = XPathFactory.newInstance().newXPath();
// First, see if there was an error
@@ -150,18 +166,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
product, Confidence.HIGH));
}
try {
rc = proc.waitFor();
} catch (InterruptedException ie) {
return;
}
if (rc == 3) {
LOGGER.log(Level.INFO, "{0} is not a valid assembly", dependency.getActualFilePath());
return;
} else if (rc != 0) {
LOGGER.log(Level.WARNING, "Return code {0} from GrokAssembly", rc);
}
} catch (IOException ioe) {
throw new AnalysisException(ioe);
} catch (SAXException saxe) {
@@ -201,9 +205,10 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
grokAssemblyExe = tempFile;
// Set the temp file to get deleted when we're done
grokAssemblyExe.deleteOnExit();
LOGGER.log(Level.FINE, "Extracted GrokAssembly.exe to {0}", grokAssemblyExe.getPath());
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.deployed", grokAssemblyExe.getPath());
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, "Could not extract GrokAssembly.exe: {0}", ioe.getMessage());
this.setEnabled(false);
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.notdeployed", ioe.getMessage());
throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
} finally {
if (fos != null) {
@@ -230,9 +235,11 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
final Process p = pb.start();
// Try evacuating the error stream
rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8"));
// CheckStyle:VisibilityModifier OFF
while (rdr.ready() && rdr.readLine() != null) {
// We expect this to complain
}
// CheckStyle:VisibilityModifier ON
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
final XPath xpath = XPathFactory.newInstance().newXPath();
final String error = xpath.evaluate("/assembly/error", doc);
@@ -240,15 +247,16 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
LOGGER.warning("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
LOGGER.fine("GrokAssembly.exe is not working properly");
grokAssemblyExe = null;
this.setEnabled(false);
throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
}
} catch (Throwable e) {
if (e instanceof AnalysisException) {
throw (AnalysisException) e;
} else {
LOGGER.warning("An error occured with the .NET AssemblyAnalyzer; "
+ "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
LOGGER.log(Level.FINE, "Could not execute GrokAssembly {0}", e.getMessage());
LOGGER.warning("analyzer.AssemblyAnalyzer.grokassembly.initialization.failed");
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.initialization.message", e.getMessage());
this.setEnabled(false);
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
}
} finally {
@@ -260,7 +268,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
}
}
}
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
@@ -272,7 +279,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
grokAssemblyExe.deleteOnExit();
}
} catch (SecurityException se) {
LOGGER.fine("Can't delete temporary GrokAssembly.exe");
LOGGER.fine("analyzer.AssemblyAnalyzer.grokassembly.notdeleted");
}
}

View File

@@ -57,6 +57,7 @@ import org.owasp.dependencycheck.utils.DependencyVersionUtil;
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class CPEAnalyzer implements Analyzer {
/**
* The Logger.
*/
@@ -90,6 +91,11 @@ public class CPEAnalyzer implements Analyzer {
*/
private CveDB cve;
/**
* The URL to perform a search of the NVD CVE data at NIST.
*/
public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
/**
* Returns the name of this analyzer.
*
@@ -164,29 +170,10 @@ public class CPEAnalyzer implements Analyzer {
* @throws ParseException is thrown when the Lucene query cannot be parsed.
*/
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
Confidence confidence = Confidence.HIGHEST;
String vendors = addEvidenceWithoutDuplicateTerms("", dependency.getVendorEvidence(), confidence);
String products = addEvidenceWithoutDuplicateTerms("", dependency.getProductEvidence(), confidence);
/* bug fix for #40 - version evidence is not showing up as "used" in the reports if there is no
* CPE identified. As such, we are "using" the evidence and ignoring the results. */
addEvidenceWithoutDuplicateTerms("", dependency.getVersionEvidence(), confidence);
int ctr = 0;
do {
if (!vendors.isEmpty() && !products.isEmpty()) {
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
dependency.getVendorEvidence().getWeighting());
for (IndexEntry e : entries) {
if (verifyEntry(e, dependency)) {
final String vendor = e.getVendor();
final String product = e.getProduct();
determineIdentifiers(dependency, vendor, product);
}
}
}
confidence = reduceConfidence(confidence);
//TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
String vendors = "";
String products = "";
for (Confidence confidence : Confidence.values()) {
if (dependency.getVendorEvidence().contains(confidence)) {
vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
}
@@ -195,10 +182,28 @@ public class CPEAnalyzer implements Analyzer {
}
/* bug fix for #40 - version evidence is not showing up as "used" in the reports if there is no
* CPE identified. As such, we are "using" the evidence and ignoring the results. */
if (dependency.getVersionEvidence().contains(confidence)) {
addEvidenceWithoutDuplicateTerms("", dependency.getVersionEvidence(), confidence);
// if (dependency.getVersionEvidence().contains(confidence)) {
// addEvidenceWithoutDuplicateTerms("", dependency.getVersionEvidence(), confidence);
// }
if (!vendors.isEmpty() && !products.isEmpty()) {
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
dependency.getVendorEvidence().getWeighting());
if (entries == null) {
continue;
}
boolean identifierAdded = false;
for (IndexEntry e : entries) {
if (verifyEntry(e, dependency)) {
final String vendor = e.getVendor();
final String product = e.getProduct();
identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
}
}
if (identifierAdded) {
break;
}
}
} while ((++ctr) < 4);
}
}
/**
@@ -233,22 +238,6 @@ public class CPEAnalyzer implements Analyzer {
return sb.toString().trim();
}
/**
* Reduces the given confidence by one level. This returns LOW if the confidence passed in is not HIGH.
*
* @param c the confidence to reduce.
* @return One less then the confidence passed in.
*/
private Confidence reduceConfidence(final Confidence c) {
if (c == Confidence.HIGHEST) {
return Confidence.HIGH;
} else if (c == Confidence.HIGH) {
return Confidence.MEDIUM;
} else {
return Confidence.LOW;
}
}
/**
* <p>
* Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and
@@ -263,27 +252,24 @@ public class CPEAnalyzer implements Analyzer {
* @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
* @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
* @return a list of possible CPE values
* @throws CorruptIndexException when the Lucene index is corrupt
* @throws IOException when the Lucene index is not found
* @throws ParseException when the generated query is not valid
*/
protected List<IndexEntry> searchCPE(String vendor, String product,
Set<String> vendorWeightings, Set<String> productWeightings)
throws CorruptIndexException, IOException, ParseException {
Set<String> vendorWeightings, Set<String> productWeightings) {
final ArrayList<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
if (searchString == null) {
return ret;
}
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
for (ScoreDoc d : docs.scoreDocs) {
if (d.score >= 0.08) {
final Document doc = cpe.getDocument(d.doc);
final IndexEntry entry = new IndexEntry();
entry.setVendor(doc.get(Fields.VENDOR));
entry.setProduct(doc.get(Fields.PRODUCT));
try {
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
for (ScoreDoc d : docs.scoreDocs) {
if (d.score >= 0.08) {
final Document doc = cpe.getDocument(d.doc);
final IndexEntry entry = new IndexEntry();
entry.setVendor(doc.get(Fields.VENDOR));
entry.setProduct(doc.get(Fields.PRODUCT));
// if (d.score < 0.08) {
// System.out.print(entry.getVendor());
// System.out.print(":");
@@ -291,13 +277,23 @@ public class CPEAnalyzer implements Analyzer {
// System.out.print(":");
// System.out.println(d.score);
// }
entry.setSearchScore(d.score);
if (!ret.contains(entry)) {
ret.add(entry);
entry.setSearchScore(d.score);
if (!ret.contains(entry)) {
ret.add(entry);
}
}
}
return ret;
} catch (ParseException ex) {
final String msg = String.format("Unable to parse: %s", searchString);
LOGGER.log(Level.WARNING, "An error occured querying the CPE data. See the log for more details.");
LOGGER.log(Level.INFO, msg, ex);
} catch (IOException ex) {
final String msg = String.format("IO Error with search string: %s", searchString);
LOGGER.log(Level.WARNING, "An error occured reading CPE data. See the log for more details.");
LOGGER.log(Level.INFO, msg, ex);
}
return ret;
return null;
}
/**
@@ -502,14 +498,21 @@ public class CPEAnalyzer implements Analyzer {
* @param dependency the Dependency being analyzed
* @param vendor the vendor for the CPE being analyzed
* @param product the product for the CPE being analyzed
* @param currentConfidence the current confidence being used during analysis
* @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
*/
private void determineIdentifiers(Dependency dependency, String vendor, String product) throws UnsupportedEncodingException {
protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
Confidence currentConfidence) throws UnsupportedEncodingException {
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
DependencyVersion bestGuess = new DependencyVersion("-");
Confidence bestGuessConf = null;
boolean hasBroadMatch = false;
final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
for (Confidence conf : Confidence.values()) {
// if (conf.compareTo(currentConfidence) > 0) {
// break;
// }
for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
if (evVer == null) {
@@ -522,9 +525,13 @@ public class CPEAnalyzer implements Analyzer {
} else {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
}
if (dbVer == null //special case, no version specified - everything is vulnerable
|| evVer.equals(dbVer)) { //yeah! exact match
final String url = String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(vs.getName(), "UTF-8"));
if (dbVer == null) { //special case, no version specified - everything is vulnerable
hasBroadMatch = true;
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
collected.add(match);
} else if (evVer.equals(dbVer)) { //yeah! exact match
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
collected.add(match);
} else {
@@ -549,7 +556,11 @@ public class CPEAnalyzer implements Analyzer {
}
}
final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
final String url = null; //String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(cpeName, "UTF-8"));
String url = null;
if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
}
if (bestGuessConf == null) {
bestGuessConf = Confidence.LOW;
}
@@ -559,6 +570,7 @@ public class CPEAnalyzer implements Analyzer {
Collections.sort(collected);
final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
boolean identifierAdded = false;
for (IdentifierMatch m : collected) {
if (bestIdentifierQuality.equals(m.getConfidence())
&& bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
@@ -569,8 +581,10 @@ public class CPEAnalyzer implements Analyzer {
i.setConfidence(bestEvidenceQuality);
}
dependency.addIdentifier(i);
identifierAdded = true;
}
}
return identifierAdded;
}
/**
@@ -585,7 +599,12 @@ public class CPEAnalyzer implements Analyzer {
/**
* A best guess for the CPE.
*/
BEST_GUESS
BEST_GUESS,
/**
* The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS
* that only specifies vendor/product.
*/
BROAD_MATCH
}
/**

View File

@@ -0,0 +1,201 @@
/*
* 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) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.central.CentralSearch;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.InvalidSettingException;
import org.owasp.dependencycheck.utils.Settings;
/**
* Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's
* SHA-1 digest.
*
* @author colezlaw
*/
public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The logger.
*/
private static final Logger LOGGER = Logger.getLogger(CentralAnalyzer.class.getName());
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Central Analyzer";
/**
* The phase in which this analyzer runs.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
/**
* The types of files on which this will work.
*/
private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
/**
* The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has
* occurred.
*/
private boolean errorFlag = false;
/**
* The searcher itself.
*/
private CentralSearch searcher;
/**
* Field indicating if the analyzer is enabled.
*/
private final boolean enabled = checkEnabled();
/**
* Determine whether to enable this analyzer or not.
*
* @return whether the analyzer should be enabled
*/
@Override
public boolean isEnabled() {
return enabled;
}
/**
* Determines if this analyzer is enabled.
*
* @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
*/
private boolean checkEnabled() {
boolean retval = false;
try {
if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
|| NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
LOGGER.info("Enabling the Central analyzer");
retval = true;
} else {
LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
}
} else {
LOGGER.info("Central analyzer disabled");
}
} catch (InvalidSettingException ise) {
LOGGER.warning("Invalid setting. Disabling the Central analyzer");
}
return retval;
}
/**
* Initializes the analyzer once before any analysis is performed.
*
* @throws Exception if there's an error during initialization
*/
@Override
public void initializeFileTypeAnalyzer() throws Exception {
LOGGER.fine("Initializing Central analyzer");
LOGGER.fine(String.format("Central analyzer enabled: %s", isEnabled()));
if (isEnabled()) {
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
LOGGER.fine(String.format("Central Analyzer URL: %s", searchUrl));
searcher = new CentralSearch(new URL(searchUrl));
}
}
/**
* Returns the analyzer's name.
*
* @return the name of the analyzer
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the key used in the properties file to to reference the analyzer's enabled property.
*
* @return the analyzer's enabled property setting key.
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
}
/**
* Returns the analysis phase under which the analyzer runs.
*
* @return the phase under which the analyzer runs
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* Returns the extensions for which this Analyzer runs.
*
* @return the extensions for which this Analyzer runs
*/
@Override
public Set<String> getSupportedExtensions() {
return SUPPORTED_EXTENSIONS;
}
/**
* Performs the analysis.
*
* @param dependency the dependency to analyze
* @param engine the engine
* @throws AnalysisException when there's an exception during analysis
*/
@Override
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
if (errorFlag || !isEnabled()) {
return;
}
try {
final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
for (MavenArtifact ma : mas) {
LOGGER.fine(String.format("Central analyzer found artifact (%s) for dependency (%s)", ma.toString(), dependency.getFileName()));
dependency.addAsEvidence("central", ma, confidence);
}
} catch (IllegalArgumentException iae) {
LOGGER.info(String.format("invalid sha1-hash on %s", dependency.getFileName()));
} catch (FileNotFoundException fnfe) {
LOGGER.fine(String.format("Artifact not found in repository: '%s", dependency.getFileName()));
} catch (IOException ioe) {
LOGGER.log(Level.FINE, "Could not connect to Central search", ioe);
errorFlag = true;
}
}
}

View File

@@ -112,7 +112,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
while (subIterator.hasNext()) {
final Dependency nextDependency = subIterator.next();
if (hashesMatch(dependency, nextDependency)) {
if (isCore(dependency, nextDependency)) {
if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
} else {
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
@@ -390,4 +390,43 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
}
return false;
}
/**
* Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to
* determine if the first path is smaller.
*
* @param left the first path to compare
* @param right the second path to compare
* @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code>
*/
protected boolean firstPathIsShortest(String left, String right) {
final String leftPath = left.replace('\\', '/');
final String rightPath = right.replace('\\', '/');
final int leftCount = countChar(leftPath, '/');
final int rightCount = countChar(rightPath, '/');
if (leftCount == rightCount) {
return leftPath.compareTo(rightPath) <= 0;
} else {
return leftCount < rightCount;
}
}
/**
* Counts the number of times the character is present in the string.
*
* @param string the string to count the characters in
* @param c the character to count
* @return the number of times the character is present in the string
*/
private int countChar(String string, char c) {
int count = 0;
final int max = string.length();
for (int i = 0; i < max; i++) {
if (c == string.charAt(i)) {
count++;
}
}
return count;
}
}

View File

@@ -86,11 +86,46 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
removeJreEntries(dependency);
removeBadMatches(dependency);
removeBadSpringMatches(dependency);
removeWrongVersionMatches(dependency);
removeSpuriousCPE(dependency);
removeDuplicativeEntriesFromJar(dependency, engine);
addFalseNegativeCPEs(dependency);
}
/**
* Removes inaccurate matches on springframework CPEs.
*
* @param dependency the dependency to test for and remove known inaccurate CPE matches
*/
private void removeBadSpringMatches(Dependency dependency) {
String mustContain = null;
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);
if (endPoint >= 0) {
mustContain = i.getValue().substring(19, endPoint).toLowerCase();
break;
}
}
}
}
if (mustContain != null) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) {
final Identifier i = itr.next();
if ("cpe".contains(i.getType())
&& i.getValue() != null
&& i.getValue().startsWith("cpe:/a:springsource:")
&& !i.getValue().toLowerCase().contains(mustContain)) {
itr.remove();
//dependency.getIdentifiers().remove(i);
}
}
}
}
/**
* <p>
* Intended to remove spurious CPE entries. By spurious we mean duplicate, less specific CPE entries.</p>
@@ -160,11 +195,20 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
*/
public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
+ "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
+ "jdk|jre|jsf|jsse)($|:.*)");
+ "jdk|jre|jsse)($|:.*)");
/**
* Regex to identify core jsf libraries.
*/
public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
/**
* Regex to identify core java library files. This is currently incomplete.
*/
public static final Pattern CORE_FILES = Pattern.compile("^((alt[-])?rt|jsf[-].*|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
/**
* Regex to identify core jsf java library files. This is currently incomplete.
*/
public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
/**
* Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar
@@ -181,27 +225,11 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
if (coreCPE.matches() && !coreFiles.matches()) {
itr.remove();
}
//replaced with the regex above.
// if (("cpe:/a:sun:java".equals(i.getValue())
// || "cpe:/a:oracle:java".equals(i.getValue())
// || "cpe:/a:ibm:java".equals(i.getValue())
// || "cpe:/a:sun:j2se".equals(i.getValue())
// || "cpe:/a:oracle:j2se".equals(i.getValue())
// || i.getValue().startsWith("cpe:/a:sun:java:")
// || i.getValue().startsWith("cpe:/a:sun:j2se:")
// || i.getValue().startsWith("cpe:/a:sun:java:jre")
// || i.getValue().startsWith("cpe:/a:sun:java:jdk")
// || i.getValue().startsWith("cpe:/a:sun:java_se")
// || i.getValue().startsWith("cpe:/a:oracle:java_se")
// || i.getValue().startsWith("cpe:/a:oracle:java:")
// || i.getValue().startsWith("cpe:/a:oracle:j2se:")
// || i.getValue().startsWith("cpe:/a:oracle:jre")
// || i.getValue().startsWith("cpe:/a:oracle:jdk")
// || i.getValue().startsWith("cpe:/a:ibm:java:"))
// && !dependency.getFileName().toLowerCase().endsWith("rt.jar")) {
// itr.remove();
// }
final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
itr.remove();
}
}
}
@@ -248,14 +276,33 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
//TODO move this startsWith expression to a configuration file?
if ("cpe".equals(i.getType())) {
if ((i.getValue().matches(".*c\\+\\+.*")
|| i.getValue().startsWith("cpe:/a:jquery:jquery")
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|| i.getValue().startsWith("cpe:/a:yahoo:yui")
|| i.getValue().startsWith("cpe:/a:file:file")
|| i.getValue().startsWith("cpe:/a:mozilla:mozilla")
|| i.getValue().startsWith("cpe:/a:cvs:cvs")
|| i.getValue().startsWith("cpe:/a:ftp:ftp")
|| i.getValue().startsWith("cpe:/a:ssh:ssh"))
|| i.getValue().startsWith("cpe:/a:tcp:tcp")
|| i.getValue().startsWith("cpe:/a:ssh:ssh")
|| i.getValue().startsWith("cpe:/a:lookup:lookup"))
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|| dependency.getFileName().toLowerCase().endsWith(".exe")
|| dependency.getFileName().toLowerCase().endsWith(".nuspec")
|| dependency.getFileName().toLowerCase().endsWith(".nupkg"))) {
itr.remove();
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|| i.getValue().startsWith("cpe:/a:yahoo:yui"))
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
itr.remove();
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|| i.getValue().startsWith("cpe:/a:microsoft:visio")
|| i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
|| i.getValue().startsWith("cpe:/a:microsoft:office"))
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
itr.remove();
@@ -266,7 +313,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
&& !dependency.getEvidenceUsed().containsUsedString("m-core")) {
itr.remove();
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
&& !dependency.getFileName().toLowerCase().matches("jboss-[\\d\\.]+(GA)?\\.jar")) {
&& !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
itr.remove();
}
}
@@ -314,6 +361,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
* @param dependency the dependency being analyzed
*/
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();
@@ -329,20 +377,92 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
try {
dependency.addIdentifier("cpe",
newCpe,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe, "UTF-8")));
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe2,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe2, "UTF-8")));
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe3,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe3, "UTF-8")));
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
dependency.addIdentifier("cpe",
newCpe4,
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe4, "UTF-8")));
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
} catch (UnsupportedEncodingException ex) {
LOGGER.log(Level.FINE, null, ex);
}
}
}
}
/**
* Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM
* entries or other types of files (such as DLLs and EXEs) being contained within the JAR.
*
* @param dependency the dependency that might be a duplicate
* @param engine the engine used to scan all dependencies
*/
private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
|| "dll".equals(dependency.getFileExtension())
|| "exe".equals(dependency.getFileExtension())) {
String parentPath = dependency.getFilePath().toLowerCase();
if (parentPath.contains(".jar")) {
parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
final Dependency parent = findDependency(parentPath, engine.getDependencies());
if (parent != null) {
boolean remove = false;
for (Identifier i : dependency.getIdentifiers()) {
if ("cpe".equals(i.getType())) {
final String trimmedCPE = trimCpeToVendor(i.getValue());
for (Identifier parentId : parent.getIdentifiers()) {
if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
remove |= true;
}
}
}
if (!remove) { //we can escape early
return;
}
}
if (remove) {
engine.getDependencies().remove(dependency);
}
}
}
}
}
/**
* Retrieves a given dependency, based on a given path, from a list of dependencies.
*
* @param dependencyPath the path of the dependency to return
* @param dependencies the collection of dependencies to search
* @return the dependency object for the given path, otherwise null
*/
private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) {
for (Dependency d : dependencies) {
if (d.getFilePath().equalsIgnoreCase(dependencyPath)) {
return d;
}
}
return null;
}
/**
* Takes a full CPE and returns the CPE trimmed to include only vendor and product.
*
* @param value the CPE value to trim
* @return a CPE value that only includes the vendor and product
*/
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
if (pos2 < 0) {
return value;
} else {
return value.substring(0, pos2);
}
}
}

View File

@@ -73,7 +73,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
//strip any path information that may get added by ArchiveAnalyzer, etc.
final File f = new File(dependency.getFileName());
final File f = dependency.getActualFile();
String fileName = f.getName();
//remove file extension

View File

@@ -64,7 +64,6 @@ import org.owasp.dependencycheck.jaxb.pom.MavenNamespaceFilter;
import org.owasp.dependencycheck.jaxb.pom.generated.License;
import org.owasp.dependencycheck.jaxb.pom.generated.Model;
import org.owasp.dependencycheck.jaxb.pom.generated.Organization;
import org.owasp.dependencycheck.jaxb.pom.generated.Parent;
import org.owasp.dependencycheck.utils.FileUtils;
import org.owasp.dependencycheck.utils.NonClosingStream;
import org.owasp.dependencycheck.utils.Settings;
@@ -74,7 +73,6 @@ import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
/**
*
* Used to load a JAR file and collect information that can be used to determine the associated CPE.
*
* @author Jeremy Long <jeremy.long@owasp.org>
@@ -138,7 +136,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
"include-resource",
"embed-dependency",
"ipojo-components",
"ipojo-extension");
"ipojo-extension",
"eclipse-sourcereferences");
/**
* item in some manifest, should be considered medium confidence.
*/
@@ -170,7 +169,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
*/
public JarAnalyzer() {
try {
final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.jaxb.pom.generated");
//final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.jaxb.pom.generated");
final JAXBContext jaxbContext = JAXBContext.newInstance(Model.class);
pomUnmarshaller = jaxbContext.createUnmarshaller();
} catch (JAXBException ex) { //guess we will just have a null pointer exception later...
LOGGER.log(Level.SEVERE, "Unable to load parser. See the log for more details.");
@@ -293,13 +293,27 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
LOGGER.log(Level.FINE, msg, ex);
return false;
}
File externalPom = null;
if (pomEntries.isEmpty()) {
return false;
if (dependency.getActualFilePath().matches(".*\\.m2.repository\\b.*")) {
String pomPath = dependency.getActualFilePath();
pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom";
externalPom = new File(pomPath);
if (externalPom.isFile()) {
pomEntries.add(pomPath);
} else {
return false;
}
} else {
return false;
}
}
for (String path : pomEntries) {
Properties pomProperties = null;
try {
pomProperties = retrievePomProperties(path, jar);
if (externalPom == null) {
pomProperties = retrievePomProperties(path, jar);
}
} catch (IOException ex) {
LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
}
@@ -313,19 +327,23 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
final String displayPath = String.format("%s%s%s",
dependency.getFilePath(),
File.separator,
path); //.replaceAll("[\\/]", File.separator));
path);
final String displayName = String.format("%s%s%s",
dependency.getFileName(),
File.separator,
path); //.replaceAll("[\\/]", File.separator));
path);
newDependency.setFileName(displayName);
newDependency.setFilePath(displayPath);
addPomEvidence(newDependency, pom, pomProperties);
setPomEvidence(newDependency, pom, pomProperties, null);
engine.getDependencies().add(newDependency);
Collections.sort(engine.getDependencies());
} else {
pom = retrievePom(path, jar);
if (externalPom == null) {
pom = retrievePom(path, jar);
} else {
pom = retrievePom(externalPom);
}
foundSomething |= setPomEvidence(dependency, pom, pomProperties, classes);
}
} catch (AnalysisException ex) {
@@ -345,16 +363,25 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
* @return a Properties object or null if no pom.properties was found
* @throws IOException thrown if there is an exception reading the pom.properties
*/
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "OS_OPEN_STREAM",
justification = "The reader is closed by closing the zipEntry")
private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
Properties pomProperties = null;
final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
final ZipEntry propEntry = jar.getEntry(propPath);
if (propEntry != null) {
final Reader reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
pomProperties = new Properties();
pomProperties.load(reader);
Reader reader = null;
try {
reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
pomProperties = new Properties();
pomProperties.load(reader);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
LOGGER.log(Level.FINEST, "close error", ex);
}
}
}
}
return pomProperties;
}
@@ -514,6 +541,41 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
return model;
}
/**
* Reads in the specified POM and converts it to a Model.
*
* @param file the pom.xml file
* @return returns a
* @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
* {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
*/
private Model retrievePom(File file) throws AnalysisException {
Model model = null;
try {
final FileInputStream stream = new FileInputStream(file);
final InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
final InputSource xml = new InputSource(reader);
final SAXSource source = new SAXSource(xml);
model = readPom(source);
} catch (SecurityException ex) {
final String msg = String.format("Unable to parse pom '%s'; invalid signature", file.getPath());
LOGGER.log(Level.WARNING, msg);
LOGGER.log(Level.FINE, null, ex);
throw new AnalysisException(ex);
} catch (IOException ex) {
final String msg = String.format("Unable to parse pom '%s'(IO Exception)", file.getPath());
LOGGER.log(Level.WARNING, msg);
LOGGER.log(Level.FINE, "", ex);
throw new AnalysisException(ex);
} catch (Throwable ex) {
final String msg = String.format("Unexpected error during parsing of the pom '%s'", file.getPath());
LOGGER.log(Level.WARNING, msg);
LOGGER.log(Level.FINE, "", ex);
throw new AnalysisException(ex);
}
return model;
}
/**
* Retrieves the specified POM from a jar file and converts it to a Model.
*
@@ -558,37 +620,90 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
*/
private boolean setPomEvidence(Dependency dependency, Model pom, Properties pomProperties, ArrayList<ClassNameInformation> classes) {
boolean foundSomething = false;
boolean addAsIdentifier = true;
if (pom == null) {
return foundSomething;
}
String groupid = interpolateString(pom.getGroupId(), pomProperties);
if (groupid != null && !groupid.isEmpty()) {
if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
groupid = groupid.substring(4);
String parentGroupId = null;
if (pom.getParent() != null) {
parentGroupId = interpolateString(pom.getParent().getGroupId(), pomProperties);
if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
groupid = parentGroupId;
}
}
final String originalGroupID = groupid;
if (groupid != null && !groupid.isEmpty()) {
foundSomething = true;
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
addMatchingValues(classes, groupid, dependency.getVendorEvidence());
addMatchingValues(classes, groupid, dependency.getProductEvidence());
if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
}
} else {
addAsIdentifier = false;
}
String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
String parentArtifactId = null;
if (pom.getParent() != null) {
parentArtifactId = interpolateString(pom.getParent().getArtifactId(), pomProperties);
if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
artifactid = parentArtifactId;
}
}
final String originalArtifactID = artifactid;
if (artifactid != null && !artifactid.isEmpty()) {
if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
artifactid = artifactid.substring(4);
}
foundSomething = true;
dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGH);
dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
addMatchingValues(classes, artifactid, dependency.getProductEvidence());
if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
}
} else {
addAsIdentifier = false;
}
//version
final String version = interpolateString(pom.getVersion(), pomProperties);
String version = interpolateString(pom.getVersion(), pomProperties);
String parentVersion = null;
if (pom.getParent() != null) {
parentVersion = interpolateString(pom.getParent().getVersion(), pomProperties);
if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
version = parentVersion;
}
}
if (version != null && !version.isEmpty()) {
foundSomething = true;
dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
}
} else {
addAsIdentifier = false;
}
if (addAsIdentifier) {
dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.LOW);
}
// org name
final Organization org = pom.getOrganization();
if (org != null && org.getName() != null) {
@@ -647,7 +762,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
//TODO remove weighting
vendor.addWeighting(entry.getKey());
if (addPackagesAsEvidence && entry.getKey().length() > 1) {
vendor.addEvidence("jar", "package", entry.getKey(), Confidence.LOW);
vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
}
}
}
@@ -656,7 +771,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
if (ratio > 0.5) {
product.addWeighting(entry.getKey());
if (addPackagesAsEvidence && entry.getKey().length() > 1) {
product.addEvidence("jar", "package", entry.getKey(), Confidence.LOW);
product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
}
}
}
@@ -690,7 +805,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
&& !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
&& !dependency.getFileName().toLowerCase().endsWith("-src.jar")
&& !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
LOGGER.log(Level.INFO,
LOGGER.log(Level.FINE,
String.format("Jar file '%s' does not contain a manifest.",
dependency.getFileName()));
}
@@ -764,6 +879,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
&& !key.endsWith("class-path")
&& !key.endsWith("-scm") //todo change this to a regex?
&& !key.startsWith("scm-")
&& !value.trim().startsWith("scm:")
&& !isImportPackage(key, value)
&& !isPackage(key, value)) {
@@ -1111,7 +1227,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
* @param evidence the evidence collection to add new entries too
*/
private void addMatchingValues(ArrayList<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
if (value == null || value.isEmpty()) {
if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
return;
}
final String text = value.toLowerCase();
@@ -1138,93 +1254,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
* Adds evidence from the POM to the dependency. This includes the GAV and in some situations the parent GAV if
* specified.
*
* @param dependency the dependency being analyzed
* @param pom the POM data
* @param pomProperties the properties file associated with the pom
*/
private void addPomEvidence(Dependency dependency, Model pom, Properties pomProperties) {
if (pom == null) {
return;
}
String groupid = interpolateString(pom.getGroupId(), pomProperties);
if (groupid != null && !groupid.isEmpty()) {
if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
groupid = groupid.substring(4);
}
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGH);
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
}
String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
if (artifactid != null && !artifactid.isEmpty()) {
if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
artifactid = artifactid.substring(4);
}
dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
}
final String version = interpolateString(pom.getVersion(), pomProperties);
if (version != null && !version.isEmpty()) {
dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
}
final Parent parent = pom.getParent(); //grab parent GAV
if (parent != null) {
final String parentGroupId = interpolateString(parent.getGroupId(), pomProperties);
if (parentGroupId != null && !parentGroupId.isEmpty()) {
if (groupid == null || groupid.isEmpty()) {
dependency.getVendorEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.HIGH);
} else {
dependency.getVendorEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.MEDIUM);
}
dependency.getProductEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.LOW);
}
final String parentArtifactId = interpolateString(parent.getArtifactId(), pomProperties);
if (parentArtifactId != null && !parentArtifactId.isEmpty()) {
if (artifactid == null || artifactid.isEmpty()) {
dependency.getProductEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.HIGH);
} else {
dependency.getProductEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.MEDIUM);
}
dependency.getVendorEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.LOW);
}
final String parentVersion = interpolateString(parent.getVersion(), pomProperties);
if (parentVersion != null && !parentVersion.isEmpty()) {
if (version == null || version.isEmpty()) {
dependency.getVersionEvidence().addEvidence("pom", "parent.version", parentVersion, Confidence.HIGH);
} else {
dependency.getVersionEvidence().addEvidence("pom", "parent.version", parentVersion, Confidence.LOW);
}
}
}
// org name
final Organization org = pom.getOrganization();
if (org != null && org.getName() != null) {
final String orgName = interpolateString(org.getName(), pomProperties);
if (orgName != null && !orgName.isEmpty()) {
dependency.getVendorEvidence().addEvidence("pom", "organization name", orgName, Confidence.HIGH);
}
}
//pom name
final String pomName = interpolateString(pom.getName(), pomProperties);
if (pomName != null && !pomName.isEmpty()) {
dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
}
//Description
if (pom.getDescription() != null) {
final String description = interpolateString(pom.getDescription(), pomProperties);
if (description != null && !description.isEmpty()) {
addDescription(dependency, description, "pom", "description");
}
}
extractLicense(pom, pomProperties, dependency);
}
/**
* Extracts the license information from the pom and adds it to the dependency.
*

View File

@@ -30,6 +30,7 @@ import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.data.nexus.NexusSearch;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.utils.InvalidSettingException;
import org.owasp.dependencycheck.utils.Settings;
/**
@@ -48,6 +49,11 @@ import org.owasp.dependencycheck.utils.Settings;
*/
public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The default URL - this will be used by the CentralAnalyzer to determine whether to enable this.
*/
public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
/**
* The logger.
*/
@@ -73,6 +79,47 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
*/
private NexusSearch searcher;
/**
* Field indicating if the analyzer is enabled.
*/
private final boolean enabled = checkEnabled();
/**
* Determines if this analyzer is enabled
*
* @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
*/
private boolean checkEnabled() {
/* Enable this analyzer ONLY if the Nexus URL has been set to something
other than the default one (if it's the default one, we'll use the
central one) and it's enabled by the user.
*/
boolean retval = false;
try {
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;
} else {
LOGGER.info("Nexus analyzer disabled, using Central instead");
}
} catch (InvalidSettingException ise) {
LOGGER.warning("Invalid setting. Disabling Nexus analyzer");
}
return retval;
}
/**
* Determine whether to enable this analyzer or not.
*
* @return whether the analyzer should be enabled
*/
@Override
public boolean isEnabled() {
return enabled;
}
/**
* Initializes the analyzer once before any analysis is performed.
*
@@ -149,20 +196,12 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
*/
@Override
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
if (!isEnabled()) {
return;
}
try {
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
if (ma.getGroupId() != null && !"".equals(ma.getGroupId())) {
dependency.getVendorEvidence().addEvidence("nexus", "groupid", ma.getGroupId(), Confidence.HIGH);
}
if (ma.getArtifactId() != null && !"".equals(ma.getArtifactId())) {
dependency.getProductEvidence().addEvidence("nexus", "artifactid", ma.getArtifactId(), Confidence.HIGH);
}
if (ma.getVersion() != null && !"".equals(ma.getVersion())) {
dependency.getVersionEvidence().addEvidence("nexus", "version", ma.getVersion(), Confidence.HIGH);
}
if (ma.getArtifactUrl() != null && !"".equals(ma.getArtifactUrl())) {
dependency.addIdentifier("maven", ma.toString(), ma.getArtifactUrl(), Confidence.HIGHEST);
}
dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
} catch (IllegalArgumentException iae) {
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));

View File

@@ -0,0 +1,151 @@
/*
* 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) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.central;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.utils.Settings;
import org.owasp.dependencycheck.utils.URLConnectionFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
/**
* Class of methods to search Maven Central via Central.
*
* @author colezlaw
*/
public class CentralSearch {
/**
* The URL for the Central service
*/
private final URL rootURL;
/**
* Whether to use the Proxy when making requests
*/
private boolean useProxy;
/**
* Used for logging.
*/
private static final Logger LOGGER = Logger.getLogger(CentralSearch.class.getName());
/**
* Creates a NexusSearch for the given repository URL.
*
* @param rootURL the URL of the repository on which searches should execute. Only parameters are added to this (so
* it should end in /select)
*/
public CentralSearch(URL rootURL) {
this.rootURL = rootURL;
if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
useProxy = true;
LOGGER.fine("Using proxy");
} else {
useProxy = false;
LOGGER.fine("Not using proxy");
}
}
/**
* Searches the configured Central URL for the given sha1 hash. If the artifact is found, a
* <code>MavenArtifact</code> is populated with the GAV.
*
* @param sha1 the SHA-1 hash string for which to search
* @return the populated Maven GAV.
* @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not
* found.
*/
public List<MavenArtifact> searchSha1(String sha1) throws IOException {
if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
throw new IllegalArgumentException("Invalid SHA1 format");
}
final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
LOGGER.fine(String.format("Searching Central url %s", url.toString()));
// 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
// 2) Otherwise, don't use the proxy (either the proxy isn't configured,
// or proxy is specifically set to false)
final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
conn.setDoOutput(true);
// JSON would be more elegant, but there's not currently a dependency
// on JSON, so don't want to add one just for this
conn.addRequestProperty("Accept", "application/xml");
conn.connect();
if (conn.getResponseCode() == 200) {
boolean missing = false;
try {
final DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
final Document doc = builder.parse(conn.getInputStream());
final XPath xpath = XPathFactory.newInstance().newXPath();
final String numFound = xpath.evaluate("/response/result/@numFound", doc);
if ("0".equals(numFound)) {
missing = true;
} else {
final ArrayList<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));
LOGGER.finest(String.format("GroupId: %s", g));
final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
LOGGER.finest(String.format("ArtifactId: %s", a));
final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
LOGGER.finest(String.format("Version: %s", v));
result.add(new MavenArtifact(g, a, v, url.toString()));
}
return result;
}
} catch (Throwable e) {
// Anything else is jacked up XML stuff that we really can't recover
// from well
throw new IOException(e.getMessage(), e);
}
if (missing) {
throw new FileNotFoundException("Artifact not found in Central");
}
} else {
final String msg = String.format("Could not connect to Central received response code: %d %s",
conn.getResponseCode(), conn.getResponseMessage());
LOGGER.fine(msg);
throw new IOException(msg);
}
return null;
}
}

View File

@@ -0,0 +1,14 @@
/**
* <html>
* <head>
* <title>org.owasp.dependencycheck.data.central</title>
* </head>
* <body>
* <p>
* Contains classes related to searching Maven Central.</p>
* <p>
* These are used to abstract Maven Central searching away from OWASP Dependency Check so they can be reused elsewhere.</p>
* </body>
* </html>
*/
package org.owasp.dependencycheck.data.central;

View File

@@ -54,6 +54,7 @@ import org.owasp.dependencycheck.utils.Pair;
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public final class CpeMemoryIndex {
/**
* The logger.
*/
@@ -160,7 +161,7 @@ public final class CpeMemoryIndex {
*/
@SuppressWarnings("unchecked")
private Analyzer createSearchingAnalyzer() {
final Map fieldAnalyzers = new HashMap();
final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);

View File

@@ -22,7 +22,7 @@ package org.owasp.dependencycheck.data.cpe;
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public abstract class Fields {
public final class Fields {
/**
* The key for the name document id.
@@ -36,7 +36,10 @@ public abstract class Fields {
* The key for the product field.
*/
public static final String PRODUCT = "product";
/**
* The key for the version field.
* Private constructor as this is more of an enumeration rather then a full class.
*/
private Fields() {
}
}

View File

@@ -29,10 +29,12 @@ import java.util.logging.Logger;
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public final class CweDB {
/**
* The Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CweDB.class.getName());
/**
* Empty private constructor as this is a utility class.
*/
@@ -55,7 +57,9 @@ public final class CweDB {
final String filePath = "data/cwe.hashmap.serialized";
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
oin = new ObjectInputStream(input);
return (HashMap<String, String>) oin.readObject();
@SuppressWarnings("unchecked")
final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject();
return ret;
} catch (ClassNotFoundException ex) {
LOGGER.log(Level.WARNING, "Unable to load CWE data. This should not be an issue.");
LOGGER.log(Level.FINE, null, ex);

View File

@@ -64,7 +64,7 @@ public class NexusSearch {
public NexusSearch(URL rootURL) {
this.rootURL = rootURL;
try {
if (null != Settings.getString(Settings.KEYS.PROXY_URL)
if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) {
useProxy = true;
LOGGER.fine("Using proxy");

View File

@@ -42,6 +42,7 @@ import org.owasp.dependencycheck.utils.Settings;
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public final class ConnectionFactory {
/**
* The Logger.
*/
@@ -49,7 +50,7 @@ public final class ConnectionFactory {
/**
* The version of the current DB Schema.
*/
public static final String DB_SCHEMA_VERSION = "2.9";
public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
/**
* Resource location for SQL file used to create the database schema.
*/
@@ -111,7 +112,10 @@ public final class ConnectionFactory {
//yes, yes - hard-coded password - only if there isn't one in the properties file.
password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
try {
connectionString = getConnectionString();
connectionString = Settings.getConnectionString(
Settings.KEYS.DB_CONNECTION_STRING,
Settings.KEYS.DB_FILE_NAME,
Settings.KEYS.DB_VERSION);
} catch (IOException ex) {
LOGGER.log(Level.FINE,
"Unable to retrieve the database connection string", ex);
@@ -120,7 +124,7 @@ public final class ConnectionFactory {
boolean shouldCreateSchema = false;
try {
if (connectionString.startsWith("jdbc:h2:file:")) { //H2
shouldCreateSchema = !dbSchemaExists();
shouldCreateSchema = !h2DataFileExists();
LOGGER.log(Level.FINE, "Need to create DB Structure: {0}", shouldCreateSchema);
}
} catch (IOException ioex) {
@@ -217,51 +221,17 @@ public final class ConnectionFactory {
return conn;
}
/**
* Returns the configured connection string. If using the embedded H2 database this function will also ensure the
* data directory exists and if not create it.
*
* @return the connection string
* @throws IOException thrown the data directory cannot be created
*/
private static String getConnectionString() throws IOException {
final String connStr = Settings.getString(Settings.KEYS.DB_CONNECTION_STRING, "jdbc:h2:file:%s;AUTO_SERVER=TRUE");
if (connStr.contains("%s")) {
final String directory = getDataDirectory().getCanonicalPath();
final File dataFile = new File(directory, "cve." + DB_SCHEMA_VERSION);
LOGGER.log(Level.FINE, String.format("File path for H2 file: '%s'", dataFile.toString()));
return String.format(connStr, dataFile.getAbsolutePath());
}
return connStr;
}
/**
* Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory
* for the embedded H2 database. This is public solely for some unit tests; otherwise this should be private.
*
* @return the data directory to store data files
* @throws IOException is thrown if an IOException occurs of course...
*/
public static File getDataDirectory() throws IOException {
final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IOException("Unable to create NVD CVE Data directory");
}
}
return path;
}
/**
* Determines if the H2 database file exists. If it does not exist then the data structure will need to be created.
*
* @return true if the H2 database file does not exist; otherwise false
* @throws IOException thrown if the data directory does not exist and cannot be created
*/
private static boolean dbSchemaExists() throws IOException {
final File dir = getDataDirectory();
final String name = String.format("cve.%s.h2.db", DB_SCHEMA_VERSION);
final File file = new File(dir, name);
private static boolean h2DataFileExists() throws IOException {
final File dir = Settings.getDataDirectory();
final String name = Settings.getString(Settings.KEYS.DB_FILE_NAME);
final String fileName = String.format(name, DB_SCHEMA_VERSION);
final File file = new File(dir, fileName);
return file.exists();
}

View File

@@ -46,6 +46,7 @@ import org.owasp.dependencycheck.utils.Pair;
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class CveDB {
/**
* The logger.
*/
@@ -247,6 +248,7 @@ public class CveDB {
/**
* SQL Statement to retrieve a property from the database.
*/
@SuppressWarnings("unused")
private static final String SELECT_PROPERTY = "SELECT id, value FROM properties WHERE id = ?";
/**
* SQL Statement to insert a new property.
@@ -259,6 +261,7 @@ public class CveDB {
/**
* SQL Statement to delete a property.
*/
@SuppressWarnings("unused")
private static final String DELETE_PROPERTY = "DELETE FROM properties WHERE id = ?";
//</editor-fold>
@@ -303,14 +306,14 @@ public class CveDB {
* @throws DatabaseException thrown when there is an error retrieving the data from the DB
*/
public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
final HashSet data = new HashSet<Pair<String, String>>();
final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
ResultSet rs = null;
PreparedStatement ps = null;
try {
ps = getConnection().prepareStatement(SELECT_VENDOR_PRODUCT_LIST);
rs = ps.executeQuery();
while (rs.next()) {
data.add(new Pair(rs.getString(1), rs.getString(2)));
data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
}
} catch (SQLException ex) {
final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
@@ -728,13 +731,15 @@ public class CveDB {
* @param previous a flag indicating if previous versions of the product are vulnerable
* @return true if the identified version is affected, otherwise false
*/
private boolean isAffected(String vendor, String product, DependencyVersion identifiedVersion, String cpeId, String previous) {
protected boolean isAffected(String vendor, String product, DependencyVersion identifiedVersion, String cpeId, String previous) {
boolean affected = false;
final boolean isStruts = "apache".equals(vendor) && "struts".equals(product);
final DependencyVersion v = parseDependencyVersion(cpeId);
final boolean prevAffected = previous != null && !previous.isEmpty();
if (identifiedVersion == null || "-".equals(identifiedVersion.toString())) {
if (v == null || "-".equals(v.toString())) {
if (v == null || "-".equals(v.toString())) { //all versions
affected = true;
} else if (identifiedVersion == null || "-".equals(identifiedVersion.toString())) {
if (prevAffected) {
affected = true;
}
} else if (identifiedVersion.equals(v) || (prevAffected && identifiedVersion.compareTo(v) < 0)) {

View File

@@ -142,8 +142,8 @@ public class DatabaseProperties {
*
* @return a map of the database meta data
*/
public Map getMetaData() {
final TreeMap map = new TreeMap();
public Map<String, String> getMetaData() {
final TreeMap<String, String> map = new TreeMap<String, String>();
for (Entry<Object, Object> entry : properties.entrySet()) {
final String key = (String) entry.getKey();
if (!"version".equals(key)) {
@@ -156,10 +156,10 @@ public class DatabaseProperties {
map.put(key, formatted);
} catch (Throwable ex) { //deliberately being broad in this catch clause
LOGGER.log(Level.FINE, "Unable to parse timestamp from DB", ex);
map.put(key, entry.getValue());
map.put(key, (String) entry.getValue());
}
} else {
map.put(key, entry.getValue());
map.put(key, (String) entry.getValue());
}
}
}

View File

@@ -22,6 +22,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.owasp.dependencycheck.data.update.exception.UpdateException;
import org.owasp.dependencycheck.utils.DownloadFailedException;
import org.owasp.dependencycheck.utils.Settings;
/**
* Class responsible for updating the NVD CVE and CPE data stores.
@@ -54,7 +55,11 @@ public class NvdCveUpdater implements CachedWebDataSource {
LOGGER.log(Level.FINE, null, ex);
} catch (DownloadFailedException ex) {
LOGGER.log(Level.WARNING,
"Unable to download the NVD CVE data, unable to update the data to use the most current data.");
"Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
LOGGER.log(Level.INFO,
"If you are behind a proxy you may need to configure dependency-check to use the proxy.");
}
LOGGER.log(Level.FINE, null, ex);
}
}

View File

@@ -34,7 +34,7 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.MODIFIED;
import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
import org.owasp.dependencycheck.data.update.exception.UpdateException;
import org.owasp.dependencycheck.data.update.task.CallableDownloadTask;
import org.owasp.dependencycheck.data.update.task.DownloadTask;
import org.owasp.dependencycheck.data.update.task.ProcessTask;
import org.owasp.dependencycheck.utils.DownloadFailedException;
import org.owasp.dependencycheck.utils.InvalidSettingException;
@@ -122,7 +122,7 @@ public class StandardUpdate {
final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
for (NvdCveInfo cve : updateable) {
if (cve.getNeedsUpdate()) {
final CallableDownloadTask call = new CallableDownloadTask(cve, processExecutor, cveDB, Settings.getInstance());
final DownloadTask call = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance());
downloadFutures.add(downloadExecutors.submit(call));
}
}
@@ -178,7 +178,9 @@ public class StandardUpdate {
if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
properties.save(updateable.get(MODIFIED));
LOGGER.log(Level.INFO, "Begin database maintenance.");
cveDB.cleanupDatabase();
LOGGER.log(Level.INFO, "End database maintenance.");
}
} finally {
closeDataStores();

View File

@@ -18,6 +18,9 @@
package org.owasp.dependencycheck.data.update.task;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Callable;
@@ -25,6 +28,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.update.NvdCveInfo;
import org.owasp.dependencycheck.data.update.exception.UpdateException;
@@ -37,12 +42,12 @@ import org.owasp.dependencycheck.utils.Settings;
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
public class DownloadTask implements Callable<Future<ProcessTask>> {
/**
* The Logger.
*/
private static final Logger LOGGER = Logger.getLogger(CallableDownloadTask.class.getName());
private static final Logger LOGGER = Logger.getLogger(DownloadTask.class.getName());
/**
* Simple constructor for the callable download task.
@@ -54,7 +59,7 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
* the dependencies have a correct reference to the global settings.
* @throws UpdateException thrown if temporary files could not be created
*/
public CallableDownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
this.nvdCveInfo = nvdCveInfo;
this.processorService = processor;
this.cveDB = cveDB;
@@ -188,13 +193,25 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
} catch (DownloadFailedException ex) {
msg = String.format("Download Failed for NVD CVE - %s%nSome CVEs may not be reported.", nvdCveInfo.getId());
LOGGER.log(Level.WARNING, msg);
if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
LOGGER.log(Level.INFO,
"If you are behind a proxy you may need to configure dependency-check to use the proxy.");
}
LOGGER.log(Level.FINE, null, ex);
return null;
}
if (url1.toExternalForm().endsWith(".xml.gz")) {
extractGzip(first);
}
if (url2.toExternalForm().endsWith(".xml.gz")) {
extractGzip(second);
}
msg = String.format("Download Complete for NVD CVE - %s", nvdCveInfo.getId());
LOGGER.log(Level.INFO, msg);
if (this.processorService == null) {
return null;
}
final ProcessTask task = new ProcessTask(cveDB, this, settings);
return this.processorService.submit(task);
@@ -203,7 +220,7 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
LOGGER.log(Level.WARNING, msg);
LOGGER.log(Level.FINE, "Download Task Failed", ex);
} finally {
Settings.cleanup();
Settings.cleanup(false);
}
return null;
}
@@ -233,4 +250,48 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
}
}
}
/**
* Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file
* specified.
*
* @param file the archive file
* @throws FileNotFoundException thrown if the file does not exist
* @throws IOException thrown if there is an error extracting the file.
*/
private void extractGzip(File file) throws FileNotFoundException, IOException {
final String originalPath = file.getPath();
File gzip = new File(originalPath + ".gz");
if (gzip.isFile()) {
gzip.delete();
}
if (!file.renameTo(gzip)) {
throw new IOException("Unable to rename '" + file.getPath() + "'");
}
final File newfile = new File(originalPath);
final byte[] buffer = new byte[4096];
GZIPInputStream cin = null;
FileOutputStream out = null;
try {
cin = new GZIPInputStream(new FileInputStream(gzip));
out = new FileOutputStream(newfile);
int len;
while ((len = cin.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} finally {
if (cin != null) {
cin.close();
}
if (out != null) {
out.close();
}
if (gzip.isFile()) {
FileUtils.deleteQuietly(gzip);
}
}
}
}

View File

@@ -79,7 +79,7 @@ public class ProcessTask implements Callable<ProcessTask> {
/**
* A reference to the callable download task.
*/
private final CallableDownloadTask filePair;
private final DownloadTask filePair;
/**
* A reference to the properties.
*/
@@ -97,7 +97,7 @@ public class ProcessTask implements Callable<ProcessTask> {
* @param settings a reference to the global settings object; this is necessary so that when the thread is started
* the dependencies have a correct reference to the global settings.
*/
public ProcessTask(final CveDB cveDB, final CallableDownloadTask filePair, Settings settings) {
public ProcessTask(final CveDB cveDB, final DownloadTask filePair, Settings settings) {
this.cveDB = cveDB;
this.filePair = filePair;
this.properties = cveDB.getDatabaseProperties();
@@ -119,7 +119,7 @@ public class ProcessTask implements Callable<ProcessTask> {
} catch (UpdateException ex) {
this.exception = ex;
} finally {
Settings.cleanup();
Settings.cleanup(false);
}
return this;
}

View File

@@ -19,12 +19,14 @@ package org.owasp.dependencycheck.dependency;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.utils.Checksum;
import org.owasp.dependencycheck.utils.FileUtils;
@@ -35,7 +37,7 @@ import org.owasp.dependencycheck.utils.FileUtils;
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class Dependency implements Comparable<Dependency> {
public class Dependency implements Serializable, Comparable<Dependency> {
/**
* The logger.
@@ -177,6 +179,33 @@ public class Dependency implements Comparable<Dependency> {
this.filePath = filePath;
}
/**
* The file name to display in reports.
*/
private String displayName = null;
/**
* Sets the file name to display in reports.
*
* @param displayName the name to display
*/
public void setDisplayFileName(String displayName) {
this.displayName = displayName;
}
/**
* Returns the file name to display in reports; if no display file name has been set it will default to the actual
* file name.
*
* @return the file name to display
*/
public String getDisplayFileName() {
if (displayName == null) {
return this.fileName;
}
return this.displayName;
}
/**
* <p>
* Gets the file path of the dependency.</p>
@@ -288,6 +317,41 @@ public class Dependency implements Comparable<Dependency> {
this.identifiers.add(i);
}
/**
* Adds the maven artifact as evidence.
*
* @param source The source of the evidence
* @param mavenArtifact The maven artifact
* @param confidence The confidence level of this evidence
*/
public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
}
if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
}
if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
}
if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
boolean found = false;
for (Identifier i : this.getIdentifiers()) {
if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
found = true;
i.setConfidence(Confidence.HIGHEST);
i.setUrl(mavenArtifact.getArtifactUrl());
LOGGER.fine(String.format("Already found identifier %s. Confidence set to highest", i.getValue()));
break;
}
}
if (!found) {
LOGGER.fine(String.format("Adding new maven identifier %s", mavenArtifact.toString()));
this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
}
}
}
/**
* Adds an entry to the list of detected Identifiers for the dependency file.
*
@@ -296,6 +360,7 @@ public class Dependency implements Comparable<Dependency> {
public void addIdentifier(Identifier identifier) {
this.identifiers.add(identifier);
}
/**
* A set of identifiers that have been suppressed.
*/
@@ -369,6 +434,15 @@ public class Dependency implements Comparable<Dependency> {
return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
}
/**
* Returns the evidence used to identify this dependency.
*
* @return an EvidenceCollection.
*/
public Set<Evidence> getEvidenceForDisplay() {
return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
}
/**
* Returns the evidence used to identify this dependency.
*
@@ -404,6 +478,7 @@ public class Dependency implements Comparable<Dependency> {
public EvidenceCollection getVersionEvidence() {
return this.versionEvidence;
}
/**
* The description of the JAR file.
*/
@@ -426,6 +501,7 @@ public class Dependency implements Comparable<Dependency> {
public void setDescription(String description) {
this.description = description;
}
/**
* The license that this dependency uses.
*/
@@ -448,6 +524,7 @@ public class Dependency implements Comparable<Dependency> {
public void setLicense(String license) {
this.license = license;
}
/**
* A list of vulnerabilities for this dependency.
*/
@@ -503,6 +580,7 @@ public class Dependency implements Comparable<Dependency> {
public void addVulnerability(Vulnerability vulnerability) {
this.vulnerabilities.add(vulnerability);
}
/**
* A collection of related dependencies.
*/
@@ -542,7 +620,7 @@ public class Dependency implements Comparable<Dependency> {
* @return an integer representing the natural ordering
*/
public int compareTo(Dependency o) {
return this.getFileName().compareToIgnoreCase(o.getFileName());
return this.getFilePath().compareToIgnoreCase(o.getFilePath());
}
/**

View File

@@ -17,12 +17,14 @@
*/
package org.owasp.dependencycheck.dependency;
import java.io.Serializable;
/**
* Evidence is a piece of information about a Dependency.
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class Evidence implements Comparable<Evidence> {
public class Evidence implements Serializable, Comparable<Evidence> {
/**
* Creates a new Evidence object.
@@ -220,22 +222,95 @@ public class Evidence implements Comparable<Evidence> {
* @return an integer indicating the ordering of the two objects
*/
public int compareTo(Evidence o) {
if (source.equals(o.source)) {
if (name.equals(o.name)) {
if (value.equals(o.value)) {
if (confidence.equals(o.confidence)) {
if (o == null) {
return 1;
}
if (equalsWithNullCheck(source, o.source)) {
if (equalsWithNullCheck(name, o.name)) {
if (equalsWithNullCheck(value, o.value)) {
if (equalsWithNullCheck(confidence, o.confidence)) {
return 0; //they are equal
} else {
return confidence.compareTo(o.confidence);
return compareToWithNullCheck(confidence, o.confidence);
}
} else {
return value.compareToIgnoreCase(o.value);
return compareToIgnoreCaseWithNullCheck(value, o.value);
}
} else {
return name.compareToIgnoreCase(o.name);
return compareToIgnoreCaseWithNullCheck(name, o.name);
}
} else {
return source.compareToIgnoreCase(o.source);
return compareToIgnoreCaseWithNullCheck(source, o.source);
}
}
/**
* Equality check with an exhaustive, possibly duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private boolean equalsWithNullCheck(String me, String other) {
if (me == null && other == null) {
return true;
} else if (me == null || other == null) {
return false;
}
return me.equals(other);
}
/**
* Equality check with an exhaustive, possibly duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private boolean equalsWithNullCheck(Confidence me, Confidence other) {
if (me == null && other == null) {
return true;
} else if (me == null || other == null) {
return false;
}
return me.equals(other);
}
/**
* Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an
* exhaustive, possibly duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private int compareToIgnoreCaseWithNullCheck(String me, String other) {
if (me == null && other == null) {
return 0;
} else if (me == null) {
return -1; //the other string is greater then me
} else if (other == null) {
return 1; //me is greater then the other string
}
return me.compareToIgnoreCase(other);
}
/**
* Wrapper around {@link java.lang.Enum#compareTo(java.lang.Enum) Enum.compareTo} with an exhaustive, possibly
* duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private int compareToWithNullCheck(Confidence me, Confidence other) {
if (me == null && other == null) {
return 0;
} else if (me == null) {
return -1; //the other string is greater then me
} else if (other == null) {
return 1; //me is greater then the other string
}
return me.compareTo(other);
}
}

View File

@@ -17,6 +17,7 @@
*/
package org.owasp.dependencycheck.dependency;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Iterator;
@@ -36,7 +37,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils;
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class EvidenceCollection implements Iterable<Evidence> {
public class EvidenceCollection implements Serializable, Iterable<Evidence> {
/**
* The logger.
@@ -311,6 +312,26 @@ public class EvidenceCollection implements Iterable<Evidence> {
return ret;
}
/**
* Merges multiple EvidenceCollections together; flattening all of the evidence items by removing the confidence.
*
* @param ec One or more EvidenceCollections
* @return new set of evidence resulting from merging the evidence in the collections
*/
public static Set<Evidence> mergeForDisplay(EvidenceCollection... ec) {
final Set<Evidence> ret = new TreeSet<Evidence>();
for (EvidenceCollection col : ec) {
for (Evidence e : col) {
if (e.isUsed()) {
final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null);
newEvidence.setUsed(true);
ret.add(newEvidence);
}
}
}
return ret;
}
/**
* Returns a string of evidence 'values'.
*

View File

@@ -17,11 +17,13 @@
*/
package org.owasp.dependencycheck.dependency;
import java.io.Serializable;
/**
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class Identifier implements Comparable<Identifier> {
public class Identifier implements Serializable, Comparable<Identifier> {
/**
* Constructs a new Identifier with the specified data.

View File

@@ -77,19 +77,19 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp
if (cpeName != null && cpeName.length() > 7) {
final String[] data = cpeName.substring(7).split(":");
if (data.length >= 1) {
this.setVendor(URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8"));
this.setVendor(urlDecode(data[0]));
}
if (data.length >= 2) {
this.setProduct(URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8"));
this.setProduct(urlDecode(data[1]));
}
if (data.length >= 3) {
version = URLDecoder.decode(data[2].replace("+", "%2B"), "UTF-8");
version = urlDecode(data[2]);
}
if (data.length >= 4) {
revision = URLDecoder.decode(data[3].replace("+", "%2B"), "UTF-8");
revision = urlDecode(data[3]);
}
if (data.length >= 5) {
edition = URLDecoder.decode(data[4].replace("+", "%2B"), "UTF-8");
edition = urlDecode(data[4]);
}
}
}
@@ -341,4 +341,25 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp
public void setEdition(String edition) {
this.edition = edition;
}
/**
* Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default.
*
* @param string the string to URL Decode
* @return the URL Decoded string
*/
private String urlDecode(String string) {
final String text = string.replace("+", "%2B");
String result;
try {
result = URLDecoder.decode(text, "UTF-8");
} catch (UnsupportedEncodingException ex) {
try {
result = URLDecoder.decode(text, "ASCII");
} catch (UnsupportedEncodingException ex1) {
result = URLDecoder.decode(text);
}
}
return result;
}
}

View File

@@ -48,7 +48,7 @@ public class ScanAgentException extends IOException {
}
/**
* Creates a new NoDataException.
* Creates a new ScanAgentException.
*
* @param ex the cause of the exception.
*/

View File

@@ -167,15 +167,28 @@ public class ReportGenerator {
*/
public void generateReports(String outputDir, String outputFormat) throws IOException, Exception {
final String format = outputFormat.toUpperCase();
final String pathToCheck = outputDir.toLowerCase();
if (format.matches("^(XML|HTML|VULN|ALL)$")) {
if ("XML".equalsIgnoreCase(format)) {
generateReports(outputDir, Format.XML);
if (pathToCheck.endsWith(".xml")) {
generateReport("XmlReport", outputDir);
} else {
generateReports(outputDir, Format.XML);
}
}
if ("HTML".equalsIgnoreCase(format)) {
generateReports(outputDir, Format.HTML);
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
generateReport("HtmlReport", outputDir);
} else {
generateReports(outputDir, Format.HTML);
}
}
if ("VULN".equalsIgnoreCase(format)) {
generateReports(outputDir, Format.VULN);
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
generateReport("VulnReport", outputDir);
} else {
generateReports(outputDir, Format.VULN);
}
}
if ("ALL".equalsIgnoreCase(format)) {
generateReports(outputDir, Format.ALL);

View File

@@ -54,6 +54,10 @@ public class SuppressionHandler extends DefaultHandler {
* The CWE element name.
*/
public static final String CWE = "cwe";
/**
* The GAV element name.
*/
public static final String GAV = "gav";
/**
* The cvssBelow element name.
*/
@@ -95,13 +99,16 @@ public class SuppressionHandler extends DefaultHandler {
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentAttributes = null;
currentAttributes = attributes;
currentText = new StringBuffer();
if (SUPPRESS.equals(qName)) {
rule = new SuppressionRule();
} else if (FILE_PATH.equals(qName)) {
currentAttributes = attributes;
final String base = currentAttributes.getValue("base");
if (base != null) {
rule.setBase(Boolean.parseBoolean(base));
} else {
rule.setBase(false);
}
}
}
@@ -123,6 +130,9 @@ public class SuppressionHandler extends DefaultHandler {
rule.setFilePath(pt);
} else if (SHA1.equals(qName)) {
rule.setSha1(currentText.toString());
} else if (GAV.equals(qName)) {
final PropertyType pt = processPropertyType();
rule.setGav(pt);
} else if (CPE.equals(qName)) {
final PropertyType pt = processPropertyType();
rule.addCpe(pt);

View File

@@ -26,11 +26,6 @@ import java.io.IOException;
*/
public class SuppressionParseException extends IOException {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new SuppressionParseException.
*/
@@ -50,7 +45,7 @@ public class SuppressionParseException extends IOException {
/**
* Creates a new SuppressionParseException.
*
* @param ex the cause of the download failure.
* @param ex the cause of the parse exception
*/
public SuppressionParseException(Throwable ex) {
super(ex);
@@ -60,7 +55,7 @@ public class SuppressionParseException extends IOException {
* Creates a new SuppressionParseException.
*
* @param msg a message for the exception.
* @param ex the cause of the download failure.
* @param ex the cause of the parse exception
*/
public SuppressionParseException(String msg, Throwable ex) {
super(msg, ex);

View File

@@ -66,10 +66,35 @@ public class SuppressionParser {
* @throws SuppressionParseException thrown if the xml file cannot be parsed
*/
public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
return parseSuppressionRules(fis);
} catch (IOException ex) {
LOGGER.log(Level.FINE, null, ex);
throw new SuppressionParseException(ex);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ex) {
LOGGER.log(Level.FINE, "Unable to close stream", ex);
}
}
}
}
/**
* Parses the given xml stream and returns a list of the suppression rules contained.
*
* @param inputStream an InputStream containing suppression rues
* @return a list of suppression rules
* @throws SuppressionParseException if the xml cannot be parsed
*/
public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException {
try {
final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd");
final SuppressionHandler handler = new SuppressionHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
@@ -80,7 +105,6 @@ public class SuppressionParser {
xmlReader.setErrorHandler(new SuppressionErrorHandler());
xmlReader.setContentHandler(handler);
final InputStream inputStream = new FileInputStream(file);
final Reader reader = new InputStreamReader(inputStream, "UTF-8");
final InputSource in = new InputSource(reader);
//in.setEncoding("UTF-8");

View File

@@ -234,6 +234,61 @@ public class SuppressionRule {
public boolean hasCve() {
return cve.size() > 0;
}
/**
* A Maven GAV to suppression.
*/
private PropertyType gav = null;
/**
* Get the value of Maven GAV.
*
* @return the value of gav
*/
public PropertyType getGav() {
return gav;
}
/**
* Set the value of Maven GAV.
*
* @param gav new value of Maven gav
*/
public void setGav(PropertyType gav) {
this.gav = gav;
}
/**
* Returns whether or not this suppression rule as GAV entries.
*
* @return whether or not this suppression rule as GAV entries
*/
public boolean hasGav() {
return gav != null;
}
/**
* A flag indicating whether or not the suppression rule is a core/base rule that should not be included in the
* resulting report in the "suppressed" section.
*/
private boolean base;
/**
* Get the value of base.
*
* @return the value of base
*/
public boolean isBase() {
return base;
}
/**
* Set the value of base.
*
* @param base new value of base
*/
public void setBase(boolean base) {
this.base = base;
}
/**
* Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any
@@ -248,13 +303,30 @@ public class SuppressionRule {
if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
return;
}
if (gav != null) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
boolean gavFound = false;
while (itr.hasNext()) {
final Identifier i = itr.next();
if (identifierMatches("maven", this.gav, i)) {
gavFound = true;
break;
}
}
if (!gavFound) {
return;
}
}
if (this.hasCpe()) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) {
final Identifier i = itr.next();
for (PropertyType c : this.cpe) {
if (cpeMatches(c, i)) {
dependency.addSuppressedIdentifier(i);
if (identifierMatches("cpe", c, i)) {
if (!isBase()) {
dependency.addSuppressedIdentifier(i);
}
itr.remove();
break;
}
@@ -293,7 +365,9 @@ public class SuppressionRule {
}
}
if (remove) {
dependency.addSuppressedVulnerability(v);
if (!isBase()) {
dependency.addSuppressedVulnerability(v);
}
itr.remove();
}
}
@@ -309,7 +383,7 @@ public class SuppressionRule {
boolean cpeHasNoVersion(PropertyType c) {
if (c.isRegex()) {
return false;
} // cpe:/a:jboss:jboss:1.0.0:
}
if (countCharacter(c.getValue(), ':') == 3) {
return true;
}
@@ -336,26 +410,75 @@ public class SuppressionRule {
/**
* Determines if the cpeEntry specified as a PropertyType matches the given Identifier.
*
* @param cpeEntry a suppression rule entry
* @param identifierType the type of identifier ("cpe", "maven", etc.)
* @param suppressionEntry a suppression rule entry
* @param identifier a CPE identifier to check
* @return true if the entry matches; otherwise false
*/
boolean cpeMatches(PropertyType cpeEntry, Identifier identifier) {
if (cpeEntry.matches(identifier.getValue())) {
return true;
} else if (cpeHasNoVersion(cpeEntry)) {
if (cpeEntry.isCaseSensitive()) {
if (identifier.getValue().startsWith(cpeEntry.getValue())) {
return true;
}
} else {
final String id = identifier.getValue().toLowerCase();
final String check = cpeEntry.getValue().toLowerCase();
if (id.startsWith(check)) {
return true;
boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
if (identifierType.equals(identifier.getType())) {
if (suppressionEntry.matches(identifier.getValue())) {
return true;
} else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
if (suppressionEntry.isCaseSensitive()) {
return identifier.getValue().startsWith(suppressionEntry.getValue());
} else {
final String id = identifier.getValue().toLowerCase();
final String check = suppressionEntry.getValue().toLowerCase();
return id.startsWith(check);
}
}
}
return false;
}
/**
* Standard toString implementation.
*
* @return a string representation of this object
*/
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("SuppressionRule{");
if (filePath != null) {
sb.append("filePath=").append(filePath).append(",");
}
if (sha1 != null) {
sb.append("sha1=").append(sha1).append(",");
}
if (gav != null) {
sb.append("gav=").append(gav).append(",");
}
if (cpe != null && cpe.size() > 0) {
sb.append("cpe={");
for (PropertyType pt : cpe) {
sb.append(pt).append(",");
}
sb.append("}");
}
if (cwe != null && cwe.size() > 0) {
sb.append("cwe={");
for (String s : cwe) {
sb.append(s).append(",");
}
sb.append("}");
}
if (cve != null && cve.size() > 0) {
sb.append("cve={");
for (String s : cve) {
sb.append(s).append(",");
}
sb.append("}");
}
if (cvssBelow != null && cvssBelow.size() > 0) {
sb.append("cvssBelow={");
for (Float s : cvssBelow) {
sb.append(s).append(",");
}
sb.append("}");
}
sb.append("}");
return sb.toString();
}
}

View File

@@ -54,7 +54,9 @@ public final class DBUtils {
int id = 0;
try {
rs = statement.getGeneratedKeys();
rs.next();
if (!rs.next()) {
throw new DatabaseException("Unable to get primary key for inserted row");
}
id = rs.getInt(1);
} catch (SQLException ex) {
throw new DatabaseException("Unable to get primary key for inserted row");

View File

@@ -65,7 +65,7 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
public final void parseVersion(String version) {
versionParts = new ArrayList<String>();
if (version != null) {
final Pattern rx = Pattern.compile("(\\d+|[a-z]+\\d+|(release|beta|alpha)$)");
final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
final Matcher matcher = rx.matcher(version.toLowerCase());
while (matcher.find()) {
versionParts.add(matcher.group());
@@ -189,17 +189,23 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
if (version == null) {
return false;
}
boolean ret = true;
int max = (this.versionParts.size() < version.versionParts.size())
? this.versionParts.size() : version.versionParts.size();
if (max > 3) {
max = 3;
if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
return false;
}
final int max = (this.versionParts.size() < version.versionParts.size())
? this.versionParts.size() : version.versionParts.size();
boolean ret = true;
for (int i = 0; i < max; i++) {
if (this.versionParts.get(i) == null || !this.versionParts.get(i).equals(version.versionParts.get(i))) {
final String thisVersion = this.versionParts.get(i);
final String otherVersion = version.getVersionParts().get(i);
if (i >= 3) {
if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
ret = false;
break;
}
} else if (!thisVersion.equals(otherVersion)) {
ret = false;
break;
}

View File

@@ -32,7 +32,7 @@ public final class DependencyVersionUtil {
/**
* Regular expression to extract version numbers from file names.
*/
private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
/**
* Regular expression to extract a single version number without periods. This is a last ditch effort just to check
* in case we are missing a version number using the previous regex.

View File

@@ -0,0 +1,147 @@
/*
* 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) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.owasp.dependencycheck.Engine;
import static org.owasp.dependencycheck.utils.FileUtils.getFileExtension;
/**
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public final class ExtractionUtil {
/**
* The logger.
*/
private static final Logger LOGGER = Logger.getLogger(ExtractionUtil.class.getName());
/**
* The buffer size to use when extracting files from the archive.
*/
private static final int BUFFER_SIZE = 4096;
/**
* Private constructor for a utility class.
*/
private ExtractionUtil() {
}
/**
* Extracts the contents of an archive into the specified directory.
*
* @param archive an archive file such as a WAR or EAR
* @param extractTo a directory to extract the contents to
* @throws ExtractionException thrown if an exception occurs while extracting the files
*/
public static void extractFiles(File archive, File extractTo) throws ExtractionException {
extractFiles(archive, extractTo, null);
}
/**
* Extracts the contents of an archive into the specified directory. The files are only extracted if they are
* supported by the analyzers loaded into the specified engine. If the engine is specified as null then all files
* are extracted.
*
* @param archive an archive file such as a WAR or EAR
* @param extractTo a directory to extract the contents to
* @param engine the scanning engine
* @throws ExtractionException thrown if there is an error extracting the files
*/
public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException {
if (archive == null || extractTo == null) {
return;
}
FileInputStream fis = null;
ZipInputStream zis = null;
try {
fis = new FileInputStream(archive);
} catch (FileNotFoundException ex) {
LOGGER.log(Level.FINE, null, ex);
throw new ExtractionException("Archive file was not found.", ex);
}
zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
try {
while ((entry = zis.getNextEntry()) != null) {
if (entry.isDirectory()) {
final File d = new File(extractTo, entry.getName());
if (!d.exists() && !d.mkdirs()) {
final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
throw new ExtractionException(msg);
}
} else {
final File file = new File(extractTo, entry.getName());
final String ext = getFileExtension(file.getName());
if (engine == null || engine.supportsExtension(ext)) {
BufferedOutputStream bos = null;
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
int count;
final byte data[] = new byte[BUFFER_SIZE];
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
bos.write(data, 0, count);
}
bos.flush();
} catch (FileNotFoundException ex) {
LOGGER.log(Level.FINE, null, ex);
final String msg = String.format("Unable to find file '%s'.", file.getName());
throw new ExtractionException(msg, ex);
} catch (IOException ex) {
LOGGER.log(Level.FINE, null, ex);
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
throw new ExtractionException(msg, ex);
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException ex) {
LOGGER.log(Level.FINEST, null, ex);
}
}
}
}
}
}
} catch (IOException ex) {
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
LOGGER.log(Level.FINE, msg, ex);
throw new ExtractionException(msg, ex);
} finally {
try {
zis.close();
} catch (IOException ex) {
LOGGER.log(Level.FINEST, null, ex);
}
}
}
}

BIN
dependency-check-core/src/main/resources/GrokAssembly.exe Executable file → Normal file

Binary file not shown.

View File

@@ -8,6 +8,7 @@ org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer
org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
org.owasp.dependencycheck.analyzer.CentralAnalyzer
org.owasp.dependencycheck.analyzer.NexusAnalyzer
org.owasp.dependencycheck.analyzer.NuspecAnalyzer
org.owasp.dependencycheck.analyzer.AssemblyAnalyzer

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
<suppress base="true">
<notes><![CDATA[
This suppresses false positives identified on spring security.
]]></notes>
<gav regex="true">org\.springframework\.security:spring.*</gav>
<cpe>cpe:/a:mod_security:mod_security</cpe>
<cpe>cpe:/a:springsource:spring_framework</cpe>
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
This suppresses false positives identified on spring security.
]]></notes>
<filePath regex="true">.*spring-security-[^\\/]*\.jar$</filePath>
<cpe>cpe:/a:mod_security:mod_security</cpe>
<cpe>cpe:/a:springsource:spring_framework</cpe>
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
This suppreses additional false positives for the xstream library that occur because spring has a copy of this library.
com.springsource.com.thoughtworks.xstream-1.3.1.jar
]]></notes>
<gav regex="true">com\.thoughtworks\.xstream:xstream:.*</gav>
<cpe>cpe:/a:springsource:spring_framework</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
Suppresses false positives on velocity tools.
]]></notes>
<gav regex="true">org\.apache\.velocity:velocity-tools:.*</gav>
<cpe>cpe:/a:apache:struts</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
Sandbox is a php blog platform and should not be flagged as a CPE for java or .net dependencies.
]]></notes>
<filePath regex="true">.*\.(jar|dll|exe|ear|war|pom)</filePath>
<cpe>cpe:/a:sandbox:sandbox</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
Suppresses false positives on Jersey core client.
]]></notes>
<gav regex="true">(com\.sun\.jersey|org\.glassfish\.jersey\.core):jersey-(client|common):.*</gav>
<cpe>cpe:/a:oracle:glassfish</cpe>
<cpe>cpe:/a:oracle:oracle_client</cpe>
</suppress>
<suppress>
<notes><![CDATA[
Suppresses false positives on the grizzly-framework
]]></notes>
<gav regex="true">org\.glassfish\.grizzly:grizzly-framework:.*</gav>
<cpe>cpe:/a:oracle:glassfish</cpe>
</suppress>
<suppress>
<notes><![CDATA[
Suppresses false positives on the grizzly-framework
]]></notes>
<gav regex="true">org\.forgerock\.opendj:opendj-ldap-sdk:.*</gav>
<cpe>cpe:/a:ldap_project:ldap</cpe>
</suppress>
</suppressions>

View File

@@ -0,0 +1,10 @@
analyzer.AssemblyAnalyzer.notdeployed=GrokAssembly didn't get deployed
analyzer.AssemblyAnalyzer.grokassembly.stderr=Error from GrokAssembly: {0}
analyzer.AssemblyAnalyzer.notassembly={0} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check
analyzer.AssemblyAnalyzer.grokassembly.rc=Return code {0} from GrokAssembly
analyzer.AssemblyAnalyzer.grokassembly.deployed=Extracted GrokAssembly.exe to {0}
analyzer.AssemblyAnalyzer.grokassembly.notdeployed=Could not extract GrokAssembly.exe: {0}
analyzer.AssemblyAnalyzer.grokassembly.initialization.failed=An error occurred with the .NET AssemblyAnalyzer; \
this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.
analyzer.AssemblyAnalyzer.grokassembly.initialization.message=Could not execute GrokAssembly {0}
analyzer.AssemblyAnalyzer.grokassembly.notdeleted=Can't delete temporary GrokAssembly.exe

View File

@@ -13,8 +13,10 @@ max.download.threads=3
# will not be used. The data.directory will be resolved and if the connection string
# below contains a %s then the data.directory will replace the %s.
data.directory=[JAR]/data
#if the filename has a %s it will be replaced with the current expected version
data.file_name=cve.%s.h2.db
data.version=2.9
data.connection_string=jdbc:h2:file:%s;FILE_LOCK=SERIALIZED;AUTOCOMMIT=ON;
#data.connection_string=jdbc:h2:file:%s;AUTO_SERVER=TRUE;AUTOCOMMIT=ON;
#data.connection_string=jdbc:mysql://localhost:3306/dependencycheck
# user name and password for the database connection. The inherent case is to use H2.
@@ -38,11 +40,16 @@ data.driver_path=
cve.url.modified.validfordays=7
# the path to the modified nvd cve xml file.
cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cve.url-1.2.modified=https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
#cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
cve.url-2.0.modified=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
#cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cve.startyear=2002
cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
cve.url-1.2.base=https://nvd.nist.gov/download/nvdcve-%d.xml.gz
#cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
#cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
# file type analyzer settings:
analyzer.archive.enabled=true
@@ -56,3 +63,7 @@ analyzer.nexus.url=https://repository.sonatype.org/service/local/
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
# are configured
analyzer.nexus.proxy=true
# the URL for searching search.maven.org for SHA-1 and whether it's enabled
analyzer.central.enabled=true
analyzer.central.url=http://search.maven.org/solrsearch/select

View File

@@ -41,6 +41,7 @@
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="filePath" type="dc:regexStringType"/>
<xs:element name="sha1" type="dc:sha1Type"/>
<xs:element name="gav" type="dc:regexStringType"/>
</xs:choice>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="cpe" type="dc:regexStringType"/>
@@ -49,6 +50,7 @@
<xs:element name="cvssBelow" type="dc:cvssScoreType"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="base" use="optional" type="xs:boolean" default="false"/>
</xs:complexType>
</xs:element>
</xs:sequence>

View File

@@ -33,8 +33,8 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</script>
<script type="text/javascript">
$(document).ready(function() {
$(".expandable").click(function (e) {
e = e || window.event;
$(".expandable").click(function (event) {
e = event || window.event;
var h = e.target || e.srcElement;
var content = "#content" + h.id.substr(6);
var header = "#" + h.id;
@@ -56,6 +56,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
$(header).addClass("expandablesubsection");
$(header).removeClass("collaspablesubsection");
}
return false;
});
});
@@ -84,13 +85,14 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
$('#modal-text').focus();
$('#modal-text').select();
}
function toggleDisplay(el, clzName) {
function toggleDisplay(el, clzName, all, some) {
$(clzName).toggle();
if (el.innerHTML == 'show all') {
el.innerHTML = 'less';
if (el.innerHTML == all) {
el.innerHTML = some;
} else {
el.innerHTML = 'show all';
el.innerHTML = all;
}
return false;
}
</script>
<style type="text/css">
@@ -427,15 +429,24 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
.indent {
margin-left:20px;
}
td, th {
td{
vertical-align:text-top;
padding:6px;
margin:0px;
}
th {
text-align:left
vertical-align:text-top;
padding:6px;
margin:0px;
border-bottom:1px;
border-color: black;
}
table {
border: 0px;
}
table.lined tr:nth-child(even) {
background-color: #fbfbfb;
background-color: #f3f3f3;
}
.fullwidth {
width:100%;
@@ -448,10 +459,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
margin-bottom:3px;
}
.vulnerable {
color: #f00;
}
.vulnerable li {
color: #000;
color: #000;
}
.notvulnerable {
display:none;
@@ -481,7 +489,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<div id="modal-content">
<div>Press CTR-C to copy XML&nbsp;<a href="http://jeremylong.github.io/DependencyCheck/suppression.html" class="infolink" target="_blank" title="Help with suppressing false positives">[help]</a></div>
<textarea id="modal-text" cols="50" rows="10"></textarea><br/>
<button id="modal-add-header" class="modal-button">Complete XML Doc</button><button id="modal-close" class="modal-button-right">Close</button>
<button id="modal-add-header" title="Add the parent XML nodes to create the complete XML file that can be used to suppress this finding" class="modal-button">Complete XML Doc</button><button id="modal-close" class="modal-button-right">Close</button>
</div>
<div class="wrapper">
<h1>Dependency-Check Report</h1>
@@ -513,7 +521,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#set($vulnSuppressedCount=$vulnSuppressedCount+$dependency.getSuppressedVulnerabilities().size())
#end
#end
Scan Information (<a href="#" onclick="toggleDisplay(this, '.scaninfo'); return false;">show all</a>):<br/>
Scan Information (<a href="#" title="Click to toggle display" onclick="return toggleDisplay(this, '.scaninfo', 'show all', 'show less'); return false;">show all</a>):<br/>
<ul class="indent">
<li><i>dependency-check version</i>: $version</li>
<li><i>Report Generated On</i>: $scanDate</li>
@@ -526,30 +534,101 @@ arising out of or in connection with the use of this tool, the analysis performe
<li class="scaninfo hidden"><i>$enc.html($prop.key)</i>: $enc.html($prop.value)</li>
#end
</ul><br/>
Dependency Display:&nbsp;<a href="#" onclick="toggleDisplay(this,'.notvulnerable'); return false;">show all</a><br/><br/>
<ul class="indent">
Display:&nbsp;<a href="#" title="Click to toggle display" onclick="return toggleDisplay(this, '.notvulnerable', 'Showing Vulnerable Dependencies', 'Showing All Dependencies'); return false;">Showing Vulnerable Dependencies</a><br/><br/>
#set($lnkcnt=0)
#foreach($dependency in $dependencies)
<table class="lined">
<tr style="text-align:left">
<th title="The name of the dependency">Dependency</th>
<th title="The Common Platform Enumeration">CPE</th>
<th title="The Maven GAV Coordinates">GAV</th>
<th title="The highest CVE Severity">Highest Severity</th>
<th title="The number of Common Vulnerability and Exposure (CVE) entries">CVE Count</th>
<th title="The confidence rating dependency-check has for the identified CPE">CPE Confidence</th>
<th title="The count of evidence used to identify the CPE">Evidence Count</th>
</tr>
#foreach($dependency in $dependencies)
#set($lnkcnt=$lnkcnt+1)
<li class="#if($dependency.getVulnerabilities().size()==0)notvulnerable#else vulnerable#end">
<a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.FileName)</a>
#if($dependency.getRelatedDependencies().size()>0)
<ul>
#foreach($related in $dependency.getRelatedDependencies())
<li>$enc.html($related.FileName)</li>
<tr class="#if($dependency.getVulnerabilities().size()==0)notvulnerable#else vulnerable#end">
<td><a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.DisplayFileName)</a></td>
#set($mavenlink="")
#set($cpeIdCount=0)
#set($cpeIdConf="")
<td>
#foreach($id in $dependency.getIdentifiers())
#if ($id.type=="maven")
#if ($mavenlink=="" || !$mavenlink.url)
#set($mavenlink=$id)
#end
#else
#if ($cpeIdCount>=1)
<br/>
#end
#if( $id.url )
<a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a>
#else
$enc.html($id.value)
#end
#if ($cpeIdConf == "")
#set($cpeIdConf=$id.confidence)
#elseif ($cpeIdConf.compareTo($id.confidence)>0)
#set($cpeIdConf=$id.confidence)
#end
#set($cpeIdCount=$cpeIdCount+1)
#end
#end
</ul>
</td>
<td>#if( $mavenlink.url )
##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here...
<a href="$enc.html($mavenlink.url)" target="_blank">$enc.html($mavenlink.value)</a>
#elseif ($mavenlink.value)
$enc.html($mavenlink.value)
#end</td>
#set($cveImpact=-1)
#foreach($vuln in $dependency.getVulnerabilities())
#if ($cveImpact<$vuln.cvssScore)
#set($cveImpact=$vuln.cvssScore)
#end
#end
<td>
#if ($cveImpact<0)
&nbsp;
#elseif ($cveImpact<4.0)
Low
#elseif ($cveImpact>=7.0)
High
#else
Medium
#end
</td>
<td>$dependency.getVulnerabilities().size()</td>
<td>$cpeIdConf</td>
<td>$dependency.getEvidenceForDisplay().size()</td>
</tr>
#end
</li>
#end
</ul>
</table>
## <ul class="indent">
## #set($lnkcnt=0)
## #foreach($dependency in $dependencies)
## #set($lnkcnt=$lnkcnt+1)
## <li class="#if($dependency.getVulnerabilities().size()==0)notvulnerable#else vulnerable#end">
## <a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.DisplayFileName)</a>
## #if($dependency.getRelatedDependencies().size()>0)
## <ul>
## #foreach($related in $dependency.getRelatedDependencies())
## <li>$enc.html($related.DisplayFileName)</li>
## #end
## </ul>
## #end
## </li>
## #end
## </ul>
<h2>Dependencies</h2>
#set($lnkcnt=0)
#set($cnt=0)
#set($vsctr=0) ##counter to create unique groups for vulnerable software
#foreach($dependency in $dependencies)
#set($lnkcnt=$lnkcnt+1)
<h3 class="subsectionheader standardsubsection#if($dependency.getVulnerabilities().size()==0) notvulnerable#end"><a name="l${lnkcnt}_$enc.html($dependency.Sha1sum)"></a>$enc.html($dependency.FileName)</h3>
<h3 class="subsectionheader standardsubsection#if($dependency.getVulnerabilities().size()==0) notvulnerable#end"><a name="l${lnkcnt}_$enc.html($dependency.Sha1sum)"></a>$enc.html($dependency.DisplayFileName)</h3>
<div class="subsectioncontent#if($dependency.getVulnerabilities().size()==0) notvulnerable#end">
#if ($dependency.description)
<p><b>Description:</b>&nbsp;$enc.html($dependency.description)<br/></p>
@@ -571,7 +650,7 @@ arising out of or in connection with the use of this tool, the analysis performe
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<table class="lined fullwidth" border="0">
<tr><th class="left" style="width:10%;">Source</th><th class="left" style="width:20%;">Name</th><th class="left" style="width:70%;">Value</th></tr>
#foreach($evidence in $dependency.getEvidenceUsed())
#foreach($evidence in $dependency.getEvidenceForDisplay())
<tr><td>$enc.html($evidence.getSource())</td><td>$enc.html($evidence.getName())</td><td>$enc.html($evidence.getValue())</td></tr>
#end
</table>
@@ -582,7 +661,7 @@ arising out of or in connection with the use of this tool, the analysis performe
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<ul>
#foreach($related in $dependency.getRelatedDependencies())
<li>$enc.html($related.FileName)
<li>$enc.html($related.DisplayFileName)
<ul>
<li>File Path:&nbsp;$enc.html($related.FilePath)</li>
<li>SHA1:&nbsp;$enc.html($related.Sha1sum)</li>
@@ -612,7 +691,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#end
#end
<h4 id="header$cnt" class="subsectionheader white">Identifiers</h4>
##:&nbsp;<a href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
##:&nbsp;<a href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
<div id="content$cnt" class="subsectioncontent standardsubsection">
#if ($dependency.getIdentifiers().size()==0)
<ul><li><b>None</b></li></ul>
@@ -630,7 +709,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#end
#if ($id.type=="cpe")
##yes, we are HTML Encoding into JavaScript... the escape utils don't have a JS Encode and I haven't written one yet
&nbsp;&nbsp;<button class="copybutton" onclick="copyText('$enc.html($dependency.FileNameForJavaScript)', '$enc.html($dependency.Sha1sum)', 'cpe', '$enc.html($id.value)')">suppress</button>
&nbsp;&nbsp;<button class="copybutton" title="Generate Suppression XML for this CPE for this file" onclick="copyText('$enc.html($dependency.FileNameForJavaScript)', '$enc.html($dependency.Sha1sum)', 'cpe', '$enc.html($id.value)')">suppress</button>
#end
#if ($id.description)
<br/>$enc.html($id.description)
@@ -646,7 +725,7 @@ arising out of or in connection with the use of this tool, the analysis performe
<div id="content$cnt" class="subsectioncontent standardsubsection">
#foreach($vuln in $dependency.getVulnerabilities())
#set($vsctr=$vsctr+1)
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b>&nbsp;&nbsp;<button class="copybutton" onclick="copyText('$enc.html($dependency.FileNameForJavaScript)', '$enc.html($dependency.Sha1sum)', 'cve', '$enc.html($vuln.name)')">suppress</button></p>
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b>&nbsp;&nbsp;<button class="copybutton" title="Generate Suppression XML for this CCE for this file" onclick="copyText('$enc.html($dependency.FileNameForJavaScript)', '$enc.html($dependency.Sha1sum)', 'cve', '$enc.html($vuln.name)')">suppress</button></p>
<p>Severity:
#if ($vuln.cvssScore<4.0)
Low
@@ -668,13 +747,20 @@ arising out of or in connection with the use of this tool, the analysis performe
</ul>
#end
</p>
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware())
<li class="vs$vsctr hidden"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#if ($vuln.getVulnerableSoftware().size()<2)
<p>Vulnerable Software &amp; Versions:<ul>
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
</ul></p>
#else
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware())
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#end
</ul></p>
#end
</ul></p>
#end
</div>
#end
@@ -692,7 +778,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#foreach($dependency in $dependencies)
#if ($dependency.getSuppressedIdentifiers().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
#set($lnkcnt=$lnkcnt+1)
<h3 class="subsectionheader standardsubsection">$enc.html($dependency.FileName)</h3>
<h3 class="subsectionheader standardsubsection">$enc.html($dependency.DisplayFileName)</h3>
<div class="subsectioncontent">
#if ($dependency.description)
<p><b>Description:</b>&nbsp;$enc.html($dependency.description)<br/></p>
@@ -714,7 +800,7 @@ arising out of or in connection with the use of this tool, the analysis performe
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<table class="lined fullwidth" border="0">
<tr><th class="left" style="width:10%;">Source</th><th class="left" style="width:20%;">Name</th><th class="left" style="width:70%;">Value</th></tr>
#foreach($evidence in $dependency.getEvidenceUsed())
#foreach($evidence in $dependency.getEvidenceForDisplay())
<tr><td>$enc.html($evidence.getSource())</td><td>$enc.html($evidence.getName())</td><td>$enc.html($evidence.getValue())</td></tr>
#end
</table>
@@ -725,7 +811,7 @@ arising out of or in connection with the use of this tool, the analysis performe
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<ul>
#foreach($related in $dependency.getRelatedDependencies())
<li>$enc.html($related.FileName)
<li>$enc.html($related.DisplayFileName)
<ul>
<li>File Path:&nbsp;$enc.html($related.FilePath)</li>
<li>SHA1:&nbsp;$enc.html($related.Sha1sum)</li>
@@ -744,7 +830,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#end
#end
<h4 id="header$cnt" class="subsectionheader white">Suppressed Identifiers</h4>
##:&nbsp;<a href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
##:&nbsp;<a href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
<div id="content$cnt" class="subsectioncontent standardsubsection">
#if ($dependency.getSuppressedIdentifiers().size()==0)
<ul><li><b>None</b></li></ul>
@@ -796,13 +882,19 @@ arising out of or in connection with the use of this tool, the analysis performe
</ul>
#end
</p>
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware())
<li class="vs$vsctr hidden"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#if ($vuln.getVulnerableSoftware().size()<2)
<p>Vulnerable Software &amp; Versions:<ul>
git st<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
</ul></p>
#else
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware())
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#end
</ul></p>
#end
</ul></p>
#end
</div>
#end
@@ -814,6 +906,6 @@ arising out of or in connection with the use of this tool, the analysis performe
## END SUPPRESSED VULNERABILITIES
</div>
</div>
<div><br/><br/>This report contains data retrieved from the <a href="nvd.nist.gov">National Vulnerability Database</a>.</div>
<div><br/><br/>This report contains data retrieved from the <a href="http://nvd.nist.gov">National Vulnerability Database</a>.</div>
</body>
</html>

View File

@@ -222,10 +222,10 @@ arising out of or in connection with the use of this tool, the analysis performe
($vuln.cvssScore)
<td>#set($cnt=$cnt+1)
#if($dependency.getRelatedDependencies().size()>0)<span id="header$cnt" class="expandable collapsedList">#end
$enc.html($dependency.FileName)
$enc.html($dependency.DisplayFileName)
#if($dependency.getRelatedDependencies().size()>0)&nbsp;&nbsp;&nbsp;</span><div id="content$cnt" class="hidden">#end
#foreach($related in $dependency.getRelatedDependencies())
$enc.html($related.FileName)<br/>
$enc.html($related.DisplayFileName)<br/>
#end
#if($dependency.getRelatedDependencies().size()>0)</div#end
</td>
@@ -236,6 +236,6 @@ arising out of or in connection with the use of this tool, the analysis performe
</tbody>
</table>
</div>
<p><br/><br/>This report contains data retrieved from the <a href="nvd.nist.gov">National Vulnerability Database</a>.</p>
<p><br/><br/>This report contains data retrieved from the <a href="http://nvd.nist.gov">National Vulnerability Database</a>.</p>
</body>
</html>

View File

@@ -36,7 +36,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<dependencies>
#foreach($dependency in $dependencies)
<dependency>
<fileName>$enc.xml($dependency.FileName)</fileName>
<fileName>$enc.xml($dependency.DisplayFileName)</fileName>
<filePath>$enc.xml($dependency.FilePath)</filePath>
<md5>$enc.xml($dependency.Md5sum)</md5>
<sha1>$enc.xml($dependency.Sha1sum)</sha1>
@@ -68,7 +68,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</relatedDependencies>
#end
<evidenceCollected>
#foreach($evidence in $dependency.getEvidenceUsed())
#foreach($evidence in $dependency.getEvidenceForDisplay())
<evidence>
<source>$enc.xml($evidence.getSource())</source>
<name>$enc.xml($evidence.getName())</name>

View File

@@ -32,6 +32,6 @@ public class BaseTest {
@AfterClass
public static void tearDownClass() throws Exception {
Settings.cleanup();
Settings.cleanup(true);
}
}

View File

@@ -23,7 +23,6 @@ import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.Settings;
@@ -42,26 +41,6 @@ public class EngineIntegrationTest extends BaseTest {
public void tearDown() {
}
/**
* Test of scan method, of class Engine.
*
* @throws Exception is thrown when an exception occurs.
*/
@Test
public void testScan() throws Exception {
String testClasses = "target/test-classes/*.zip";
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
Engine instance = new Engine();
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
instance.scan(testClasses);
assertTrue(instance.getDependencies().size() > 0);
for (Dependency d : instance.getDependencies()) {
assertTrue("non-zip file collected " + d.getFileName(), d.getFileName().toLowerCase().endsWith(".zip"));
}
instance.cleanup();
}
/**
* Test running the entire engine.
*
@@ -70,10 +49,10 @@ public class EngineIntegrationTest extends BaseTest {
@Test
public void testEngine() throws Exception {
String testClasses = "target/test-classes";
// boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
// Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
Engine instance = new Engine();
// Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
instance.scan(testClasses);
assertTrue(instance.getDependencies().size() > 0);
instance.analyzeDependencies();
@@ -81,8 +60,7 @@ public class EngineIntegrationTest extends BaseTest {
cveDB.open();
DatabaseProperties dbProp = cveDB.getDatabaseProperties();
cveDB.close();
ReportGenerator rg = new ReportGenerator("DependencyCheck",
instance.getDependencies(), instance.getAnalyzers(), dbProp);
ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp);
rg.generateReports("./target/", "ALL");
instance.cleanup();
}

View File

@@ -17,31 +17,78 @@
*/
package org.owasp.dependencycheck.analyzer;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.BaseTest;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.suppression.SuppressionParseException;
import org.owasp.dependencycheck.suppression.SuppressionRule;
import org.owasp.dependencycheck.utils.Settings;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class AbstractSuppressionAnalyzerTest extends BaseTest {
private AbstractSuppressionAnalyzer instance;
@Before
public void setUp() throws Exception {
public void createObjectUnderTest() throws Exception {
instance = new AbstractSuppressionAnalyzerImpl();
}
/**
* Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer.
*/
@Test
public void testGetSupportedExtensions() {
Set<String> result = instance.getSupportedExtensions();
assertNull(result);
}
/**
* Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL.
*/
@Test
public void testGetRulesFromSuppressionFileFromURL() throws Exception {
setSupressionFileFromURL();
instance.initialize();
int expCount = 5;
List<SuppressionRule> result = instance.getRules();
assertTrue(expCount <= result.size());
}
/**
* Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL.
*/
@Test
public void testGetRulesFromSuppressionFileInClasspath() throws Exception {
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml");
instance.initialize();
int expCount = 5;
List<SuppressionRule> result = instance.getRules();
assertTrue(expCount <= result.size());
}
@Test(expected = SuppressionParseException.class)
public void testFailureToLocateSuppressionFileAnywhere() throws Exception {
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml");
instance.initialize();
}
private void setSupressionFileFromURL() throws Exception {
try {
final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString();
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri);
@@ -52,37 +99,6 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest {
}
}
/**
* Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer.
*/
@Test
public void testGetSupportedExtensions() {
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
Set<String> result = instance.getSupportedExtensions();
assertNull(result);
}
/**
* Test of initialize method, of class AbstractSuppressionAnalyzer.
*/
@Test
public void testInitialize() throws Exception {
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
instance.initialize();
}
/**
* Test of getRules method, of class AbstractSuppressionAnalyzer.
*/
@Test
public void testGetRules() throws Exception {
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
instance.initialize();
int expCount = 5;
List<SuppressionRule> result = instance.getRules();
assertEquals(expCount, result.size());
}
public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer {
@Override

View File

@@ -40,7 +40,7 @@ public class ArchiveAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
@Test
public void testGetSupportedExtensions() {
ArchiveAnalyzer instance = new ArchiveAnalyzer();
Set expResult = new HashSet<String>();
Set<String> expResult = new HashSet<String>();
expResult.add("zip");
expResult.add("war");
expResult.add("ear");

View File

@@ -25,9 +25,11 @@ import java.util.Set;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryparser.classic.ParseException;
import org.junit.Assert;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
import org.owasp.dependencycheck.data.cpe.IndexEntry;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Identifier;
@@ -81,12 +83,24 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
*/
@Test
public void testDetermineCPE_full() throws Exception {
callDetermineCPE_full("hazelcast-2.5.jar", null);
callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:vmware:springsource_spring_framework:2.5.5");
callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0");
callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2");
callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null);
callDetermineCPE_full("ehcache-core-2.2.0.jar", null);
CPEAnalyzer instance = new CPEAnalyzer();
instance.open();
FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer();
JarAnalyzer jarAnalyzer = new JarAnalyzer();
HintAnalyzer hAnalyzer = new HintAnalyzer();
FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer();
try {
//callDetermineCPE_full("struts2-core-2.3.16.3.jar", "cpe:/a:apache:struts:2.3.16.3", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:vmware:springsource_spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
} finally {
instance.close();
}
}
/**
@@ -94,37 +108,25 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
*
* @throws Exception is thrown when an exception occurs
*/
public void callDetermineCPE_full(String depName, String expResult) throws Exception {
public void callDetermineCPE_full(String depName, String expResult, CPEAnalyzer instance, FileNameAnalyzer fnAnalyzer, JarAnalyzer jarAnalyzer, HintAnalyzer hAnalyzer, FalsePositiveAnalyzer fp) throws Exception {
File file = new File(this.getClass().getClassLoader().getResource(depName).getPath());
Dependency dep = new Dependency(file);
FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer();
fnAnalyzer.analyze(dep, null);
JarAnalyzer jarAnalyzer = new JarAnalyzer();
jarAnalyzer.analyze(dep, null);
HintAnalyzer hAnalyzer = new HintAnalyzer();
hAnalyzer.analyze(dep, null);
CPEAnalyzer instance = new CPEAnalyzer();
instance.open();
instance.analyze(dep, null);
instance.close();
FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer();
fp.analyze(dep, null);
// for (Identifier i : dep.getIdentifiers()) {
// System.out.println(i.getValue());
// }
if (expResult != null) {
Identifier expIdentifier = new Identifier("cpe", expResult, expResult);
Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier));
} else if (dep.getIdentifiers().isEmpty()) {
Assert.assertTrue("Match found when an Identifier should not have been found: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().isEmpty());
} else {
Assert.assertTrue("Match found when an Identifier should not have been found: { dep:'" + dep.getFileName() + "', identifier:'" + dep.getIdentifiers().iterator().next().getValue() + "' }", dep.getIdentifiers().isEmpty());
for (Identifier i : dep.getIdentifiers()) {
Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType()));
}
}
}
@@ -170,7 +172,10 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5";
String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0";
Assert.assertTrue("Apache Common Validator - found an identifier?", commonValidator.getIdentifiers().isEmpty());
for (Identifier i : commonValidator.getIdentifiers()) {
Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType()));
}
Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1);
Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier));
Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1);
@@ -180,6 +185,30 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
//Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring));
}
/**
* Test of determineIdentifiers method, of class CPEAnalyzer.
*
* @throws Exception is thrown when an exception occurs
*/
@Test
public void testDetermineIdentifiers() throws Exception {
Dependency openssl = new Dependency();
openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST);
openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST);
openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST);
CPEAnalyzer instance = new CPEAnalyzer();
instance.open();
instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST);
instance.close();
String expResult = "cpe:/a:openssl:openssl:1.0.1c";
Identifier expIdentifier = new Identifier("cpe", expResult, expResult);
assertTrue(openssl.getIdentifiers().contains(expIdentifier));
}
/**
* Test of searchCPE method, of class CPEAnalyzer.
*
@@ -190,12 +219,12 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
String vendor = "apache software foundation";
String product = "struts 2 core";
String version = "2.1.2";
String expResult = "cpe:/a:apache:struts:2.1.2";
String expVendor = "apache";
String expProduct = "struts";
CPEAnalyzer instance = new CPEAnalyzer();
instance.open();
//TODO - yeah, not a very good test as the results are the same with or without weighting...
Set<String> productWeightings = new HashSet<String>(1);
productWeightings.add("struts2");
@@ -203,9 +232,16 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
vendorWeightings.add("apache");
List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings);
//TODO fix this assert
//Assert.assertEquals(expResult, result.get(0).getName());
instance.close();
boolean found = false;
for (IndexEntry entry : result) {
if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) {
found = true;
break;
}
}
assertTrue("apache:struts was not identified", found);
}
}

View File

@@ -86,4 +86,40 @@ public class DependencyBundlingAnalyzerTest extends BaseTest {
assertEquals(expResult, result);
}
@Test
public void testFirstPathIsShortest() {
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
String left = "./a/c.jar";
String right = "./d/e/f.jar";
boolean expResult = true;
boolean result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
left = "./a/b/c.jar";
right = "./d/e/f.jar";
expResult = true;
result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
left = "./d/b/c.jar";
right = "./a/e/f.jar";
expResult = false;
result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
left = "./a/b/c.jar";
right = "./d/f.jar";
expResult = false;
result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
left = "./a/b/c.jar";
right = "./a/b/c.jar";
expResult = true;
result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
}
}

View File

@@ -56,6 +56,7 @@ public class FalsePositiveAnalyzerTest {
public void testAnalyze() throws Exception {
Dependency dependency = new Dependency();
dependency.setFileName("pom.xml");
dependency.setFilePath("pom.xml");
dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url");
Engine engine = null;
FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer();

View File

@@ -85,7 +85,7 @@ public class HintAnalyzerTest extends BaseTest {
for (Dependency d : engine.getDependencies()) {
if (d.getActualFile().equals(guice)) {
gdep = d;
} else {
} else if (d.getActualFile().equals(spring)) {
sdep = d;
}
}

View File

@@ -93,7 +93,7 @@ public class JarAnalyzerTest extends BaseTest {
@Test
public void testGetSupportedExtensions() {
JarAnalyzer instance = new JarAnalyzer();
Set expResult = new HashSet();
Set<String> expResult = new HashSet<String>();
expResult.add("jar");
expResult.add("war");
Set result = instance.getSupportedExtensions();

View File

@@ -38,7 +38,7 @@ public class JavaScriptAnalyzerTest extends BaseTest {
@Test
public void testGetSupportedExtensions() {
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
Set expResult = new HashSet<String>();
Set<String> expResult = new HashSet<String>();
expResult.add("js");
Set result = instance.getSupportedExtensions();
assertEquals(expResult, result);

View File

@@ -61,19 +61,26 @@ public class VulnerabilitySuppressionAnalyzerIntegrationTest extends AbstractDat
@Test
public void testAnalyze() throws Exception {
File file = new File(this.getClass().getClassLoader().getResource("FileHelpers.2.0.0.0.nupkg").getPath());
File suppression = new File(this.getClass().getClassLoader().getResource("FileHelpers.2.0.0.0.suppression.xml").getPath());
File file = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.jar").getPath());
File suppression = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.suppression.xml").getPath());
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
Engine engine = new Engine();
engine.scan(file);
engine.analyzeDependencies();
Dependency dependency = getDependency(engine, file);
assertTrue(dependency.getVulnerabilities().size() > 0);
int cveSize = dependency.getVulnerabilities().size();
int cpeSize = dependency.getIdentifiers().size();
assertTrue(cveSize > 0);
assertTrue(cpeSize > 0);
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppression.getAbsolutePath());
VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer();
instance.initialize();
instance.analyze(dependency, engine);
assertTrue(dependency.getVulnerabilities().size() == 0);
cveSize = cveSize > 1 ? cveSize - 2 : 0;
cpeSize = cpeSize > 0 ? cpeSize - 1 : 0;
assertTrue(dependency.getVulnerabilities().size() == cveSize);
assertTrue(dependency.getIdentifiers().size() == cpeSize);
engine.cleanup();
}

View File

@@ -0,0 +1,63 @@
package org.owasp.dependencycheck.data.central;
import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.BaseTest;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.utils.Settings;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;
import static org.junit.Assert.*;
/**
* Created by colezlaw on 10/13/14.
*/
public class CentralSearchTest extends BaseTest {
private static final Logger LOGGER = Logger.getLogger(CentralSearchTest.class.getName());
private CentralSearch searcher;
@Before
public void setUp() throws Exception {
String centralUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
LOGGER.fine(centralUrl);
searcher = new CentralSearch(new URL(centralUrl));
}
@Test(expected = IllegalArgumentException.class)
public void testNullSha1() throws Exception { searcher.searchSha1(null); }
@Test(expected = IllegalArgumentException.class)
public void testMalformedSha1() throws Exception {
searcher.searchSha1("invalid");
}
// This test does generate network traffic and communicates with a host
// you may not be able to reach. Remove the @Ignore annotation if you want to
// test it anyway
@Test
public void testValidSha1() throws Exception {
List<MavenArtifact> ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea");
assertEquals("Incorrect group", "org.apache.maven.plugins", ma.get(0).getGroupId());
assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.get(0).getArtifactId());
assertEquals("Incorrect version", "3.1", ma.get(0).getVersion());
}
// This test does generate network traffic and communicates with a host
// you may not be able to reach. Remove the @Ignore annotation if you want to
// test it anyway
@Test(expected = FileNotFoundException.class)
public void testMissingSha1() throws Exception {
searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}
// This test should give us multiple results back from Central
@Test
public void testMultipleReturns() throws Exception {
List<MavenArtifact> ma = searcher.searchSha1("94A9CE681A42D0352B3AD22659F67835E560D107");
assertTrue(ma.size() > 1);
}
}

View File

@@ -45,8 +45,10 @@ public abstract class BaseDBTestCase extends BaseTest {
public static void ensureDBExists() throws Exception {
java.io.File dataPath = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
if (!dataPath.exists() || (dataPath.isDirectory() && dataPath.listFiles().length < 3)) {
java.io.File dataPath = Settings.getDataDirectory();
String fileName = String.format(Settings.getString(Settings.KEYS.DB_FILE_NAME), Settings.getString(Settings.KEYS.DB_VERSION));
java.io.File dataFile = new File(dataPath, fileName);
if (!dataPath.exists() || !dataFile.exists()) {
dataPath.mkdirs();
FileInputStream fis = null;
ZipInputStream zin = null;

View File

@@ -19,9 +19,11 @@ package org.owasp.dependencycheck.data.nvdcve;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
import org.owasp.dependencycheck.utils.DependencyVersion;
/**
*
@@ -72,4 +74,21 @@ public class CveDBIntegrationTest extends BaseDBTestCase {
instance.close();
}
}
/**
* Test of isAffected method, of class CveDB.
*/
@Test
public void testIsAffected() throws Exception {
String vendor = "openssl";
String product = "openssl";
DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o");
String cpeId = "cpe:/a:openssl:openssl:1.0.1e";
String previous = "y";
CveDB instance = new CveDB();
assertFalse(instance.isAffected(vendor, product, identifiedVersion, cpeId, previous));
}
}

View File

@@ -17,8 +17,12 @@
*/
package org.owasp.dependencycheck.data.update;
import java.io.File;
import java.util.Calendar;
import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.BaseTest;
import org.owasp.dependencycheck.utils.Settings;
/**
*
@@ -26,6 +30,32 @@ import org.owasp.dependencycheck.BaseTest;
*/
public class NvdCveUpdaterIntegrationTest extends BaseTest {
@Before
public void setUp() throws Exception {
int year = Calendar.getInstance().get(Calendar.YEAR);
if (year <= 2014) {
File f = new File(NvdCveUpdaterIntegrationTest.class.getClassLoader().getResource("nvdcve-2.0-2014.xml").getPath());
String baseURL = f.toURI().toURL().toString();
String modified12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-modified.xml");
String modified20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-modified.xml");
String full12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-%d.xml");
String full20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-%d.xml");
// cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
// cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
// cve.startyear=2014
// cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
// cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, modified12);
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, modified20);
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, full12);
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, full20);
Settings.setString(Settings.KEYS.CVE_START_YEAR, "2014");
} else {
System.err.println("Consider updating the local data files to make the NvdCveUpdaterIntegrationTest perform faster");
}
}
/**
* Test of update method, of class NvdCveUpdater.
*/

View File

@@ -67,16 +67,16 @@ public class StandardUpdateIntegrationTest extends BaseTest {
result = instance.withinRange(lastRun, current, range);
assertEquals(expResult, result);
}
/**
* Test of update method, of class StandardUpdate.
*/
@Test
public void testUpdate() throws Exception {
StandardUpdate instance = getStandardUpdateTask();
instance.update();
//TODO make this an actual test
}
// test removed as it is duplicative of the EngineIntegrationTest and the NvdCveUpdaterIntergraionTest
// /**
// * Test of update method, of class StandardUpdate.
// */
// @Test
// public void testUpdate() throws Exception {
// StandardUpdate instance = getStandardUpdateTask();
// instance.update();
// //TODO make this an actual test
// }
/**
* Test of updatesNeeded method, of class StandardUpdate.

View File

@@ -0,0 +1,75 @@
/*
* 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) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.data.update.task;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.update.NvdCveInfo;
import org.owasp.dependencycheck.utils.Settings;
/**
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public class DownloadTaskTest {
public DownloadTaskTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
Settings.initialize();
}
@After
public void tearDown() {
Settings.cleanup();
}
/**
* Test of call method, of class DownloadTask.
*/
@Test
public void testCall() throws Exception {
NvdCveInfo cve = new NvdCveInfo();
cve.setId("modified");
cve.setNeedsUpdate(true);
cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL));
cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL));
ExecutorService processExecutor = null;
CveDB cveDB = null;
DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance());;
Future<ProcessTask> result = instance.call();
assertNull(result);
}
}

View File

@@ -23,10 +23,12 @@ import java.util.Set;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
/**
*
@@ -152,7 +154,7 @@ public class DependencyTest {
public void testGetMd5sum() {
File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
Dependency instance = new Dependency(file);
// assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum());
//assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum());
String expResult = "C30B57142E1CCBC1EFD5CD15F307358F";
String result = instance.getMd5sum();
assertEquals(expResult, result);
@@ -294,4 +296,34 @@ public class DependencyTest {
EvidenceCollection result = instance.getVersionEvidence();
assertTrue(true); //this is just a getter setter pair.
}
/**
* Test of addAsEvidence method, of class Dependency.
*/
@Test
public void testAddAsEvidence() {
Dependency instance = new Dependency();
MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url");
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
assertTrue(instance.getEvidence().contains(Confidence.HIGH));
assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty());
assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty());
assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty());
assertFalse(instance.getIdentifiers().isEmpty());
}
/**
* Test of addAsEvidence method, of class Dependency.
*/
@Test
public void testAddAsEvidenceWithEmptyArtefact() {
Dependency instance = new Dependency();
MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null);
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
assertFalse(instance.getEvidence().contains(Confidence.HIGH));
assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty());
assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty());
assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty());
assertTrue(instance.getIdentifiers().isEmpty());
}
}

View File

@@ -88,7 +88,15 @@ public class SuppressionHandlerTest {
xmlReader.parse(in);
List result = handler.getSuppressionRules();
List<SuppressionRule> result = handler.getSuppressionRules();
assertTrue(result.size() > 3);
int baseCount = 0;
for (SuppressionRule r : result) {
if (r.isBase()) {
baseCount++;
}
}
assertTrue(baseCount > 0);
}
}

View File

@@ -146,6 +146,17 @@ public class SuppressionRuleTest {
List<String> result = instance.getCve();
assertEquals(cve, result);
}
/**
* Test of base property, of class SuppressionRule.
*/
@Test
public void testBase() {
SuppressionRule instance = new SuppressionRule();
assertFalse(instance.isBase());
instance.setBase(true);
assertTrue(instance.isBase());
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Ignored duplicate tests, left in, as empty tests, so IDE doesn't re-generate them">
@@ -339,55 +350,70 @@ public class SuppressionRuleTest {
}
/**
* Test of cpeMatches method, of class SuppressionRule.
* Test of identifierMatches method, of class SuppressionRule.
*/
@Test
public void testCpeMatches() {
Identifier identifier = new Identifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
Identifier identifier = new Identifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
PropertyType cpe = new PropertyType();
cpe.setValue("cpe:/a:microsoft:.net_framework:4.5");
SuppressionRule instance = new SuppressionRule();
boolean expResult = true;
boolean result = instance.cpeMatches(cpe, identifier);
boolean result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.net_framework:4.0");
expResult = false;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("CPE:/a:microsoft:.net_framework:4.5");
cpe.setCaseSensitive(true);
expResult = false;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.net_framework");
cpe.setCaseSensitive(false);
expResult = true;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.*");
cpe.setRegex(true);
expResult = true;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("CPE:/a:microsoft:.*");
cpe.setRegex(true);
cpe.setCaseSensitive(true);
expResult = false;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("cpe:/a:apache:.*");
cpe.setRegex(true);
cpe.setCaseSensitive(false);
expResult = false;
result = instance.cpeMatches(cpe, identifier);
result = instance.identifierMatches("cpe", cpe, identifier);
assertEquals(expResult, result);
identifier = new Identifier("maven", "org.springframework:spring-core:2.5.5", "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.springframework&a=spring-core&v=2.5.5&e=jar");
cpe.setValue("org.springframework:spring-core:2.5.5");
cpe.setRegex(false);
cpe.setCaseSensitive(false);
expResult = true;
result = instance.identifierMatches("maven", cpe, identifier);
assertEquals(expResult, result);
cpe.setValue("org\\.springframework\\.security:spring.*");
cpe.setRegex(true);
cpe.setCaseSensitive(false);
expResult = false;
result = instance.identifierMatches("maven", cpe, identifier);
assertEquals(expResult, result);
}
@@ -398,7 +424,7 @@ public class SuppressionRuleTest {
public void testProcess() {
File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
Dependency dependency = new Dependency(struts);
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
String sha1 = dependency.getSha1sum();
dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970");
Vulnerability v = createVulnerability();
@@ -409,33 +435,33 @@ public class SuppressionRuleTest {
instance.setSha1(sha1);
instance.addCwe("287");
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().size() == 1);
assertEquals(1, dependency.getVulnerabilities().size());
dependency.setSha1sum(sha1);
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().isEmpty());
assertTrue(dependency.getSuppressedVulnerabilities().size() == 1);
assertEquals(1, dependency.getSuppressedVulnerabilities().size());
//cvss
dependency.addVulnerability(v);
instance = new SuppressionRule();
instance.addCvssBelow(5f);
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().size() == 1);
assertEquals(1, dependency.getVulnerabilities().size());
instance.addCvssBelow(8f);
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().isEmpty());
assertTrue(dependency.getSuppressedVulnerabilities().size() == 1);
assertEquals(1, dependency.getSuppressedVulnerabilities().size());
//cve
dependency.addVulnerability(v);
instance = new SuppressionRule();
instance.addCve("CVE-2012-1337");
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().size() == 1);
assertEquals(1, dependency.getVulnerabilities().size());
instance.addCve("CVE-2013-1337");
instance.process(dependency);
assertTrue(dependency.getVulnerabilities().isEmpty());
assertTrue(dependency.getSuppressedVulnerabilities().size() == 1);
assertEquals(1, dependency.getSuppressedVulnerabilities().size());
//cpe
instance = new SuppressionRule();
@@ -453,18 +479,58 @@ public class SuppressionRuleTest {
instance.setFilePath(pt);
instance.process(dependency);
assertTrue(dependency.getIdentifiers().isEmpty());
assertTrue(dependency.getSuppressedIdentifiers().size() == 1);
assertEquals(1, dependency.getSuppressedIdentifiers().size());
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
instance = new SuppressionRule();
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
pt = new PropertyType();
pt.setValue("cpe:/a:microsoft:.net_framework");
instance.addCpe(pt);
assertTrue(dependency.getIdentifiers().size() == 3);
instance.setBase(true);
assertEquals(3, dependency.getIdentifiers().size());
assertEquals(1, dependency.getSuppressedIdentifiers().size());
instance.process(dependency);
assertTrue(dependency.getIdentifiers().isEmpty());
assertTrue(dependency.getSuppressedIdentifiers().size() == 3);
assertEquals(1, dependency.getSuppressedIdentifiers().size());
}
/**
* Test of process method, of class SuppressionRule.
*/
@Test
public void testProcessGAV() {
File spring = new File(this.getClass().getClassLoader().getResource("spring-security-web-3.0.0.RELEASE.jar").getPath());
Dependency dependency = new Dependency(spring);
dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_framework:3.0.0", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:springsource:spring_framework:3.0.0", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:mod_security:mod_security:3.0.0", "some url not needed for this test");
dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_security:3.0.0", "some url not needed for this test");
dependency.addIdentifier("maven", "org.springframework.security:spring-security-web:3.0.0.RELEASE", "some url not needed for this test");
//cpe
SuppressionRule instance = new SuppressionRule();
PropertyType pt = new PropertyType();
pt.setValue("org\\.springframework\\.security:spring.*");
pt.setRegex(true);
pt.setCaseSensitive(false);
instance.setGav(pt);
pt = new PropertyType();
pt.setValue("cpe:/a:mod_security:mod_security");
instance.addCpe(pt);
pt = new PropertyType();
pt.setValue("cpe:/a:springsource:spring_framework");
instance.addCpe(pt);
pt = new PropertyType();
pt.setValue("cpe:/a:vmware:springsource_spring_framework");
instance.addCpe(pt);
instance.process(dependency);
assertEquals(2, dependency.getIdentifiers().size());
}
private Vulnerability createVulnerability() {

View File

@@ -134,14 +134,14 @@ public class DependencyVersionTest {
@Test
public void testMatchesAtLeastThreeLevels() {
DependencyVersion instance = new DependencyVersion("1.2.3.4");
DependencyVersion version = new DependencyVersion("1.2.3.5");
DependencyVersion instance = new DependencyVersion("2.3.16.3");
DependencyVersion version = new DependencyVersion("2.3.16.4");
//true tests
assertEquals(true, instance.matchesAtLeastThreeLevels(version));
version = new DependencyVersion("1.2");
version = new DependencyVersion("2.3");
assertEquals(true, instance.matchesAtLeastThreeLevels(version));
//false tests
version = new DependencyVersion("1.2.2.5");
version = new DependencyVersion("2.3.16.1");
assertEquals(false, instance.matchesAtLeastThreeLevels(version));
version = new DependencyVersion("2");
assertEquals(false, instance.matchesAtLeastThreeLevels(version));
@@ -165,6 +165,14 @@ public class DependencyVersionTest {
version = new DependencyVersion("1.2.3.1");
assertEquals(-1, instance.compareTo(version));
instance = new DependencyVersion("1.0.1n");
version = new DependencyVersion("1.0.1m");
assertEquals(1, instance.compareTo(version));
version = new DependencyVersion("1.0.1n");
assertEquals(0, instance.compareTo(version));
version = new DependencyVersion("1.0.1o");
assertEquals(-1, instance.compareTo(version));
DependencyVersion[] dv = new DependencyVersion[7];
dv[0] = new DependencyVersion("2.1.3");
dv[1] = new DependencyVersion("2.1.3.r2");

View File

@@ -54,13 +54,13 @@ public class DependencyVersionUtilTest {
* Test of parseVersion method, of class DependencyVersionUtil.
*/
@Test
public void testParseVersionFromFileName() {
public void testParseVersion() {
final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar",
"lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar",
"lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar",
"-", "", "1.3-beta", "6"};
"-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar"};
final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1",
"2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6"};
"2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", "2.2.8.02"};
for (int i = 0; i < fileName.length; i++) {
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]);

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
<suppress>
<notes><![CDATA[
file name: FileHelpers.2.0.0.0.nupkg
]]></notes>
<sha1>30FB37D6163CF16E3BA740343BECDD14D5457619</sha1>
<cve>CVE-2007-1536</cve>
</suppress>
</suppressions>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
<suppress>
<notes><![CDATA[
file name: commons-fileupload-1.2.1.jar
]]></notes>
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
<cpe>cpe:/a:apache:commons_fileupload:1.2.1</cpe>
</suppress>
<suppress>
<notes><![CDATA[
file name: commons-fileupload-1.2.1.jar
]]></notes>
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
<cve>CVE-2014-0050</cve>
</suppress>
<suppress>
<notes><![CDATA[
file name: commons-fileupload-1.2.1.jar
]]></notes>
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
<cve>CVE-2013-0248</cve>
</suppress>
</suppressions>

View File

@@ -13,8 +13,12 @@ max.download.threads=3
# will not be used. The data.directory will be resolved and if the connection string
# below contains a %s then the data.directory will replace the %s.
data.directory=[JAR]/data
# if the filename has a %s it will be replaced with the current expected version. For file
# based databases the below filename will be added to the data directory above and then
# if the connection string has a %s it will be replaced by the directory/filename path.
data.file_name=cve.%s.h2.db
data.version=2.9
data.connection_string=jdbc:h2:file:%s;FILE_LOCK=SERIALIZED;AUTOCOMMIT=ON;
#data.connection_string=jdbc:h2:file:%s;AUTO_SERVER=TRUE;AUTOCOMMIT=ON;
#data.connection_string=jdbc:mysql://localhost:3306/dependencycheck
# user name and password for the database connection. The inherent case is to use H2.
@@ -43,11 +47,16 @@ cpe.meta.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-di
cve.url.modified.validfordays=7
# the path to the modified nvd cve xml file.
cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cve.startyear=2014
cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
cve.url-1.2.modified=https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
#cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
cve.url-2.0.modified=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
#cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cve.url-1.2.base=https://nvd.nist.gov/download/nvdcve-%d.xml.gz
#cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
#cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
analyzer.nexus.enabled=true
@@ -55,3 +64,7 @@ analyzer.nexus.url=https://repository.sonatype.org/service/local/
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
# are configured
analyzer.nexus.proxy=true
# the URL for searching search.maven.org for SHA-1 and whether it's enabled
analyzer.central.enabled=true
analyzer.central.url=http://search.maven.org/solrsearch/select

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
<filePath>c:\path\to\some.jar</filePath>
<cpe>cpe:/a:csv:csv:1.0</cpe>
</suppress>
<suppress>
<suppress base="true">
<notes><![CDATA[
This suppresses any jboss:jboss cpe for any test.jar in any directory.
]]></notes>

View File

@@ -1,17 +1,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<description>This plug-in can independently execute a Dependency-Check analysis and visualize the results.</description>
<url>http://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin</url>
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.2.0</version>
<version>1.2.6</version>
</parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-jenkins</artifactId>
<name>Dependency-Check Jenkins Plugin</name>
<url>http://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin</url>
<description>dependency-check-jenkins is a Jenkins plugin that runs dependency-check-core on a project to detect publicly disclosed vulnerabilities associated with the project's dependencies. The plugin will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries. This module is simply a placeholder and does not contain the actual plugin source code. The source code and distribution of the plugin is handled via https://github.com/jenkinsci/dependency-check-jenkins and Jenkin's plugin management.</description>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
<id>github-pages-site</id>
<name>Deployment through GitHub's site deployment plugin</name>
<url>${basedir}/../target/site/${project.version}/dependency-check-jenkins</url>
</site>
</distributionManagement>
<!-- end copy -->
<packaging>pom</packaging>
<inceptionYear>2012</inceptionYear>
<organization>
@@ -31,15 +39,6 @@
</roles>
</developer>
</developers>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
<site>
<id>github-pages-site</id>
<name>Deployment through GitHub's site deployment plugin</name>
<url>${basedir}/../target/site/${project.version}/dependency-check-maven</url>
</site>
</distributionManagement>
<!-- end copy -->
<scm>
<connection>scm:git:git@github.com:jenkinsci/dependency-check-jenkins.git</connection>
<url>https://github.com/jenkinsci/dependency-check-jenkins</url>

View File

@@ -15,7 +15,6 @@ limitations under the License.
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<url>http://maven.apache.org</url>
@@ -23,14 +22,14 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.2.0</version>
<version>1.2.6</version>
</parent>
<artifactId>dependency-check-maven</artifactId>
<packaging>maven-plugin</packaging>
<name>Dependency-Check Maven Plugin</name>
<description>Dependency-Check-Maven is a Maven Plugin 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.</description>
<description>dependency-check-maven is a Maven Plugin that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the project's dependencies. The plugin will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.</description>
<inceptionYear>2013</inceptionYear>
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
<distributionManagement>
@@ -150,6 +149,9 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<bottom>Copyright© 2012-14 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
@@ -239,7 +241,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<linkXref>true</linkXref>
<sourceEncoding>utf-8</sourceEncoding>
<excludes>
<exclude>**/generated/*.java</exclude>
<exclude>**/generated/**/*.java</exclude>
<exclude>**/HelpMojo.java</exclude>
</excludes>
<rulesets>
@@ -277,6 +279,11 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<artifactId>dependency-check-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>

View File

@@ -0,0 +1,462 @@
/*
* This file is part of dependency-check-maven.
*
* 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) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.maven;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.reporting.MavenReportException;
/**
* <p>
* This is an abstract reporting mojo that enables report aggregation. Some of the code in the this class was copied
* from the CoberturaReportMojo (http://mojo.codehaus.org/cobertura-maven-plugin/, version 2.6). The authors of the
* CoberturaReportMojo were <a href="will.gwaltney@sas.com">Will Gwaltney</a> and
* <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>. There working example of how to do report aggregation was
* invaluable.</p>
* <p>
* An important point about using this abstract class is that it is intended for one to write some form of serialized
* data (via the {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#writeDataFile() }; note that the
* <code>writeDataFile()</code> function is called automatically after either {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#executeNonAggregateReport(org.apache.maven.doxia.sink.Sink,
* org.apache.maven.doxia.sink.SinkFactory, java.util.Locale)
* } or {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#executeAggregateReport(org.apache.maven.doxia.sink.Sink,
* org.apache.maven.doxia.sink.SinkFactory, java.util.Locale)
* } are called. When <code>executeAggregateReport()</code> is implemented, one can call {@link org.owasp.dependencycheck.maven.ReportAggregationMojo#getChildDataFiles()
* } to obtain a list of the data files to aggregate.</p>
*
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
public abstract class ReportAggregationMojo extends AbstractMojo implements MavenReport {
/**
* The Maven Project Object.
*/
@Component
private MavenProject project;
/**
* Logger field reference.
*/
private static final Logger LOGGER = Logger.getLogger(ReportAggregationMojo.class.getName());
/**
* List of Maven project of the current build
*/
@Parameter(readonly = true, required = true, property = "reactorProjects")
private List<MavenProject> reactorProjects;
/**
* Generate aggregate reports in multi-module projects.
*/
@Parameter(property = "aggregate", defaultValue = "false")
private boolean aggregate;
/**
* Sets whether or not the external report format should be used.
*/
@Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true)
private String dataFileName;
/**
* Specifies the destination directory for the generated Dependency-Check report. This generally maps to
* "target/site".
*/
@Parameter(property = "reportOutputDirectory", defaultValue = "${project.reporting.outputDirectory}", required = true)
private File reportOutputDirectory;
/**
* Sets the Reporting output directory.
*
* @param directory the output directory
*/
@Override
public void setReportOutputDirectory(File directory) {
reportOutputDirectory = directory;
}
/**
* Returns the output directory.
*
* @return the output directory
*/
@Override
public File getReportOutputDirectory() {
return reportOutputDirectory;
}
/**
* Returns the output directory for the given project.
*
* @param project the Maven project to get the output directory for
* @return the output directory for the given project
*/
public File getReportOutputDirectory(MavenProject project) {
final Object o = project.getContextValue(getOutputDirectoryContextKey());
if (o != null && o instanceof File) {
return (File) o;
}
return null;
}
/**
* Returns whether this is an external report. This method always returns true.
*
* @return <code>true</code>
*/
@Override
public final boolean isExternalReport() {
return true;
}
/**
* The collection of child projects.
*/
private final Map<MavenProject, Set<MavenProject>> projectChildren = new HashMap<MavenProject, Set<MavenProject>>();
/**
* Called before execute; allows for any setup that is needed. If this is overridden you must call
* </code>super.preExecute()</code>.
*
* @throws MojoExecutionException thrown if there is an issue executing the mojo
* @throws MojoFailureException thrown if there is an issue executing the mojo
*/
protected void preExecute() throws MojoExecutionException, MojoFailureException {
buildAggregateInfo();
}
/**
* Called when the mojo is being executed.
*
* @throws MojoExecutionException thrown if there is an issue executing the mojo
* @throws MojoFailureException thrown if there is an issue executing the mojo
*/
protected abstract void performExecute() throws MojoExecutionException, MojoFailureException;
/**
* Runs after the mojo has executed. This implementation will call <code>writeDataFile()</code>. As such, it is
* important that if this method is overriden that <code>super.postExecute()</code> is called.
*
* @throws MojoExecutionException thrown if there is an issue executing the mojo
* @throws MojoFailureException thrown if there is an issue executing the mojo
*/
protected void postExecute() throws MojoExecutionException, MojoFailureException {
final File written = writeDataFile();
if (written != null) {
project.setContextValue(getDataFileContextKey(), written.getAbsolutePath());
}
}
/**
* Returns the key used to store the path to the data file that is saved by <code>writeDataFile()</code>. This key
* is used in the <code>MavenProject.(set|get)ContextValue</code>.
*
* @return the key used to store the path to the data file
*/
protected String getDataFileContextKey() {
return "dependency-check-path-" + this.getDataFileName();
}
/**
* Returns the key used to store the path to the output directory. When generating the report in the
* <code>executeAggregateReport()</code> the output directory should be obtained by using this key.
*
* @return the key used to store the path to the output directory
*/
protected String getOutputDirectoryContextKey() {
return "dependency-output-dir-" + this.getDataFileName();
}
/**
* Is called by Maven to execute the mojo.
*
* @throws MojoExecutionException thrown if there is an issue executing the mojo
* @throws MojoFailureException thrown if there is an issue executing the mojo
*/
public final void execute() throws MojoExecutionException, MojoFailureException {
try {
preExecute();
performExecute();
} finally {
postExecute();
}
}
/**
* Runs prior to the site report generation.
*
* @throws MavenReportException if a maven report exception occurs
*/
protected void preGenerate() throws MavenReportException {
buildAggregateInfo();
project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory());
}
/**
* Executes after the site report has been generated.
*
* @throws MavenReportException if a maven report exception occurs
*/
protected void postGenerate() throws MavenReportException {
final File written = writeDataFile();
if (written != null) {
project.setContextValue(getDataFileContextKey(), written.getAbsolutePath());
}
}
/**
* Generates the non aggregate report.
*
* @param locale the locale to use when generating the report
* @throws MavenReportException if a maven report exception occurs
*/
protected abstract void executeNonAggregateReport(Locale locale) throws MavenReportException;
/**
* Generates the aggregate Site Report.
*
* @param project the maven project used to generate the aggregate report
* @param locale the locale to use when generating the report
* @throws MavenReportException if a maven report exception occurs
*/
protected abstract void executeAggregateReport(MavenProject project, Locale locale) throws MavenReportException;
/**
* Generates the Dependency-Check Site Report.
*
* @param sink the sink to write the report to
* @param locale the locale to use when generating the report
* @throws MavenReportException if a maven report exception occurs
* @deprecated use {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale) instead.
*/
@Deprecated
public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException {
generate((Sink) sink, locale);
}
/**
* Generates the Dependency-Check Site Report.
*
* @param sink the sink to write the report to
* @param locale the locale to use when generating the report
* @throws MavenReportException if a maven report exception occurs
*/
public final void generate(Sink sink, Locale locale) throws MavenReportException {
try {
preGenerate();
if (canGenerateNonAggregateReport()) {
executeNonAggregateReport(locale);
}
if (canGenerateAggregateReport()) {
for (MavenProject proj : reactorProjects) {
if (!isMultiModule(proj)) {
continue;
}
executeAggregateReport(proj, locale);
}
}
} finally {
postGenerate();
}
}
/**
* Returns whether or not the mojo can generate a non-aggregate report for this project.
*
* @return <code>true</code> if a non-aggregate report can be generated, otherwise <code>false</code>
*/
protected abstract boolean canGenerateNonAggregateReport();
/**
* Returns whether or not we can generate any aggregate reports at this time.
*
* @return <code>true</code> if an aggregate report can be generated, otherwise <code>false</code>
*/
protected abstract boolean canGenerateAggregateReport();
/**
* Returns the name of the data file that contains the serialized data.
*
* @return the name of the data file that contains the serialized data
*/
protected String getDataFileName() {
return dataFileName;
}
/**
* Writes the data file to disk in the target directory.
*
* @return the File object referencing the data file that was written
*/
protected abstract File writeDataFile();
/**
* Collects the information needed for building aggregate reports.
*/
private void buildAggregateInfo() {
// build parent-child map
for (MavenProject proj : reactorProjects) {
Set<MavenProject> depList = projectChildren.get(proj.getParent());
if (depList == null) {
depList = new HashSet<MavenProject>();
projectChildren.put(proj.getParent(), depList);
}
depList.add(proj);
}
}
/**
* Returns a list containing all the recursive, non-pom children of the given project, never <code>null</code>.
*
* @return a list of child projects
*/
protected List<MavenProject> getAllChildren() {
return getAllChildren(project);
}
/**
* Returns a list containing all the recursive, non-pom children of the given project, never <code>null</code>.
*
* @param parentProject the parent project to collect the child project references
* @return a list of child projects
*/
protected List<MavenProject> getAllChildren(MavenProject parentProject) {
final Set<MavenProject> children = projectChildren.get(parentProject);
if (children == null) {
return Collections.emptyList();
}
final List<MavenProject> result = new ArrayList<MavenProject>();
for (MavenProject child : children) {
if (isMultiModule(child)) {
result.addAll(getAllChildren(child));
} else {
result.add(child);
}
}
return result;
}
/**
* Returns a list of data files that were produced by the direct children of the given MavenProject.
*
* @param project the Maven project to obtain the child data files from
* @return a list of the data files
*/
protected List<File> getAllChildDataFiles(MavenProject project) {
final List<MavenProject> children = getAllChildren(project);
return getDataFiles(children);
}
/**
* Returns any existing output files from the given list of projects.
*
* @param projects the list of projects to obtain the output files from
* @return a list of output files
*/
protected List<File> getDataFiles(List<MavenProject> projects) {
final List<File> files = new ArrayList<File>();
for (MavenProject proj : projects) {
final Object path = project.getContextValue(getDataFileContextKey());
if (path == null) {
final String msg = String.format("Unable to aggregate data for '%s' - aggregate data file was not generated",
proj.getName());
LOGGER.warning(msg);
} else {
final File outputFile = new File((String) path);
if (outputFile.exists()) {
files.add(outputFile);
} else {
if (!isMultiModule(project)) {
final String msg = String.format("Unable to aggregate data for '%s' - missing data file '%s'",
proj.getName(), outputFile.getPath());
LOGGER.warning(msg);
}
}
}
}
return files;
}
/**
* Test if the project has pom packaging
*
* @param mavenProject Project to test
* @return <code>true</code> if it has a pom packaging; otherwise <code>false</code>
*/
protected boolean isMultiModule(MavenProject mavenProject) {
return "pom".equals(mavenProject.getPackaging());
}
/**
* Test if the current project has pom packaging
*
* @return <code>true</code> if it has a pom packaging; otherwise <code>false</code>
*/
protected boolean isMultiModule() {
return isMultiModule(project);
}
/**
* Check whether the current project is the last project in a multi-module build. If the maven build is not a
* multi-module project then this will always return true.
*
* @return <code>true</code> if the current project is the last project in a multi-module build; otherwise
* <code>false</code>
*/
protected boolean isLastProject() {
return project.equals(reactorProjects.get(reactorProjects.size() - 1));
}
/**
* Returns whether or not the mojo is configured to perform report aggregation.
*
* @return <code>true</code> if report aggregation is enabled; otherwise <code>false</code>
*/
public boolean isAggregate() {
return aggregate;
}
/**
* Returns a reference to the current project. This method is used instead of auto-binding the project via component
* annotation in concrete implementations of this. If the child has a <code>@Component MavenProject project;</code>
* defined then the abstract class (i.e. this class) will not have access to the current project (just the way Maven
* works with the binding).
*
* @return returns a reference to the current project
*/
protected MavenProject getProject() {
return project;
}
}

View File

@@ -0,0 +1,456 @@
/*
* This file is part of dependency-check-maven.
*
* 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) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.maven;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.doxia.sink.Sink;
import org.owasp.dependencycheck.Engine;
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.dependency.Evidence;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Reference;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
import org.owasp.dependencycheck.reporting.ReportGenerator;
/**
* A utility class that encapsulates the report generation for dependency-check-maven.
*
* @author Jeremy Long <jeremy.long@owasp.org>
*/
final class ReportingUtil {
/**
* Logger field reference.
*/
private static final Logger LOGGER = Logger.getLogger(ReportingUtil.class.getName());
/**
* Empty private constructor for this utility class.
*/
private ReportingUtil() {
}
/**
* Generates the reports for a given dependency-check engine.
*
* @param engine a dependency-check engine
* @param outDirectory the directory to write the reports to
* @param projectName the name of the project that a report is being generated for
* @param format the format of the report to generate
*/
static void generateExternalReports(Engine engine, File outDirectory, String projectName, String format) {
DatabaseProperties prop = null;
CveDB cve = null;
try {
cve = new CveDB();
cve.open();
prop = cve.getDatabaseProperties();
} catch (DatabaseException ex) {
LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex);
} finally {
if (cve != null) {
cve.close();
}
}
final ReportGenerator r = new ReportGenerator(projectName, engine.getDependencies(), engine.getAnalyzers(), prop);
try {
r.generateReports(outDirectory.getCanonicalPath(), format);
} catch (IOException ex) {
LOGGER.log(Level.SEVERE,
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
LOGGER.log(Level.FINE, null, ex);
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE,
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
LOGGER.log(Level.FINE, null, ex);
}
}
/**
* Generates a dependency-check report using the Maven Site format.
*
* @param engine the engine used to scan the dependencies
* @param sink the sink to write the data to
* @param projectName the name of the project
*/
static void generateMavenSiteReport(final Engine engine, Sink sink, String projectName) {
final List<Dependency> dependencies = engine.getDependencies();
writeSiteReportHeader(sink, projectName);
writeSiteReportTOC(sink, dependencies);
int cnt = 0;
for (Dependency d : dependencies) {
writeSiteReportDependencyHeader(sink, d);
cnt = writeSiteReportDependencyEvidenceUsed(d, cnt, sink);
cnt = writeSiteReportDependencyRelatedDependencies(d, cnt, sink);
writeSiteReportDependencyIdentifiers(d, sink);
writeSiteReportDependencyVulnerabilities(d, sink, cnt);
}
sink.body_();
}
// <editor-fold defaultstate="collapsed" desc="various writeXXXXX methods to generate the Site Report">
/**
* Writes the vulnerabilities to the site report.
*
* @param d the dependency
* @param sink the sink to write the data to
* @param collapsibleHeaderCount the collapsible header count
*/
private static void writeSiteReportDependencyVulnerabilities(Dependency d, Sink sink, int collapsibleHeaderCount) {
int cnt = collapsibleHeaderCount;
if (d.getVulnerabilities() != null && !d.getVulnerabilities().isEmpty()) {
for (Vulnerability v : d.getVulnerabilities()) {
sink.paragraph();
sink.bold();
try {
sink.link("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + URLEncoder.encode(v.getName(), "US-ASCII"));
sink.text(v.getName());
sink.link_();
sink.bold_();
} catch (UnsupportedEncodingException ex) {
sink.text(v.getName());
sink.bold_();
sink.lineBreak();
sink.text("http://web.nvd.nist.gov/view/vuln/detail?vulnId=" + v.getName());
}
sink.paragraph_();
sink.paragraph();
sink.text("Severity: ");
if (v.getCvssScore() < 4.0) {
sink.text("Low");
} else {
if (v.getCvssScore() >= 7.0) {
sink.text("High");
} else {
sink.text("Medium");
}
}
sink.lineBreak();
sink.text("CVSS Score: " + v.getCvssScore());
if (v.getCwe() != null && !v.getCwe().isEmpty()) {
sink.lineBreak();
sink.text("CWE: ");
sink.text(v.getCwe());
}
sink.paragraph_();
sink.paragraph();
sink.text(v.getDescription());
if (v.getReferences() != null && !v.getReferences().isEmpty()) {
sink.list();
for (Reference ref : v.getReferences()) {
sink.listItem();
sink.text(ref.getSource());
sink.text(" - ");
sink.link(ref.getUrl());
sink.text(ref.getName());
sink.link_();
sink.listItem_();
}
sink.list_();
}
sink.paragraph_();
if (v.getVulnerableSoftware() != null && !v.getVulnerableSoftware().isEmpty()) {
sink.paragraph();
cnt += 1;
sink.rawText("Vulnerable Software <a href=\"javascript:toggleElement(this, 'vulnSoft" + cnt + "')\">[-]</a>");
sink.rawText("<div id=\"vulnSoft" + cnt + "\" style=\"display:block\">");
sink.list();
for (VulnerableSoftware vs : v.getVulnerableSoftware()) {
sink.listItem();
try {
sink.link("http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + URLEncoder.encode(vs.getName(), "US-ASCII"));
sink.text(vs.getName());
sink.link_();
if (vs.hasPreviousVersion()) {
sink.text(" and all previous versions.");
}
} catch (UnsupportedEncodingException ex) {
sink.text(vs.getName());
if (vs.hasPreviousVersion()) {
sink.text(" and all previous versions.");
}
sink.text(" (http://web.nvd.nist.gov/view/vuln/search-results?cpe=" + vs.getName() + ")");
}
sink.listItem_();
}
sink.list_();
sink.rawText("</div>");
sink.paragraph_();
}
}
}
}
/**
* Writes the identifiers to the site report.
*
* @param d the dependency
* @param sink the sink to write the data to
*/
private static void writeSiteReportDependencyIdentifiers(Dependency d, Sink sink) {
if (d.getIdentifiers() != null && !d.getIdentifiers().isEmpty()) {
sink.sectionTitle4();
sink.text("Identifiers");
sink.sectionTitle4_();
sink.list();
for (Identifier i : d.getIdentifiers()) {
sink.listItem();
sink.text(i.getType());
sink.text(": ");
if (i.getUrl() != null && i.getUrl().length() > 0) {
sink.link(i.getUrl());
sink.text(i.getValue());
sink.link_();
} else {
sink.text(i.getValue());
}
if (i.getDescription() != null && i.getDescription().length() > 0) {
sink.lineBreak();
sink.text(i.getDescription());
}
sink.listItem_();
}
sink.list_();
}
}
/**
* Writes the related dependencies to the site report.
*
* @param d the dependency
* @param sink the sink to write the data to
* @param collapsibleHeaderCount the collapsible header count
* @return the collapsible header count
*/
private static int writeSiteReportDependencyRelatedDependencies(Dependency d, int collapsibleHeaderCount, Sink sink) {
int cnt = collapsibleHeaderCount;
if (d.getRelatedDependencies() != null && !d.getRelatedDependencies().isEmpty()) {
cnt += 1;
sink.sectionTitle4();
sink.rawText("Related Dependencies <a href=\"javascript:toggleElement(this, 'related" + cnt + "')\">[+]</a>");
sink.sectionTitle4_();
sink.rawText("<div id=\"related" + cnt + "\" style=\"display:none\">");
sink.list();
for (Dependency r : d.getRelatedDependencies()) {
sink.listItem();
sink.text(r.getFileName());
sink.list();
writeListItem(sink, "File Path: " + r.getFilePath());
writeListItem(sink, "SHA1: " + r.getSha1sum());
writeListItem(sink, "MD5: " + r.getMd5sum());
sink.list_();
sink.listItem_();
}
sink.list_();
sink.rawText("</div>");
}
return cnt;
}
/**
* Writes the evidence used to the site report.
*
* @param d the dependency
* @param sink the sink to write the data to
* @param collapsibleHeaderCount the collapsible header count
* @return the collapsible header count
*/
private static int writeSiteReportDependencyEvidenceUsed(Dependency d, int collapsibleHeaderCount, Sink sink) {
int cnt = collapsibleHeaderCount;
final Set<Evidence> evidence = d.getEvidenceForDisplay();
if (evidence != null && evidence.size() > 0) {
cnt += 1;
sink.sectionTitle4();
sink.rawText("Evidence Collected <a href=\"javascript:toggleElement(this, 'evidence" + cnt + "')\">[+]</a>");
sink.sectionTitle4_();
sink.rawText("<div id=\"evidence" + cnt + "\" style=\"display:none\">");
sink.table();
sink.tableRow();
writeTableHeaderCell(sink, "Source");
writeTableHeaderCell(sink, "Name");
writeTableHeaderCell(sink, "Value");
sink.tableRow_();
for (Evidence e : evidence) {
sink.tableRow();
writeTableCell(sink, e.getSource());
writeTableCell(sink, e.getName());
writeTableCell(sink, e.getValue());
sink.tableRow_();
}
sink.table_();
sink.rawText("</div>");
}
return cnt;
}
/**
* Writes the dependency header to the site report.
*
* @param d the dependency
* @param sink the sink to write the data to
*/
private static void writeSiteReportDependencyHeader(Sink sink, Dependency d) {
sink.sectionTitle2();
sink.anchor("sha1" + d.getSha1sum());
sink.text(d.getFileName());
sink.anchor_();
sink.sectionTitle2_();
if (d.getDescription() != null && d.getDescription().length() > 0) {
sink.paragraph();
sink.bold();
sink.text("Description: ");
sink.bold_();
sink.text(d.getDescription());
sink.paragraph_();
}
if (d.getLicense() != null && d.getLicense().length() > 0) {
sink.paragraph();
sink.bold();
sink.text("License: ");
sink.bold_();
if (d.getLicense().startsWith("http://") && !d.getLicense().contains(" ")) {
sink.link(d.getLicense());
sink.text(d.getLicense());
sink.link_();
} else {
sink.text(d.getLicense());
}
sink.paragraph_();
}
}
/**
* Adds a list item to the site report.
*
* @param sink the sink to write the data to
* @param text the text to write
*/
private static void writeListItem(Sink sink, String text) {
sink.listItem();
sink.text(text);
sink.listItem_();
}
/**
* Adds a table cell to the site report.
*
* @param sink the sink to write the data to
* @param text the text to write
*/
private static void writeTableCell(Sink sink, String text) {
sink.tableCell();
sink.text(text);
sink.tableCell_();
}
/**
* Adds a table header cell to the site report.
*
* @param sink the sink to write the data to
* @param text the text to write
*/
private static void writeTableHeaderCell(Sink sink, String text) {
sink.tableHeaderCell();
sink.text(text);
sink.tableHeaderCell_();
}
/**
* Writes the TOC for the site report.
*
* @param sink the sink to write the data to
* @param dependencies the dependencies that are being reported on
*/
private static void writeSiteReportTOC(Sink sink, final List<Dependency> dependencies) {
sink.list();
for (Dependency d : dependencies) {
sink.listItem();
sink.link("#sha1" + d.getSha1sum());
sink.text(d.getFileName());
sink.link_();
if (!d.getVulnerabilities().isEmpty()) {
sink.rawText(" <font style=\"color:red\">•</font>");
}
if (!d.getRelatedDependencies().isEmpty()) {
sink.list();
for (Dependency r : d.getRelatedDependencies()) {
writeListItem(sink, r.getFileName());
}
sink.list_();
}
sink.listItem_();
}
sink.list_();
}
/**
* Writes the site report header.
*
* @param sink the sink to write the data to
* @param projectName the name of the project
*/
private static void writeSiteReportHeader(Sink sink, String projectName) {
sink.head();
sink.title();
sink.text("Dependency-Check Report: " + projectName);
sink.title_();
sink.head_();
sink.body();
sink.rawText("<script type=\"text/javascript\">");
sink.rawText("function toggleElement(el, targetId) {");
sink.rawText("if (el.innerText == '[+]') {");
sink.rawText(" el.innerText = '[-]';");
sink.rawText(" document.getElementById(targetId).style.display='block';");
sink.rawText("} else {");
sink.rawText(" el.innerText = '[+]';");
sink.rawText(" document.getElementById(targetId).style.display='none';");
sink.rawText("}");
sink.rawText("}");
sink.rawText("</script>");
sink.section1();
sink.sectionTitle1();
sink.text("Project: " + projectName);
sink.sectionTitle1_();
sink.date();
final Date now = new Date();
sink.text(DateFormat.getDateTimeInstance().format(now));
sink.date_();
sink.section1_();
}
// </editor-fold>
}

View File

@@ -4,8 +4,8 @@ The following properties can be set on the dependency-check-maven plugin.
Property | Description | Default Value
---------------------|------------------------------------|------------------
aggregate | Sets whether report aggregation will be performed for multi-module site reports. This option only affects the report generation when configured within the reporting section. | false
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
outputDirectory | 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
format | 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
@@ -23,49 +23,44 @@ 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
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 Jar Analyzer will be used. | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
nexusUrl | Defines the Nexus Pro Server URL. 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;
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
====================
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 | http://nvd.nist.gov/download/nvdcve-modified.xml
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
connectionTimeout | The URL Connection Timeout. | &nbsp;
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. | &nbsp;
Property | Description | Default Value
---------------------|--------------------------------------------------------------------------|------------------
cveUrl12Modified | URL for the modified CVE 1.2. | http://nvd.nist.gov/download/nvdcve-modified.xml
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
connectionTimeout | Sets the URL Connection Timeout used when downloading external data. | &nbsp;
dataDirectory | Sets the data directory to hold SQL CVEs contents. This should generally not be changed. | &nbsp;
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;
metaFileName | Sets the name of the file to use for storing the metadata about the project. | dependency-check.ser
Deprecated Configuration
Proxy Configuration
====================
The following properties have been deprecated. These can still be set in
the dependency-check-maven plugin's configuration. However, future versions
will remove these properties. Instead using these properties you should
use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to
configure a proxy.
Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server. If multiple proxies
are configured in the Maven settings file you must tell dependency-check which proxy to use with the following property:
Property | Description | Default Value
---------------------|--------------------------------------------------------------------------------------|------------------
mavenSettingsProxyId | The id for the proxy, configured via settings.xml, that dependency-check should use. | &nbsp;
Property | Description | Default Value
---------------------|------------------------------------|------------------
proxyUrl | The Proxy URL. | &nbsp;
proxyPort | The Proxy Port. | &nbsp;
proxyUsername | Defines the proxy user name. | &nbsp;
proxyPassword | Defines the proxy password. | &nbsp;

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