DependencyTrack / dependency-track

Dependency-Track is an intelligent Component Analysis platform that allows organizations to identify and reduce risk in the software supply chain.
https://dependencytrack.org/
Apache License 2.0
2.69k stars 578 forks source link

BOM upload and analysis bugs in 4.11.x #4151

Closed calderonth closed 1 month ago

calderonth commented 1 month ago

Current Behavior

I recently upgraded to 4.11.7 and have observed regressions in the BOM processing code. Prior to this new version which includes the new BOMv2 processing code https://github.com/DependencyTrack/dependency-track/pull/3357 I would regularly upload my SBOM via the API or UI and the reporting/analysis would behave normally.

Since the update some of my uploads are not processingly correctly and I get database errors as well. For example, I can see the following stack traces:

Processing CycloneDX dependency graph for project: 92f4fbbf-887c-4451-a668-6f11ab4055a3
2024-09-16 17:46:39,165 ERROR [Transaction] Operation commit failed on resource: org.datanucleus.store.rdbms.ConnectionFactoryImpl$EmulatedXAResource@55fc2de6, error code UNKNOWN and transaction [DataNucleus Transaction, ID=1352542619-317350, enlisted resources=[org.datanucleus.store.rdbms.ConnectionFactoryImpl$EmulatedXAResource@55fc2de6]] : ERROR: update or delete on table "COMPONENT" violates foreign key constraint "FINDINGATTRIBUTION_FK1" on table "FINDINGATTRIBUTION"
  Detail: Key (ID)=(1206874) is still referenced from table "FINDINGATTRIBUTION".
2024-09-16 17:46:39,166 ERROR [BomUploadProcessingTask] Error while processing bom
javax.jdo.JDODataStoreException: Transaction rolled back due to failure during commit
        at org.datanucleus.api.jdo.JDOAdapter.getJDOExceptionForNucleusException(JDOAdapter.java:720)
        at org.datanucleus.api.jdo.JDOTransaction.commit(JDOTransaction.java:157)
        at alpine.persistence.AbstractAlpineQueryManager.delete(AbstractAlpineQueryManager.java:474)
        at org.dependencytrack.persistence.ComponentQueryManager.recursivelyDelete(ComponentQueryManager.java:457)
        at org.dependencytrack.persistence.ComponentQueryManager.reconcileComponents(ComponentQueryManager.java:690)
        at org.dependencytrack.persistence.QueryManager.reconcileComponents(QueryManager.java:951)
        at org.dependencytrack.tasks.BomUploadProcessingTask.inform(BomUploadProcessingTask.java:189)
        at org.dependencytrack.tasks.BomUploadProcessingTaskV2.inform(BomUploadProcessingTaskV2.java:151)
        at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:110)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "COMPONENT" violates foreign key constraint "FINDINGATTRIBUTION_FK1" on table "FINDINGATTRIBUTION"
  Detail: Key (ID)=(1206874) is still referenced from table "FINDINGATTRIBUTION".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2725)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2412)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:371)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:329)
        at org.postgresql.jdbc.PgConnection.executeTransactionCommand(PgConnection.java:981)
        at org.postgresql.jdbc.PgConnection.commit(PgConnection.java:1003)
        at com.zaxxer.hikari.pool.ProxyConnection.commit(ProxyConnection.java:377)
        at com.zaxxer.hikari.pool.HikariProxyConnection.commit(HikariProxyConnection.java)
        at org.datanucleus.store.rdbms.ConnectionFactoryImpl$EmulatedXAResource.commit(ConnectionFactoryImpl.java:739)
        at org.datanucleus.transaction.ResourcedTransaction.commit(ResourcedTransaction.java:351)
        at org.datanucleus.transaction.ResourcedTransactionManager.commit(ResourcedTransactionManager.java:64)
        at org.datanucleus.transaction.TransactionImpl.internalCommit(TransactionImpl.java:418)
        at org.datanucleus.transaction.TransactionImpl.commit(TransactionImpl.java:289)
        at org.datanucleus.api.jdo.JDOTransaction.commit(JDOTransaction.java:94)
        ... 10 common frames omitted

Uploading the same SBOM over and over yields some more errors:

Caused by: org.datanucleus.exceptions.NucleusObjectNotFoundException: Object with id "org.dependencytrack.model.Component:1207197" not found !
        at org.datanucleus.store.rdbms.request.FetchRequest.execute(FetchRequest.java:492)
        at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.fetchObject(RDBMSPersistenceHandler.java:427)
        at org.datanucleus.state.StateManagerImpl.loadFieldsFromDatastore(StateManagerImpl.java:1632)
        at org.datanucleus.state.StateManagerImpl.validate(StateManagerImpl.java:5597)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3538)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:2999)
        at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1721)
        ... 6 common frames omitted
2024-09-16 17:49:58,676 ERROR [NewVulnerableDependencyAnalysisTask] An unknown error occurred while analyzing notification criteria for component 15d9eb9b-16eb-434a-ad95-14f552e1dcde
javax.jdo.JDOObjectNotFoundException: Object with id "org.dependencytrack.model.Component:1207198" not found !
        at org.datanucleus.api.jdo.JDOAdapter.getJDOExceptionForNucleusException(JDOAdapter.java:634)
        at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1726)
        at alpine.persistence.AbstractAlpineQueryManager.getObjectById(AbstractAlpineQueryManager.java:535)
        at org.dependencytrack.tasks.NewVulnerableDependencyAnalysisTask.inform(NewVulnerableDependencyAnalysisTask.java:44)
        at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:110)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.datanucleus.exceptions.NucleusObjectNotFoundException: Object with id "org.dependencytrack.model.Component:1207198" not found !
        at org.datanucleus.store.rdbms.request.FetchRequest.execute(FetchRequest.java:492)
        at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.fetchObject(RDBMSPersistenceHandler.java:427)
        at org.datanucleus.state.StateManagerImpl.loadFieldsFromDatastore(StateManagerImpl.java:1632)
        at org.datanucleus.state.StateManagerImpl.validate(StateManagerImpl.java:5597)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3538)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:2999)
        at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1721)
        ... 6 common frames omitted
2024-09-16 17:49:58,678 ERROR [NewVulnerableDependencyAnalysisTask] An unknown error occurred while analyzing notification criteria for component 53051145-3f24-4247-a9fe-2c01db4f2a8b
javax.jdo.JDOObjectNotFoundException: Object with id "org.dependencytrack.model.Component:1207199" not found !
        at org.datanucleus.api.jdo.JDOAdapter.getJDOExceptionForNucleusException(JDOAdapter.java:634)
        at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1726)
        at alpine.persistence.AbstractAlpineQueryManager.getObjectById(AbstractAlpineQueryManager.java:535)
        at org.dependencytrack.tasks.NewVulnerableDependencyAnalysisTask.inform(NewVulnerableDependencyAnalysisTask.java:44)
        at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:110)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.datanucleus.exceptions.NucleusObjectNotFoundException: Object with id "org.dependencytrack.model.Component:1207199" not found !
        at org.datanucleus.store.rdbms.request.FetchRequest.execute(FetchRequest.java:492)
        at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.fetchObject(RDBMSPersistenceHandler.java:427)
        at org.datanucleus.state.StateManagerImpl.loadFieldsFromDatastore(StateManagerImpl.java:1632)
        at org.datanucleus.state.StateManagerImpl.validate(StateManagerImpl.java:5597)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3538)
        at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:2999)
        at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1721)
        ... 6 common frames omitted

The main way to describe what I can see in the UI is that some of the components are purged from the project. Deleting all components from the project allows and re-uploading a fresh SBOM restores the state (with the current component count) until I upload a new SBOM again (I only use CURRENT_VERSION).

The odd thing is that enabling the BOMv2 experimental feature seem to resolve the issue. This leads me to believe that there was a regression introduced when adding the BOMv2 code which isn't gated by the config flag.

Steps to Reproduce

  1. Create a project
  2. Upload inital SBOM, observe expected behavior with components count and vulnerabilities identified
  3. Upload SBOM again, observe components count going down

Expected Behavior

Successive uploads of the same SBOM should not result in different components being reported.

Dependency-Track Version

4.11.7

Dependency-Track Distribution

Container Image

Database Server

PostgreSQL

Database Server Version

No response

Browser

Google Chrome

Checklist

nscuro commented 1 month ago

The odd thing is that enabling the BOMv2 experimental feature seem to resolve the issue. This leads me to believe that there was a regression introduced when adding the BOMv2 code which isn't gated by the config flag.

Hmmm, we took great care to not affect the legacy processing logic, hence keeping it entirely separate from the V2 implementation.

I can't 100% exclude us making any mistake in that, but looking at the errors you shared, those look pretty much exactly like the cases that the V2 implementation was supposed to fix (have a look at a few of the referenced Addressed Issues in https://github.com/DependencyTrack/dependency-track/pull/3357). So it makes sense that switching to V2 resolves them.

calderonth commented 1 month ago

Interesting, the behavior was indeed observed on SBOM uploads that do not have components with PURL but instead components that report via CPE strings.

I will leave the BOMv2 enabled for now and observe the behavior on other uploads.

nscuro commented 1 month ago

Any new observations since last week?

calderonth commented 1 month ago

No, I think we can close this one since turning on the BOMv2 feature.

On Tue, 24 Sept 2024, 17:36 Niklas, @.***> wrote:

Any new observations since last week?

— Reply to this email directly, view it on GitHub https://github.com/DependencyTrack/dependency-track/issues/4151#issuecomment-2371790048, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAF3DVRTCNZ66UEQMCGKDEDZYGIHZAVCNFSM6AAAAABOJ3RVMSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNZRG44TAMBUHA . You are receiving this because you authored the thread.Message ID: @.***>

nscuro commented 1 month ago

Thanks for reporting back!

github-actions[bot] commented 2 weeks ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.