1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
44
45
46
47
48 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
49
50
51
52
53 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
54
55
56
57
58 private static final String ANALYZER_NAME = "Node.js Package Analyzer";
59
60
61
62
63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
64
65
66
67
68 public static final String PACKAGE_JSON = "package.json";
69
70
71
72 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
73 .addFilenames(PACKAGE_JSON).build();
74
75
76
77
78
79
80 @Override
81 protected FileFilter getFileFilter() {
82 return PACKAGE_JSON_FILTER;
83 }
84
85 @Override
86 protected void initializeFileTypeAnalyzer() throws Exception {
87
88 }
89
90
91
92
93
94
95 @Override
96 public String getName() {
97 return ANALYZER_NAME;
98 }
99
100
101
102
103
104
105 @Override
106 public AnalysisPhase getAnalysisPhase() {
107 return ANALYSIS_PHASE;
108 }
109
110
111
112
113
114
115 @Override
116 protected String getAnalyzerEnabledSettingKey() {
117 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
118 }
119
120 @Override
121 protected void analyzeFileType(Dependency dependency, Engine engine)
122 throws AnalysisException {
123 final File file = dependency.getActualFile();
124 JsonReader jsonReader;
125 try {
126 jsonReader = Json.createReader(FileUtils.openInputStream(file));
127 } catch (IOException e) {
128 throw new AnalysisException(
129 "Problem occurred while reading dependency file.", e);
130 }
131 try {
132 final JsonObject json = jsonReader.readObject();
133 final EvidenceCollection productEvidence = dependency.getProductEvidence();
134 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
135 if (json.containsKey("name")) {
136 final Object value = json.get("name");
137 if (value instanceof JsonString) {
138 final String valueString = ((JsonString) value).getString();
139 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
140 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
141 } else {
142 LOGGER.warn("JSON value not string as expected: {}", value);
143 }
144 }
145 addToEvidence(json, productEvidence, "description");
146 addToEvidence(json, vendorEvidence, "author");
147 addToEvidence(json, dependency.getVersionEvidence(), "version");
148 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
149 } catch (JsonException e) {
150 LOGGER.warn("Failed to parse package.json file.", e);
151 } finally {
152 jsonReader.close();
153 }
154 }
155
156
157
158
159
160
161
162
163 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
164 if (json.containsKey(key)) {
165 final JsonValue value = json.get(key);
166 if (value instanceof JsonString) {
167 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
168 } else if (value instanceof JsonObject) {
169 final JsonObject jsonObject = (JsonObject) value;
170 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
171 final String property = entry.getKey();
172 final JsonValue subValue = entry.getValue();
173 if (subValue instanceof JsonString) {
174 collection.addEvidence(PACKAGE_JSON,
175 String.format("%s.%s", key, property),
176 ((JsonString) subValue).getString(),
177 Confidence.HIGHEST);
178 } else {
179 LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
180 }
181 }
182 } else {
183 LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
184 }
185 }
186 }
187 }