Coverage Report - org.owasp.dependencycheck.analyzer.NodePackageAnalyzer
 
Classes in this File Line Coverage Branch Coverage Complexity
NodePackageAnalyzer
86%
46/53
64%
9/14
2.429
 
 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) 2015 Institute for Defense Analyses. All Rights Reserved.
 17  
  */
 18  
 package org.owasp.dependencycheck.analyzer;
 19  
 
 20  
 import org.apache.commons.io.FileUtils;
 21  
 import org.owasp.dependencycheck.Engine;
 22  
 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
 23  
 import org.owasp.dependencycheck.dependency.Confidence;
 24  
 import org.owasp.dependencycheck.dependency.Dependency;
 25  
 import org.owasp.dependencycheck.dependency.EvidenceCollection;
 26  
 import org.owasp.dependencycheck.utils.FileFilterBuilder;
 27  
 import org.owasp.dependencycheck.utils.Settings;
 28  
 import org.slf4j.Logger;
 29  
 import org.slf4j.LoggerFactory;
 30  
 
 31  
 import java.io.File;
 32  
 import java.io.FileFilter;
 33  
 import java.io.IOException;
 34  
 import java.util.Map;
 35  
 import javax.json.Json;
 36  
 import javax.json.JsonException;
 37  
 import javax.json.JsonObject;
 38  
 import javax.json.JsonReader;
 39  
 import javax.json.JsonString;
 40  
 import javax.json.JsonValue;
 41  
 
 42  
 /**
 43  
  * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the
 44  
  * associated CPE.
 45  
  *
 46  
  * @author Dale Visser
 47  
  */
 48  7
 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
 49  
 
 50  
     /**
 51  
      * The logger.
 52  
      */
 53  1
     private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
 54  
 
 55  
     /**
 56  
      * The name of the analyzer.
 57  
      */
 58  
     private static final String ANALYZER_NAME = "Node.js Package Analyzer";
 59  
 
 60  
     /**
 61  
      * The phase that this analyzer is intended to run in.
 62  
      */
 63  1
     private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
 64  
 
 65  
     /**
 66  
      * The file name to scan.
 67  
      */
 68  
     public static final String PACKAGE_JSON = "package.json";
 69  
     /**
 70  
      * Filter that detects files named "package.json".
 71  
      */
 72  2
     private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
 73  1
             .addFilenames(PACKAGE_JSON).build();
 74  
 
 75  
     /**
 76  
      * Returns the FileFilter
 77  
      *
 78  
      * @return the FileFilter
 79  
      */
 80  
     @Override
 81  
     protected FileFilter getFileFilter() {
 82  854
         return PACKAGE_JSON_FILTER;
 83  
     }
 84  
 
 85  
     @Override
 86  
     protected void initializeFileTypeAnalyzer() throws Exception {
 87  
         // NO-OP
 88  3
     }
 89  
 
 90  
     /**
 91  
      * Returns the name of the analyzer.
 92  
      *
 93  
      * @return the name of the analyzer.
 94  
      */
 95  
     @Override
 96  
     public String getName() {
 97  5
         return ANALYZER_NAME;
 98  
     }
 99  
 
 100  
     /**
 101  
      * Returns the phase that the analyzer is intended to run in.
 102  
      *
 103  
      * @return the phase that the analyzer is intended to run in.
 104  
      */
 105  
     @Override
 106  
     public AnalysisPhase getAnalysisPhase() {
 107  3
         return ANALYSIS_PHASE;
 108  
     }
 109  
 
 110  
     /**
 111  
      * Returns the key used in the properties file to reference the analyzer's enabled property.
 112  
      *
 113  
      * @return the analyzer's enabled property setting key
 114  
      */
 115  
     @Override
 116  
     protected String getAnalyzerEnabledSettingKey() {
 117  7
         return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
 118  
     }
 119  
 
 120  
     @Override
 121  
     protected void analyzeFileType(Dependency dependency, Engine engine)
 122  
             throws AnalysisException {
 123  1
         final File file = dependency.getActualFile();
 124  
         JsonReader jsonReader;
 125  
         try {
 126  1
             jsonReader = Json.createReader(FileUtils.openInputStream(file));
 127  0
         } catch (IOException e) {
 128  0
             throw new AnalysisException(
 129  
                     "Problem occurred while reading dependency file.", e);
 130  1
         }
 131  
         try {
 132  1
             final JsonObject json = jsonReader.readObject();
 133  1
             final EvidenceCollection productEvidence = dependency.getProductEvidence();
 134  1
             final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
 135  1
             if (json.containsKey("name")) {
 136  1
                 final Object value = json.get("name");
 137  1
                 if (value instanceof JsonString) {
 138  1
                     final String valueString = ((JsonString) value).getString();
 139  1
                     productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
 140  1
                     vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
 141  1
                 } else {
 142  0
                     LOGGER.warn("JSON value not string as expected: {}", value);
 143  
                 }
 144  
             }
 145  1
             addToEvidence(json, productEvidence, "description");
 146  1
             addToEvidence(json, vendorEvidence, "author");
 147  1
             addToEvidence(json, dependency.getVersionEvidence(), "version");
 148  1
             dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
 149  0
         } catch (JsonException e) {
 150  0
             LOGGER.warn("Failed to parse package.json file.", e);
 151  
         } finally {
 152  1
             jsonReader.close();
 153  1
         }
 154  1
     }
 155  
 
 156  
     /**
 157  
      * Adds information to an evidence collection from the node json configuration.
 158  
      *
 159  
      * @param json information from node.js
 160  
      * @param collection a set of evidence about a dependency
 161  
      * @param key the key to obtain the data from the json information
 162  
      */
 163  
     private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
 164  3
         if (json.containsKey(key)) {
 165  3
             final JsonValue value = json.get(key);
 166  3
             if (value instanceof JsonString) {
 167  2
                 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
 168  1
             } else if (value instanceof JsonObject) {
 169  1
                 final JsonObject jsonObject = (JsonObject) value;
 170  1
                 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
 171  1
                     final String property = entry.getKey();
 172  1
                     final JsonValue subValue = entry.getValue();
 173  1
                     if (subValue instanceof JsonString) {
 174  2
                         collection.addEvidence(PACKAGE_JSON,
 175  1
                                 String.format("%s.%s", key, property),
 176  1
                                 ((JsonString) subValue).getString(),
 177  
                                 Confidence.HIGHEST);
 178  
                     } else {
 179  0
                         LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
 180  
                     }
 181  1
                 }
 182  1
             } else {
 183  0
                 LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
 184  
             }
 185  
         }
 186  3
     }
 187  
 }