Skip to content

fix: Return unsorted vulnerabilities in new HashSet, avoiding CoMod#7848

Merged
nhumblot merged 2 commits intodependency-check:mainfrom
HandyG52:NpmCoModExc
Aug 6, 2025
Merged

fix: Return unsorted vulnerabilities in new HashSet, avoiding CoMod#7848
nhumblot merged 2 commits intodependency-check:mainfrom
HandyG52:NpmCoModExc

Conversation

@HandyG52
Copy link
Copy Markdown

Description of Change

Dependency.java getVulnerabilities(boolean sorted) method when sorted=false returns the vulnerabilities HashSet global to the Dependency object. It is returned wrapped in an UnmodifiableSet, but this does not protect against concurrent modifications as it just wraps the original set. Any future calls to add or remove vulnerabilities will proceed, as we are outside the synchronized methods, while someone is potentially iterating over the UnmodifiableSet retrieved earlier.

I came across this intermittent issue during my builds while in AbstractNpmAnalyzer.replaceOrAddVulnerability. I assume one AbstractNpmAnalyzer instance is performing a stream.anyMatch on the Set while another instance, or some other mechanism, is adding or removing vulnerabilities from the same dependency.

Note: In this same line of code (AbstractNpmAnalyzer.replaceOrAddVulnerability) there is another stream operation to locate references for a vulnerability by name, however I think the references Set is thread-safe. It also uses Collections.unmodifiableSet, but in this case the Set being wrapped is ConcurrentHashMap.newKeySet which should remain thread-safe. A similar approach could be taken in Dependency.java with the vulnerabilitySet, but would be more invasive.

Related issues

[ERROR]
java.util.ConcurrentModificationException
at java.util.HashMap$KeySpliterator.tryAdvance (HashMap.java:1738)
at java.util.stream.ReferencePipeline.forEachWithCancel (ReferencePipeline.java:129)
at java.util.stream.AbstractPipeline.copyIntoWithCancel (AbstractPipeline.java:527)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:513)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:499)
at java.util.stream.MatchOps$MatchOp.evaluateSequential (MatchOps.java:230)
at java.util.stream.MatchOps$MatchOp.evaluateSequential (MatchOps.java:196)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.anyMatch (ReferencePipeline.java:632)
at org.owasp.dependencycheck.analyzer.AbstractNpmAnalyzer.replaceOrAddVulnerability (AbstractNpmAnalyzer.java:508)
at org.owasp.dependencycheck.analyzer.AbstractNpmAnalyzer.processResults (AbstractNpmAnalyzer.java:494)
at org.owasp.dependencycheck.analyzer.NodeAuditAnalyzer.analyzeDependency (NodeAuditAnalyzer.java:151)
at org.owasp.dependencycheck.analyzer.AbstractAnalyzer.analyze (AbstractAnalyzer.java:131)
at org.owasp.dependencycheck.AnalysisTask.call (AnalysisTask.java:88)
at org.owasp.dependencycheck.AnalysisTask.call (AnalysisTask.java:37)
at java.util.concurrent.FutureTask.run (FutureTask.java:317)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1144)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:642)
at java.lang.Thread.run (Thread.java:1583)

Have test cases been added to cover the new functionality?

no

@boring-cyborg boring-cyborg bot added the core changes to core label Jul 31, 2025
@HandyG52 HandyG52 changed the title Return unsorted vulnerabilities in new HashSet, avoiding CoMod fix: Return unsorted vulnerabilities in new HashSet, avoiding CoMod Jul 31, 2025
@HandyG52 HandyG52 changed the title fix: Return unsorted vulnerabilities in new HashSet, avoiding CoMod fix: Return unsorted vulnerabilities in new HashSet, avoiding CoMod Aug 1, 2025
@nhumblot nhumblot added the bug label Aug 6, 2025
@nhumblot
Copy link
Copy Markdown
Collaborator

nhumblot commented Aug 6, 2025

Relates to #5809 & #7177

Thank you for your help!

Copy link
Copy Markdown
Collaborator

@nhumblot nhumblot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the callers of the updated method and did not see any call to Set<Vulnerability> getVulnerabilities(boolean sorted) that would try to add a new Vulnerability to the returned Set<Vulnerability>.

@nhumblot nhumblot merged commit 4333171 into dependency-check:main Aug 6, 2025
5 checks passed
@jeremylong jeremylong added this to the 12.1.4 milestone Aug 6, 2025
@HandyG52 HandyG52 deleted the NpmCoModExc branch August 14, 2025 15:39
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bug core changes to core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants