##### Coverage Report - org.owasp.dependencycheck.analyzer.NvdCveAnalyzer

Classes in this File | Line Coverage | Branch Coverage | Complexity
NvdCveAnalyzer |
74% | 20/27
37% | 3/8
| 1.5;1.5

1 |  |
     /*
2 |  |
      * This file is part of dependency-check-core.
3 |  |
      *
4 |  |
      * Dependency-check-core is free software: you can redistribute it and/or modify it
5 |  |
      * under the terms of the GNU General Public License as published by the Free
6 |  |
      * Software Foundation, either version 3 of the License, or (at your option) any
7 |  |
      * later version.
8 |  |
      *
9 |  |
      * Dependency-check-core is distributed in the hope that it will be useful, but
10 |  |
      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 |  |
      * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 |  |
      * details.
13 |  |
      *
14 |  |
      * You should have received a copy of the GNU General Public License along with
15 |  |
      * dependency-check-core. If not, see http://www.gnu.org/licenses/.
16 |  |
      *
17 |  |
      * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
18 |  |
      */
19 |  |
     package org.owasp.dependencycheck.analyzer;
20 |  |
21 |  |
     import java.io.IOException;
22 |  |
     import java.sql.SQLException;
23 |  |
     import java.util.List;
24 |  |
     import java.util.Set;
25 |  |
     import org.owasp.dependencycheck.Engine;
26 |  |
     import org.owasp.dependencycheck.dependency.Dependency;
27 |  |
     import org.owasp.dependencycheck.dependency.Vulnerability;
28 |  |
     import org.owasp.dependencycheck.dependency.Identifier;
29 |  |
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
30 |  |
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
31 |  |
32 |  |
     /**
33 |  |
      * NvdCveAnalyzer is a utility class that takes a project dependency and
34 |  |
      * attempts to discern if there is an associated CVEs. It uses the the
35 |  |
      * identifiers found by other analyzers to lookup the CVE data.
36 |  |
      *
37 |  |
      * @author Jeremy Long (jeremy.long@owasp.org)
38 |  |
      */
39 | 1 |
     public class NvdCveAnalyzer implements Analyzer {
40 |  |
41 |  |
         /**
42 |  |
          * The maximum number of query results to return.
43 |  |
          */
44 |  |
         static final int MAX_QUERY_RESULTS = 100;
45 |  |
         /**
46 |  |
          * The CVE Index.
47 |  |
          */
48 |  |
         private CveDB cveDB;
49 |  |
50 |  |
         /**
51 |  |
          * Opens the data source.
52 |  |
          *
53 |  |
          * @throws SQLException thrown when there is a SQL Exception
54 |  |
          * @throws IOException thrown when there is an IO Exception
55 |  |
          * @throws DatabaseException thrown when there is a database exceptions
56 |  |
          * @throws ClassNotFoundException thrown if the h2 database driver cannot be
57 |  |
          * loaded
58 |  |
          */
59 |  |
         public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
60 | 3 |
             cveDB = new CveDB();
61 | 3 |
             cveDB.open();
62 | 3 |
         }
63 |  |
64 |  |
         /**
65 |  |
          * Closes the data source.
66 |  |
          */
67 |  |
         public void close() {
68 | 3 |
             cveDB.close();
69 | 3 |
             cveDB = null;
70 | 3 |
         }
71 |  |
72 |  |
         /**
73 |  |
          * Returns the status of the data source - is the database open.
74 |  |
          *
75 |  |
          * @return true or false.
76 |  |
          */
77 |  |
         public boolean isOpen() {
78 | 0 |
             return (cveDB != null);
79 |  |
         }
80 |  |
81 |  |
         /**
82 |  |
          * Ensures that the CVE Database is closed.
83 |  |
          *
84 |  |
          * @throws Throwable when a throwable is thrown.
85 |  |
          */
86 |  |
         @Override
87 |  |
         protected void finalize() throws Throwable {
88 | 0 |
             super.finalize();
89 | 0 |
             if (isOpen()) {
90 | 0 |
                 close();
91 |  |
             }
92 | 0 |
         }
93 |  |
94 |  |
         /**
95 |  |
          * Analyzes a dependency and attempts to determine if there are any CPE
96 |  |
          * identifiers for this dependency.
97 |  |
          *
98 |  |
          * @param dependency The Dependency to analyze
99 |  |
          * @param engine The analysis engine
100 |  |
          * @throws AnalysisException is thrown if there is an issue analyzing the
101 |  |
          * dependency
102 |  |
          */
103 |  |
         public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
104 | 9 |
             for (Identifier id : dependency.getIdentifiers()) {
105 | 11 |
                 if ("cpe".equals(id.getType())) {
106 |  |
                     try {
107 | 11 |
                         final String value = id.getValue();
108 | 11 |
                         final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
109 | 11 |
                         dependency.getVulnerabilities().addAll(vulns);
110 |  |
     //TODO - remove this comment block after additional testing is completed
111 |  |
     //note - valid match functionality has been moved into the CveDB class.
112 |  |
     ////                    for (Vulnerability v : vulns) {
113 |  |
     ////                        if (isValidMatch(dependency, v)) {
114 |  |
     ////                            dependency.addVulnerability(v);
115 |  |
     ////                        }
116 |  |
     ////                    }
117 | 0 |
                     } catch (DatabaseException ex) {
118 | 0 |
                         throw new AnalysisException(ex);
119 | 11 |
                     }
120 |  |
                 }
121 |  |
             }
122 | 9 |
         }
123 |  |
124 |  |
         /**
125 |  |
          * Returns true because this analyzer supports all dependency types.
126 |  |
          *
127 |  |
          * @return true.
128 |  |
          */
129 |  |
         public Set<String> getSupportedExtensions() {
130 | 132 |
             return null;
131 |  |
         }
132 |  |
133 |  |
         /**
134 |  |
          * Returns the name of this analyzer.
135 |  |
          *
136 |  |
          * @return the name of this analyzer.
137 |  |
          */
138 |  |
         public String getName() {
139 | 9 |
             return "NVD CVE Analyzer";
140 |  |
         }
141 |  |
142 |  |
         /**
143 |  |
          * Returns true because this analyzer supports all dependency types.
144 |  |
          *
145 |  |
          * @param extension the file extension of the dependency being analyzed.
146 |  |
          * @return true.
147 |  |
          */
148 |  |
         public boolean supportsExtension(String extension) {
149 | 9 |
             return true;
150 |  |
         }
151 |  |
152 |  |
         /**
153 |  |
          * Returns the analysis phase that this analyzer should run in.
154 |  |
          *
155 |  |
          * @return the analysis phase that this analyzer should run in.
156 |  |
          */
157 |  |
         public AnalysisPhase getAnalysisPhase() {
158 | 6 |
             return AnalysisPhase.FINDING_ANALYSIS;
159 |  |
         }
160 |  |
161 |  |
         /**
162 |  |
          * Opens the NVD CVE Lucene Index.
163 |  |
          *
164 |  |
          * @throws Exception is thrown if there is an issue opening the index.
165 |  |
          */
166 |  |
         public void initialize() throws Exception {
167 | 3 |
             this.open();
168 | 3 |
         }
169 |  |
     //TODO - remove this comment block after additional testing is completed
170 |  |
     // The following check has been moved into the CveDB class.
171 |  |
     ////    /**
172 |  |
     ////     * <p>Determines if this is a valid vulnerability match for the given
173 |  |
     ////     * dependency. Specifically, this is concerned with ensuring the version
174 |  |
     ////     * numbers are correct.</p>
175 |  |
     ////     * <p>Currently, this is focused on the issues with the versions for Struts
176 |  |
     ////     * 1 and Struts 2. In the future this will due better matching on more
177 |  |
     ////     * version numbers.</p>
178 |  |
     ////     *
179 |  |
     ////     * @param dependency the dependency
180 |  |
     ////     * @param v the vulnerability
181 |  |
     ////     * @return returns true if the vulnerability is for the given dependency
182 |  |
     ////     */
183 |  |
     ////    private boolean isValidMatch(final Dependency dependency, final Vulnerability v) {
184 |  |
     ////        //right now I only know of the issue with Struts1/2
185 |  |
     ////        // start with fixing this problem.
186 |  |
     ////
187 |  |
     ////        //TODO extend this solution to do better version matching for the vulnerable software.
188 |  |
     ////        boolean struts1 = false;
189 |  |
     ////        boolean struts2 = false;
190 |  |
     ////        for (Identifier i : dependency.getIdentifiers()) {
191 |  |
     ////            if (i.getValue().startsWith("cpe:/a:apache:struts:")) {
192 |  |
     ////                final char version = i.getValue().charAt(21);
193 |  |
     ////                if (version == '1') {
194 |  |
     ////                    struts1 = true;
195 |  |
     ////                }
196 |  |
     ////                if (version == '2') {
197 |  |
     ////                    struts2 = true;
198 |  |
     ////                }
199 |  |
     ////            }
200 |  |
     ////        }
201 |  |
     ////        if (!struts1 && !struts2) {
202 |  |
     ////            return true; //we are not looking at struts, so return true.
203 |  |
     ////        }
204 |  |
     ////        if (struts1 && struts2) {
205 |  |
     ////            return true; //there is a mismatch here, but we can't solve it here so we return valid.
206 |  |
     ////        }
207 |  |
     ////        if (struts1) {
208 |  |
     ////            boolean hasStruts1Vuln = false;
209 |  |
     ////            boolean hasStruts2PreviousVersion = false;
210 |  |
     ////            for (VulnerableSoftware vs : v.getVulnerableSoftware()) {
211 |  |
     ////                //TODO FIX THIS
212 |  |
     ////                //hasStruts2PreviousVersion |= vs.hasPreviousVersion() && vs.getName().charAt(21) == '2';
213 |  |
     ////                //hasStruts1Vuln |= vs.getName().charAt(21) == '1';
214 |  |
     ////            }
215 |  |
     ////            if (!hasStruts1Vuln && hasStruts2PreviousVersion) {
216 |  |
     ////                return false;
217 |  |
     ////            }
218 |  |
     ////        }
219 |  |
     ////
220 |  |
     ////        return true;
221 |  |
     ////    }
222 |  |
     }