Skip to content

Commit a9498ed

Browse files
authored
fix: follow GHSA best practices for rate limiting (#370)
* fix: add out argument for GHSA command Ensures banner, etc. are not in the JSON output * build(deps): bump open-vulnerability-clients from 9.0.1 to 9.0.2 * build: bump release version
1 parent 4c53e67 commit a9498ed

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ description = "A java CLI to call the NVD API"
1717
group = "io.github.jeremylong"
1818

1919
repositories {
20+
mavenLocal()
2021
mavenCentral()
2122
gradlePluginPortal()
2223
}
@@ -30,7 +31,7 @@ val commonsLang3Version by extra("3.17.0")
3031

3132
dependencies {
3233
compileOnly("com.github.spotbugs:spotbugs-annotations:${spotbugs.toolVersion.get()}")
33-
implementation("io.github.jeremylong:open-vulnerability-clients:9.0.0")
34+
implementation("io.github.jeremylong:open-vulnerability-clients:9.0.2")
3435
implementation("info.picocli:picocli-spring-boot-starter:4.7.7")
3536
constraints {
3637
implementation("org.springframework.boot:spring-boot-starter:3.4.2")

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = 9.0.1
1+
version = 9.0.2

src/main/java/io/github/jeremylong/vulnz/cli/commands/GHSACommand.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.springframework.stereotype.Component;
3737
import picocli.CommandLine;
3838

39+
import java.io.FileOutputStream;
40+
import java.io.OutputStream;
3941
import java.time.ZonedDateTime;
4042
import java.util.Collection;
4143
import java.util.Objects;
@@ -66,6 +68,8 @@ public class GHSACommand extends AbstractJsonCommand {
6668
private String classifications;
6769
@CommandLine.Option(names = {"--interactive"}, description = "Displays a progress bar")
6870
private boolean interactive;
71+
@CommandLine.Option(names = {"--out"}, description = "Output file path (writes to stdout if not specified)")
72+
private String output;
6973
// yes - this should not be a string, but seriously down the call path the HttpClient
7074
// doesn't support passing a header in as a char[]...
7175
private String apiKey = null;
@@ -127,37 +131,41 @@ public Integer timedCall() throws Exception {
127131
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
128132

129133
JsonFactory jfactory = objectMapper.getFactory();
130-
JsonGenerator jsonOut = jfactory.createGenerator(System.out, JsonEncoding.UTF8);
131-
if (isPrettyPrint()) {
132-
jsonOut.useDefaultPrettyPrinter();
133-
}
134-
135-
jsonOut.writeStartObject();
136-
jsonOut.writeFieldName("advisories");
137-
jsonOut.writeStartArray();
138134
BasicOutput output = new BasicOutput();
139-
try (GitHubSecurityAdvisoryClient api = builder.build();
135+
try (OutputStream outStream = (this.output != null) ? new FileOutputStream(this.output) : System.out;
136+
JsonGenerator jsonOut = jfactory.createGenerator(outStream, JsonEncoding.UTF8);
137+
GitHubSecurityAdvisoryClient api = builder.build();
140138
IProgressMonitor monitor = new ProgressMonitor(interactive, "GHSA")) {
139+
if (isPrettyPrint()) {
140+
jsonOut.useDefaultPrettyPrinter();
141+
}
142+
143+
jsonOut.writeStartObject();
144+
jsonOut.writeFieldName("advisories");
145+
jsonOut.writeStartArray();
146+
LOG.debug("START: Requesting GHSA data");
141147
while (api.hasNext()) {
142148
Collection<SecurityAdvisory> list = api.next();
149+
LOG.debug("Retrieved {} GHSA records", (list != null) ? list.size() : 0);
143150
if (list != null) {
144151
output.setSuccess(true);
145152
output.addCount(list.size());
146153
for (SecurityAdvisory c : list) {
147154
jsonOut.writeObject(c);
148155
}
156+
jsonOut.flush();
149157
monitor.updateProgress("GHSA", output.getCount(), api.getTotalAvailable());
150158
} else {
151159
output.setSuccess(false);
152160
output.setReason(String.format("Received HTTP Status Code: %s", api.getLastStatusCode()));
153161
break;
154162
}
155163
}
164+
LOG.debug("END: Requesting GHSA data");
156165
output.setLastModifiedDate(api.getLastUpdated());
157166
jsonOut.writeEndArray();
158167
jsonOut.writeObjectField("results", output);
159168
jsonOut.writeEndObject();
160-
jsonOut.close();
161169

162170
if (!output.isSuccess()) {
163171
String msg = String.format("%nFAILED: %s", output.getReason());

0 commit comments

Comments
 (0)