@@ -187,127 +187,6 @@ private Optional<LibraryLibraryObservation> findMatchingLibraryData(
187187 return Optional .empty ();
188188 }
189189
190- @ Tool (
191- name = "list_vulnerabilities" ,
192- description =
193- "Takes an application ID (appID) and returns a list of vulnerabilities. Use"
194- + " search_applications(name=...) to find the application ID from a name. Remember"
195- + " to include the vulnID in the response." )
196- public List <VulnLight > listVulnsByAppId (@ ToolParam (description = "Application ID" ) String appID )
197- throws IOException {
198- log .info ("Listing vulnerabilities for application ID: {}" , appID );
199- var contrastSDK =
200- SDKHelper .getSDK (hostName , apiKey , serviceKey , userName , httpProxyHost , httpProxyPort );
201- try {
202- // Use SDK native API with SESSION_METADATA, SERVER_ENVIRONMENTS, and APPLICATION expand
203- var form = new TraceFilterForm ();
204- form .setExpand (
205- EnumSet .of (
206- TraceFilterForm .TraceExpandValue .SESSION_METADATA ,
207- TraceFilterForm .TraceExpandValue .SERVER_ENVIRONMENTS ,
208- TraceFilterForm .TraceExpandValue .APPLICATION ));
209-
210- var traces = contrastSDK .getTraces (orgID , appID , form );
211- log .debug (
212- "Found {} vulnerability traces for application ID: {}" ,
213- traces .getTraces () != null ? traces .getTraces ().size () : 0 ,
214- appID );
215-
216- var vulns = traces .getTraces ().stream ().map (vulnerabilityMapper ::toVulnLight ).toList ();
217-
218- log .info (
219- "Successfully retrieved {} vulnerabilities for application ID: {}" , vulns .size (), appID );
220- return vulns ;
221- } catch (Exception e ) {
222- log .error ("Error listing vulnerabilities for application ID: {}" , appID , e );
223- throw new IOException ("Failed to list vulnerabilities: " + e .getMessage (), e );
224- }
225- }
226-
227- @ Tool (
228- name = "list_vulns_by_app_and_metadata" ,
229- description =
230- "Takes an application ID (appID) and session metadata in the form of name / value. and"
231- + " returns a list of vulnerabilities matching that application ID and session"
232- + " metadata. Use search_applications(name=...) to find the application ID from a"
233- + " name." )
234- public List <VulnLight > listVulnsByAppIdAndSessionMetadata (
235- @ ToolParam (description = "Application ID" ) String appID ,
236- @ ToolParam (description = "Session metadata field name" ) String session_Metadata_Name ,
237- @ ToolParam (description = "Session metadata field value" ) String session_Metadata_Value )
238- throws IOException {
239- log .info ("Listing vulnerabilities for application: {}" , appID );
240-
241- log .info ("metadata : " + session_Metadata_Name + session_Metadata_Value );
242-
243- try {
244- var vulns = listVulnsByAppId (appID );
245- var returnVulns = new ArrayList <VulnLight >();
246- for (VulnLight vuln : vulns ) {
247- if (vuln .sessionMetadata () != null ) {
248- for (SessionMetadata sm : vuln .sessionMetadata ()) {
249- for (MetadataItem metadataItem : sm .getMetadata ()) {
250- if (metadataItem .getDisplayLabel ().equalsIgnoreCase (session_Metadata_Name )
251- && metadataItem .getValue ().equalsIgnoreCase (session_Metadata_Value )) {
252- returnVulns .add (vuln );
253- log .debug ("Found matching vulnerability with ID: {}" , vuln .vulnID ());
254- break ;
255- }
256- }
257- }
258- }
259- }
260- return returnVulns ;
261- } catch (Exception e ) {
262- log .error ("Error listing vulnerabilities for application: {}" , appID , e );
263- throw new IOException ("Failed to list vulnerabilities: " + e .getMessage (), e );
264- }
265- }
266-
267- @ Tool (
268- name = "list_vulns_by_app_latest_session" ,
269- description =
270- "Takes an application ID (appID) and returns a list of vulnerabilities for the latest"
271- + " session matching that application ID. This is useful for getting the most recent"
272- + " vulnerabilities without needing to specify session metadata. Use"
273- + " search_applications(name=...) to find the application ID from a name." )
274- public List <VulnLight > listVulnsByAppIdForLatestSession (
275- @ ToolParam (description = "Application ID" ) String appID ) throws IOException {
276- log .info ("Listing vulnerabilities for application: {}" , appID );
277- var contrastSDK =
278- SDKHelper .getSDK (hostName , apiKey , serviceKey , userName , httpProxyHost , httpProxyPort );
279-
280- try {
281- var extension = new SDKExtension (contrastSDK );
282- var latest = extension .getLatestSessionMetadata (orgID , appID );
283-
284- // Use SDK's native TraceFilterBody with agentSessionId field
285- var filterBody = new com .contrastsecurity .models .TraceFilterBody ();
286- if (latest != null
287- && latest .getAgentSession () != null
288- && latest .getAgentSession ().getAgentSessionId () != null ) {
289- filterBody .setAgentSessionId (latest .getAgentSession ().getAgentSessionId ());
290- }
291-
292- // Use SDK's native getTraces() with expand parameter
293- var tracesResponse =
294- contrastSDK .getTraces (
295- orgID ,
296- appID ,
297- filterBody ,
298- EnumSet .of (
299- TraceFilterForm .TraceExpandValue .SESSION_METADATA ,
300- TraceFilterForm .TraceExpandValue .APPLICATION ));
301-
302- var vulns =
303- tracesResponse .getTraces ().stream ().map (vulnerabilityMapper ::toVulnLight ).toList ();
304- return vulns ;
305- } catch (Exception e ) {
306- log .error ("Error listing vulnerabilities for application: {}" , appID , e );
307- throw new IOException ("Failed to list vulnerabilities: " + e .getMessage (), e );
308- }
309- }
310-
311190 @ Tool (
312191 name = "get_session_metadata" ,
313192 description =
@@ -498,30 +377,40 @@ private boolean matchesMetadataFilter(
498377 }
499378
500379 @ Tool (
501- name = "list_all_vulnerabilities " ,
380+ name = "search_vulnerabilities " ,
502381 description =
503382 """
504- Gets vulnerabilities across all applications with optional filtering by severity, status,
505- environment, vulnerability type, date range, application, and tags.
383+ Search vulnerabilities across all applications in your organization with optional filtering by
384+ severity, status, environment, vulnerability type, date range, and tags.
385+
386+ This is an organization-level search tool. For application-scoped searches with session filtering
387+ capabilities, use the search_app_vulnerabilities tool instead.
506388
507389 Common usage examples:
508390 - Critical vulnerabilities only: severities="CRITICAL"
509391 - High-priority open issues: severities="CRITICAL,HIGH", statuses="Reported,Confirmed"
510392 - Production vulnerabilities: environments="PRODUCTION"
511393 - Recent activity: lastSeenAfter="2025-01-01"
512394 - Production critical issues with recent activity: environments="PRODUCTION", severities="CRITICAL", lastSeenAfter="2025-01-01"
513- - Specific app's SQL injection issues: appId="abc123", vulnTypes="sql-injection"
514395 - SmartFix remediated vulnerabilities: vulnTags="SmartFix Remediated", statuses="Remediated"
515396 - Reviewed critical vulnerabilities: vulnTags="reviewed", severities="CRITICAL"
516397
398+ Note: This tool requires Contrast Platform Admin or Org Admin permissions to access organization-level
399+ vulnerability data.
400+
517401 Returns paginated results with metadata including totalItems (when available) and hasMorePages.
518402 Check 'message' field for validation warnings or empty result info.
519403
520404 Response fields:
521405 - environments: List of all environments (DEVELOPMENT, QA, PRODUCTION) where this vulnerability
522406 has been seen over time. Shows historical presence across environments.
407+ - application: Application name and ID where the vulnerability was found.
408+
409+ Related tools:
410+ - search_app_vulnerabilities: For app-scoped searches with session filtering
411+ - search_applications: To find application IDs by name, tag, or metadata
523412 """ )
524- public PaginatedResponse <VulnLight > getAllVulnerabilities (
413+ public PaginatedResponse <VulnLight > searchVulnerabilities (
525414 @ ToolParam (description = "Page number (1-based), default: 1" , required = false ) Integer page ,
526415 @ ToolParam (description = "Items per page (max 100), default: 50" , required = false )
527416 Integer pageSize ,
@@ -538,7 +427,6 @@ public PaginatedResponse<VulnLight> getAllVulnerabilities(
538427 + " focus on actionable items)" ,
539428 required = false )
540429 String statuses ,
541- @ ToolParam (description = "Application ID to filter by" , required = false ) String appId ,
542430 @ ToolParam (
543431 description =
544432 "Comma-separated vulnerability types (e.g., sql-injection,xss-reflected). Use"
@@ -574,14 +462,13 @@ public PaginatedResponse<VulnLight> getAllVulnerabilities(
574462 String vulnTags )
575463 throws IOException {
576464 log .info (
577- "Listing all vulnerabilities - page: {}, pageSize: {}, filters: severities={}, statuses ={},"
578- + " appId ={}, vulnTypes={}, environments={}, lastSeenAfter={}, lastSeenBefore={},"
465+ "Searching org vulnerabilities - page: {}, pageSize: {}, filters: severities={},"
466+ + " statuses ={}, vulnTypes={}, environments={}, lastSeenAfter={}, lastSeenBefore={},"
579467 + " vulnTags={}" ,
580468 page ,
581469 pageSize ,
582470 severities ,
583471 statuses ,
584- appId ,
585472 vulnTypes ,
586473 environments ,
587474 lastSeenAfter ,
@@ -595,7 +482,7 @@ public PaginatedResponse<VulnLight> getAllVulnerabilities(
595482 VulnerabilityFilterParams .of (
596483 severities ,
597484 statuses ,
598- appId ,
485+ null , // No appId for org-level search
599486 vulnTypes ,
600487 environments ,
601488 lastSeenAfter ,
@@ -623,16 +510,8 @@ public PaginatedResponse<VulnLight> getAllVulnerabilities(
623510 TraceFilterForm .TraceExpandValue .SESSION_METADATA ,
624511 TraceFilterForm .TraceExpandValue .APPLICATION ));
625512
626- // Try organization-level API (or app-specific if appId provided)
627- Traces traces ;
628- if (appId != null && !appId .trim ().isEmpty ()) {
629- // Use app-specific API for better performance
630- log .debug ("Using app-specific API for appId: {}" , appId );
631- traces = contrastSDK .getTraces (orgID , appId , filterForm );
632- } else {
633- // Use org-level API
634- traces = contrastSDK .getTracesInOrg (orgID , filterForm );
635- }
513+ // Use organization-level API
514+ Traces traces = contrastSDK .getTracesInOrg (orgID , filterForm );
636515
637516 if (traces != null && traces .getTraces () != null ) {
638517 // Organization API worked (empty list with count=0 is valid - means no vulnerabilities or
0 commit comments