Skip to content

feat: add rating source tracking for context-aware OWASP scores#6210

Open
fahedouch wants to merge 1 commit into
DependencyTrack:mainfrom
fahedouch:feature/rating-source-tracking-v5
Open

feat: add rating source tracking for context-aware OWASP scores#6210
fahedouch wants to merge 1 commit into
DependencyTrack:mainfrom
fahedouch:feature/rating-source-tracking-v5

Conversation

@fahedouch
Copy link
Copy Markdown
Contributor

@fahedouch fahedouch commented May 29, 2026

Description

Re-targeting DependencyTrack/hyades-apiserver#1928 here, since v5 dev moved to this repo (asked by @nscuro: DependencyTrack/hyades-apiserver#1928 (comment)).

Same change as the original PR, just rebased on main. Only thing that changed: renamed the migration so it runs after the latest one on main instead of in the middle.

Addressed Issue

No separate issue — this is the re-target of DependencyTrack/hyades-apiserver#1928 onto this repo, as requested by @nscuro for the v5 GA move.

Additional Details

Checklist

  • I have read and understand the contributing guidelines
  • This PR fixes a defect, and I have provided tests to verify that the fix is effective
  • This PR implements an enhancement, and I have provided tests to verify that it works as intended
  • This PR introduces changes to the database model, and I have updated the migration changelog accordingly
  • This PR introduces new or alters existing behavior, and I have updated the documentation accordingly
  • This PR is a substantial change (per the ADR criteria), and I have added an ADR under docs/adr/

Signed-off-by: Fahed Dorgaa <fahed.dorgaa@gmail.com>
Copilot AI review requested due to automatic review settings May 29, 2026 17:23
@owasp-dt-bot
Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a source column to analyses that tracks the origin of an analysis (POLICY, VEX, MANUAL, NVD) and enforces precedence rules so lower-precedence sources cannot overwrite higher-precedence ones. Also extends the analysis request/command surface with OWASP RR vector/score and updates the CycloneDX VEX importer to ingest OWASP ratings.

Changes:

  • Introduces RatingSource enum + SOURCE column on ANALYSIS, with migration and DAO/mapper wiring to persist it.
  • Threads source, owaspVector, owaspScore through MakeAnalysisCommand, REST request, and apply overwrite precedence in AnalysisQueryManager#makeAnalysis.
  • Updates CycloneDXVexImporter to support OWASP ratings and proceed when a vulnerability has ratings but no analysis block.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
migration/.../V202605291854__add_source_column_to_analysis.sql Adds SOURCE column, index, and backfills POLICY/MANUAL values.
apiserver/.../model/RatingSource.java New enum encoding source precedence and canOverwrite logic.
apiserver/.../model/Analysis.java Adds persistent source field with getters/setters.
apiserver/.../persistence/command/MakeAnalysisCommand.java Adds source, owaspVector, owaspScore fields/builders.
apiserver/.../persistence/AnalysisQueryManager.java Guards updates by precedence and audits OWASP/source changes.
apiserver/.../persistence/jdbi/AnalysisDao.java Includes SOURCE in policy-driven analysis upserts.
apiserver/.../persistence/jdbi/VulnerabilityPolicyDao.java Resets SOURCE when unassigning policy.
apiserver/.../persistence/jdbi/mapping/AnalysisRowMapper.java Reads SOURCE column into Analysis.
apiserver/.../resources/v1/vo/AnalysisRequest.java Adds OWASP vector/score request fields.
apiserver/.../resources/v1/AnalysisResource.java Passes OWASP fields and MANUAL source to the command.
apiserver/.../parser/cyclonedx/CycloneDXVexImporter.java Imports OWASP ratings as VEX-sourced analyses.
apiserver/.../test/.../RatingSourceTest.java Tests for precedence/overwrite behavior.
apiserver/.../test/.../AnalysisResourceTest.java Updates constructor calls for new request params.
apiserver/.../test/.../ProcessScheduledNotificationRuleActivityTest.java Adopts builder-style MakeAnalysisCommand.

Comment on lines +106 to +108
final boolean canUpdate = canUpdateAnalysis(analysis.getSource(), command.source());

if (canUpdate) {
Comment on lines +224 to +229
private boolean canUpdateAnalysis(final RatingSource existingSource, final RatingSource newSource) {
if (newSource == null || existingSource == null) {
return true;
}
return newSource.canOverwrite(existingSource);
}
Comment on lines +241 to +243
final java.math.BigDecimal score = rating.getScore() != null
? java.math.BigDecimal.valueOf(rating.getScore())
: null;
maybeSet(rs, "CVSSV4SCORE", ResultSet::getBigDecimal, analysis::setCvssV4Score);
maybeSet(rs, "OWASPVECTOR", ResultSet::getString, analysis::setOwaspVector);
maybeSet(rs, "OWASPSCORE", ResultSet::getBigDecimal, analysis::setOwaspScore);
maybeSet(rs, "SOURCE", ResultSet::getString, value -> analysis.setSource(RatingSource.valueOf(value)));
Comment on lines +11 to +24
-- Backfill: other analyses with meaningful data get MANUAL source
UPDATE "ANALYSIS"
SET "SOURCE" = 'MANUAL'
WHERE "SOURCE" IS NULL
AND (
("STATE" IS NOT NULL AND "STATE" != 'NOT_SET')
OR ("JUSTIFICATION" IS NOT NULL AND "JUSTIFICATION" != 'NOT_SET')
OR ("RESPONSE" IS NOT NULL AND "RESPONSE" != 'NOT_SET')
OR "SEVERITY" IS NOT NULL
OR "CVSSV2VECTOR" IS NOT NULL
OR "CVSSV3VECTOR" IS NOT NULL
OR "CVSSV4VECTOR" IS NOT NULL
OR "OWASPVECTOR" IS NOT NULL
);
Comment on lines +143 to +148
if (command.source() != null && analysis.getSource() != command.source()) {
if (analysis.getSource() != null) {
auditTrailComments.add("Source: %s → %s".formatted(analysis.getSource(), command.source()));
}
analysis.setSource(command.source());
}
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 29, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 26 complexity · 0 duplication

Metric Results
Complexity 26
Duplication 0

View in Codacy

🟢 Coverage 80.36% diff coverage · -0.03% coverage variation

Metric Results
Coverage variation -0.03% coverage variation (-1.00%)
Diff coverage 80.36% diff coverage (70.00%)

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (659d391) 41636 35834 86.06%
Head commit (2a2c8a8) 41693 (+57) 35869 (+35) 86.03% (-0.03%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#6210) 112 90 80.36%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants