View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.analyzer;
19  
20  import java.io.IOException;
21  import java.sql.SQLException;
22  import java.util.List;
23  import org.owasp.dependencycheck.Engine;
24  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
25  import org.owasp.dependencycheck.data.nvdcve.CveDB;
26  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
27  import org.owasp.dependencycheck.dependency.Dependency;
28  import org.owasp.dependencycheck.dependency.Identifier;
29  import org.owasp.dependencycheck.dependency.Vulnerability;
30  import org.owasp.dependencycheck.exception.InitializationException;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated
35   * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data.
36   *
37   * @author Jeremy Long
38   */
39  public class NvdCveAnalyzer extends AbstractAnalyzer {
40      /**
41       * The Logger for use throughout the class
42       */
43      private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(NvdCveAnalyzer.class);
44      /**
45       * The maximum number of query results to return.
46       */
47      static final int MAX_QUERY_RESULTS = 100;
48      /**
49       * The CVE Index.
50       */
51      private CveDB cveDB;
52  
53      /**
54       * Opens the data source.
55       *
56       * @throws SQLException thrown when there is a SQL Exception
57       * @throws IOException thrown when there is an IO Exception
58       * @throws DatabaseException thrown when there is a database exceptions
59       * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded
60       */
61      public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
62          cveDB = new CveDB();
63          cveDB.open();
64      }
65  
66      /**
67       * Closes the data source.
68       */
69      @Override
70      public void close() {
71          cveDB.close();
72          cveDB = null;
73      }
74  
75      /**
76       * Returns the status of the data source - is the database open.
77       *
78       * @return true or false.
79       */
80      public boolean isOpen() {
81          return cveDB != null;
82      }
83  
84      /**
85       * Ensures that the CVE Database is closed.
86       *
87       * @throws Throwable an exception raised by this method
88       */
89      @Override
90      protected void finalize() throws Throwable {
91          super.finalize();
92          if (isOpen()) {
93              close();
94          }
95      }
96  
97      /**
98       * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
99       *
100      * @param dependency The Dependency to analyze
101      * @param engine The analysis engine
102      * @throws AnalysisException thrown if there is an issue analyzing the dependency
103      */
104     @Override
105     public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
106         for (Identifier id : dependency.getIdentifiers()) {
107             if ("cpe".equals(id.getType())) {
108                 try {
109                     final String value = id.getValue();
110                     final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
111                     dependency.getVulnerabilities().addAll(vulns);
112                 } catch (DatabaseException ex) {
113                     throw new AnalysisException(ex);
114                 }
115             }
116         }
117         for (Identifier id : dependency.getSuppressedIdentifiers()) {
118             if ("cpe".equals(id.getType())) {
119                 try {
120                     final String value = id.getValue();
121                     final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
122                     dependency.getSuppressedVulnerabilities().addAll(vulns);
123                 } catch (DatabaseException ex) {
124                     throw new AnalysisException(ex);
125                 }
126             }
127         }
128     }
129 
130     /**
131      * Returns the name of this analyzer.
132      *
133      * @return the name of this analyzer.
134      */
135     @Override
136     public String getName() {
137         return "NVD CVE Analyzer";
138     }
139 
140     /**
141      * Returns the analysis phase that this analyzer should run in.
142      *
143      * @return the analysis phase that this analyzer should run in.
144      */
145     @Override
146     public AnalysisPhase getAnalysisPhase() {
147         return AnalysisPhase.FINDING_ANALYSIS;
148     }
149 
150     /**
151      * Opens the database used to gather NVD CVE data.
152      *
153      * @throws InitializationException is thrown if there is an issue opening the index.
154      */
155     @Override
156     public void initialize() throws InitializationException {
157         try {
158             this.open();
159         } catch (SQLException ex) {
160             LOGGER.debug("SQL Exception initializing NvdCveAnalyzer", ex);
161             throw new InitializationException(ex);
162         } catch (IOException ex) {
163             LOGGER.debug("IO Exception initializing NvdCveAnalyzer", ex);
164             throw new InitializationException(ex);
165         } catch (DatabaseException ex) {
166             LOGGER.debug("Database Exception initializing NvdCveAnalyzer", ex);
167             throw new InitializationException(ex);
168         } catch (ClassNotFoundException ex) {
169             LOGGER.debug("Exception initializing NvdCveAnalyzer", ex);
170             throw new InitializationException(ex);
171         }
172     }
173 }