-
Notifications
You must be signed in to change notification settings - Fork 5
feat(enrichment): ingest KEV,EPSS,OSV feeds with vulnerability rescoring #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f1e765e
feat(enrichment): ingest KEV,EPSS,OSV feeds with vulnerability rescoring
Arzu-N 4f3b39a
fix(config): add feed sync delay propertiy
Arzu-N 948bc99
chore(config): configure scheduler thread pool and HTTP timeouts
Arzu-N 8118339
refactor(enrichment): use URI template for epss requests
Arzu-N aa6bc67
perf(enrichment): cache KEV feed lookups
Arzu-N f1e4235
refactor(enrichment): map KEV cveID field explicitly
Arzu-N ca1d9c5
refactor(scanning): move vulnerability updates into transactional ser…
Arzu-N db8d1e8
test(scanning): update FeedSyncService test after refactor
Arzu-N 3635b6b
test(scanning): update FeedSyncService test for paginated processing
Arzu-N 49378bd
refactor(worker): move task scheduler configuration to worker applica…
Arzu-N 16c354f
refactor(eenrichment): make KEV cache access thread-safe
Arzu-N 4b9280f
feat(persistence): add optimistic locking for vulnerabilities
Arzu-N File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,3 +29,7 @@ management: | |
| enabled: true | ||
| redis: | ||
| enabled: true | ||
|
|
||
| feed: | ||
| sync: | ||
| delay: 3600000 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
backend/apps/worker/src/main/java/dev/cleat/worker/config/SchedulingConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package dev.cleat.worker.config; | ||
|
|
||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.scheduling.TaskScheduler; | ||
| import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; | ||
|
|
||
| @Configuration | ||
| public class SchedulingConfig { | ||
|
|
||
| @Bean | ||
| public TaskScheduler taskScheduler() { | ||
| ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); | ||
| scheduler.setPoolSize(4); | ||
| scheduler.setThreadNamePrefix("scheduler-"); | ||
| scheduler.initialize(); | ||
| return scheduler; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,4 +32,8 @@ management: | |
|
|
||
| app: | ||
| security: | ||
| scan-interval: 600000 | ||
| scan-interval: 600000 | ||
|
|
||
| feed: | ||
| sync: | ||
| delay: 3600000 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
backend/libs/common/src/main/java/dev/cleat/common/exception/FeedSyncException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package dev.cleat.common.exception; | ||
|
|
||
| public class FeedSyncException extends RuntimeException { | ||
| public FeedSyncException(String msg) { | ||
| super(msg); | ||
| } | ||
|
|
||
| public FeedSyncException(String msg, Throwable cause) { | ||
| super(msg, cause); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletion
6
backend/libs/domain/src/main/java/dev/cleat/domain/model/Vulnerability.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,16 @@ | ||
| package dev.cleat.domain.model; | ||
|
|
||
| import dev.cleat.common.enums.Reachable; | ||
| import dev.cleat.common.enums.Severity; | ||
| import java.util.Objects; | ||
|
|
||
| public record Vulnerability(Boolean kev, Double cvss, Severity severity) { | ||
| public record Vulnerability(Boolean kev, Double cvss, Severity severity, Double epss, Reachable reachable) { | ||
| public Vulnerability { | ||
| Objects.requireNonNull(cvss, "cvss cannot be null"); | ||
| Objects.requireNonNull(severity, "severity cannot be null"); | ||
|
|
||
| kev = (kev != null) ? kev : false; | ||
| epss = (epss != null) ? epss : 0.0; | ||
| reachable = (reachable != null) ? reachable : Reachable.UNKNOWN; | ||
| } | ||
| } |
29 changes: 29 additions & 0 deletions
29
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/EpssClient.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package dev.cleat.enrichment.client; | ||
|
|
||
| import dev.cleat.enrichment.dto.EpssResponse; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| @Component | ||
| public class EpssClient { | ||
| private final RestTemplate restTemplate; | ||
|
|
||
| public EpssClient(RestTemplate restTemplate) { | ||
| this.restTemplate = restTemplate; | ||
| } | ||
|
|
||
| private static final String URL = "https://api.first.org/data/v1/epss?cve={cve}"; | ||
|
|
||
| public Double fetchScore(String cve) { | ||
|
|
||
| EpssResponse response = restTemplate.getForObject(URL, EpssResponse.class, cve); | ||
| if (response == null || response.getData() == null || response.getData().isEmpty()) { | ||
| return null; | ||
| } | ||
| return response.getData().getFirst().getEpss(); | ||
| } | ||
|
Arzu-N marked this conversation as resolved.
|
||
|
|
||
| public EpssResponse fetchFeed(String cve) { | ||
| return restTemplate.getForObject(URL, EpssResponse.class, cve); | ||
| } | ||
| } | ||
45 changes: 45 additions & 0 deletions
45
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/KevClient.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package dev.cleat.enrichment.client; | ||
|
|
||
| import dev.cleat.enrichment.dto.KevResponse; | ||
| import dev.cleat.enrichment.dto.KevVulnerability; | ||
| import java.util.Set; | ||
| import java.util.stream.Collectors; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| @Component | ||
| public class KevClient { | ||
| private final RestTemplate restTemplate; | ||
| private Set<String> kevCache; | ||
| private Long cacheTimestamp; | ||
| private static final long CACHE_TTL_MS = 3600_000L; | ||
|
|
||
| public KevClient(RestTemplate restTemplate) { | ||
| this.restTemplate = restTemplate; | ||
| } | ||
|
|
||
| private static final String URL = | ||
| "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"; | ||
|
|
||
| public synchronized Set<String> getKevCache() { | ||
|
|
||
| if (kevCache == null || System.currentTimeMillis() - cacheTimestamp > CACHE_TTL_MS) { | ||
| KevResponse response = restTemplate.getForObject(URL, KevResponse.class); | ||
| kevCache = (response == null || response.getVulnerabilities() == null) | ||
| ? Set.of() | ||
| : response.getVulnerabilities().stream() | ||
| .map(KevVulnerability::getCveId) | ||
| .collect(Collectors.toSet()); | ||
| cacheTimestamp = System.currentTimeMillis(); | ||
| } | ||
| return kevCache; | ||
| } | ||
|
|
||
| public boolean isKev(String cve) { | ||
| return getKevCache().contains(cve); | ||
| } | ||
|
|
||
| public KevResponse fetchFeed() { | ||
| return restTemplate.getForObject(URL, KevResponse.class); | ||
| } | ||
| } |
26 changes: 26 additions & 0 deletions
26
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/client/OsvClient.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package dev.cleat.enrichment.client; | ||
|
|
||
| import dev.cleat.enrichment.dto.OsvPackage; | ||
| import dev.cleat.enrichment.dto.OsvRequest; | ||
| import dev.cleat.enrichment.dto.OsvResponse; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| @Component | ||
| public class OsvClient { | ||
| private final RestTemplate restTemplate; | ||
|
|
||
| public OsvClient(RestTemplate restTemplate) { | ||
| this.restTemplate = restTemplate; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| private static final String URL = "https://api.osv.dev/v1/query"; | ||
|
|
||
| public OsvResponse query(String packageName, String ecosystem) { | ||
| OsvPackage osvPackage = new OsvPackage().setName(packageName).setEcosystem(ecosystem); | ||
|
|
||
| OsvRequest osvRequest = new OsvRequest().setPkg(osvPackage); | ||
|
|
||
| return restTemplate.postForObject(URL, osvRequest, OsvResponse.class); | ||
| } | ||
| } | ||
18 changes: 18 additions & 0 deletions
18
backend/libs/enrichment/src/main/java/dev/cleat/enrichment/config/RestTemplateConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package dev.cleat.enrichment.config; | ||
|
|
||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.http.client.SimpleClientHttpRequestFactory; | ||
| import org.springframework.web.client.RestTemplate; | ||
|
|
||
| @Configuration | ||
| public class RestTemplateConfig { | ||
|
|
||
| @Bean | ||
| public RestTemplate restTemplate() { | ||
| SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); | ||
| factory.setConnectTimeout(4000); | ||
| factory.setReadTimeout(10000); | ||
| return new RestTemplate(factory); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.