Skip to content

Composite_key_approach#68

Open
cx-apoorva-singh wants to merge 11 commits intopre-release-1.0.34from
composite_key_approach
Open

Composite_key_approach#68
cx-apoorva-singh wants to merge 11 commits intopre-release-1.0.34from
composite_key_approach

Conversation

@cx-apoorva-singh
Copy link
Copy Markdown
Contributor

PR Title
CxOne AVIT Composite Key Implementation & Aggregation Logic

Description
This PR introduces a stable composite key for mapping CxOne SAST findings to ServiceNow AVITs, replacing the previous key based on resultHash. The new key is a SHA256 hash of the finding’s code-flow location, ensuring stability across scans and enabling aggregation of multiple findings into a single AVIT. The implementation also includes logic for migration from old keys, aggregation handling, NOT_EXPLOITABLE closure, and ensures correct closure/update behavior for AVITs. Non-SAST findings (SCA, KICS, Containers, etc.) remain unaffected.

Summary of New Changes

  • Composite Key: SAST source_avit_id is now computed as similarityId + '_' + SHA256(similarityId + startNodeName + startFileName + endNodeName + endFileName).

  • Aggregation: Multiple findings with the same composite key are aggregated into one AVIT. The count is stored in dependency_type, and up to 20 deep links are stored in source_vulnerability_summary.

  • Migration: On first scan after deployment, old-key AVITs are re-keyed to the new composite key, and duplicates are closed.

  • NOT_EXPLOITABLE Handling: If a finding is marked NOT_EXPLOITABLE, all AVITs sharing the composite key for the project/branch are set to FIXED and closed.

  • Closure Logic: AVITs are closed if all findings disappear in a scan; remain open if any finding remains.

  • Non-SAST Findings: SCA, KICS, Containers, etc., continue to use the old key logic.

  • Max Link Limit: Only 20 links are stored per AVIT for aggregated findings.

Test Cases & Coverage

  • Composite Key Generation (Covered)

    • Test Case:
      • Input: SAST finding with specific similarityId, nodes array (with start/end node names and file names).
      • Expected: source_avit_id is similarityId + '_' + SHA256(similarityId + startNodeName + startFileName + endNodeName + endFileName).
      • Edge: Single-node and multi-node findings.
  • Aggregation Logic (Covered)

    • Test Case:
      • Input: Two findings with same composite key (different resultHash), same scan.
      • Expected: Only one AVIT created, dependency_type = 2, both deep links in source_vulnerability_summary (max 20).
  • Migration from Old Key (Covered)

    • Test Case:
      • Input: Existing AVIT with old key (similarityId + '_' + resultHash), new scan with composite key.
      • Expected: Old AVIT re-keyed to new composite key, counter/links reset, duplicates closed (state=3, FIXED).
  • Counter and Link Reset per Scan (Covered)

    • Test Case:
      • Input: First finding for composite key in new scan.
      • Expected: dependency_type = 1, source_vulnerability_summary = current link.
    • Test Case:
      • Input: Second finding for same composite key in same scan.
      • Expected: dependency_type increments, link appended.
  • Closure Logic (Remaining)

    • Test Case:
      • Input: All findings for a composite key disappear in a scan.
      • Expected: AVIT is closed by closure processor.
    • Test Case:
      • Input: Some findings remain.
      • Expected: AVIT remains open.
  • Max Link Limit (Remaining)

    • Test Case:
      • Input: >20 findings for same composite key in one scan.
      • Expected: Only 20 links stored in source_vulnerability_summary.
  • Non-SAST Findings (Remaining)

    • Test Case:
      • Input: SCA, KICS, Containers, etc.
      • Expected: Old key logic applies, no composite key logic.

Jira Link : https://checkmarx.atlassian.net/browse/CXSER-983

Addition pf Composite_key (source_avit_id is similarityId + '_' + SHA256(similarityId + startNodeName + startFileName + endNodeName + endFileName) to Source AVIT Id column of ServiceNow.
Jira link: https://checkmarx.atlassian.net/browse/CXSER-983
…9e510026f72021153af1b.js

removing stale code
'?resultId=' + encodeURIComponent(sastResultHash);

var sastScanUrl = '';
if (!jsonLastScanReportResp.results[item].data.resultHash.indexOf('/') == -1) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The ! negates indexOf(...) before comparing to -1, so !0 == -1 → false, !5 == -1 → false, and !(-1) == -1 → false as well. This condition is always false — the else branch (/sast) is always taken, making the URL-building logic dead code. The intent was almost certainly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will update sastVulnerabilityLink creation

existingCounter = parseInt(avitNew.getValue('dependency_type') || '0', 10);
existingLinks = avitNew.getValue('source_vulnerability_summary') || '';
existingScanSummaryStr = avitNew.getDisplayValue('app_vul_scan_summary') || '';
existingStatus = avitNew.getValue('source_remediation_status') || '';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

missing var declaration for existingStatus

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will remove existingStatus , it is not being used.

existingCounter = parseInt(avitNew.getValue('dependency_type') || '0', 10);
existingLinks = avitNew.getValue('source_vulnerability_summary') || '';
existingScanSummaryStr = avitNew.getDisplayValue('app_vul_scan_summary') || '';
existingStatus = avitNew.getValue('source_remediation_status') || '';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

existingStatus is read but never used anywhere in the function body. It's dead code that should either be removed or actually consumed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will remove existingStatus , it is not being used.

} else {
var newCounter = existingCounter + 1;
resultObj['dependency_type'] = '' + newCounter;
if (linkHtml && existingCounter < 20) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

checked against existingCounter (the pre-increment value) but the result uses newCounter. The check should be against newCounter?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, will add check against newCounter.

updated sastVulnerabilityLink  creation
added null check for compositeLocationHash
removed existingStatus , since it not being used
line 442 added check for newCounter  insted of existingCounter
change has been added to handle closing of record , which has not been migrated with new composite key and belongs to latest scan hence was not handled by existing closure logic.
…9e510026f72021153af1b.js

Updated SAST aggregation to use resultHash as the displayed link text in source_vulnerability_summary instead of the full vulnerability URL. Since resultHash is only about 22 characters and keeps the stored HTML well within the field's 8000 character limit, the append cap was increased from 20 to 30 to retain more finding links per AVIT.
Update CheckmarxOneAVITClosureProcessor.js

This change adds handling for closing records that were not migrated to the new composite key and belong to the latest scan. Such records were not covered by the existing closure logic, and this update ensures they are now processed correctly.
… key and aggregation changes.pdf

Document to manually apply composite change in version 1.0.34
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.

2 participants