Skip to main content

Vulnerability Findings

Collects and processes Wiz Vulnerabilities logs from the Wiz API, ensuring continuous monitoring and reporting of vulnerabilities.

Sync Type: Incremental

Requirements

  • Before connecting Monad to Wiz, you need to obtain API credentials (Client ID and Client Secret). These credentials allow access to the Wiz API to fetch cloud configuration findings.
  • Ensure that your Wiz credentials have the appropriate permissions to access the necessary API endpoints. To access Vulnerabilities specifically, make sure your credentials have create:reports, read:vulnerabilities and update:reports permissions.

Details

Monad connects to the Wiz API to collect Vulnerabilities data. The connector operates on incremental syncs. For subsequent runs, the connector fetches all data since the report was first generated, and retrieves only vulnerabilities that were updated after this timestamp using the updatedAt filter on the Wiz API.

Configuration

The following configuration defines the input parameters. Each field's specifications, such as type, requirements, and descriptions, are detailed below.

Settings

SettingTypeRequiredDescription
Endpoint URLstringYesEndpoint URL to connect to Wiz.
Asset TypestringYesYour Wiz Asset Types for Vulnerability Findings.
Vendor SeverityArrayNoYour Wiz Vendor Severity for Vulnerability Findings.
Asset StatusArrayNoVulnerability Findings for assets with these statuses
StatusArrayNoThe status of a Vulnerability Finding.
Detection MethodArrayNoVulnerability Findings found via these detection methods.
Backfill Start TimestringNoThe date to start fetching data from. If not specified, no past records will be fetched.

Secrets

SecretTypeRequiredDescription
Client IDstringYesClient ID for the Wiz API. This is required to authenticate requests.
Client SecretstringYesClient Secret for the Wiz API. This is required to authenticate requests.

OCSF Conversion

The following JQ transformations convert Wiz Vulnerability data to OCSF Version 1.1.0 compliant format based on the selected asset type.

Container Image Asset Type

JQ Transformation

{
activity_id: 0,
category_uid: 2,
class_uid: 2002,

cloud: {
provider: .vulnerableAsset.cloudPlatform,
subscription: {
id: .vulnerableAsset.subscriptionId,
name: .vulnerableAsset.subscriptionName,
external_id: .vulnerableAsset.subscriptionExternalId
},
region: .vulnerableAsset.region
},

finding_info: {
title: .name,
desc: .description,
uid: .id,
status: .status,
resolution_reason: .resolutionReason,
resolved_at: (if .resolvedAt then (.resolvedAt | gsub("\\.[0-9]+"; "") | fromdateiso8601) else null end)
},

metadata: {
product: {
name: "Wiz",
vendor_name: "Wiz"
},
version: "1.1.0",
detection_details: {
method: .detectionMethod,
validation: .validatedInRuntime
},
source: {
name: .dataSourceName,
link: .link,
portal_url: .portalUrl
}
},

resource: {
type: .vulnerableAsset.type,
name: .vulnerableAsset.name,
id: .vulnerableAsset.id,
status: .vulnerableAsset.status,
image: {
id: .vulnerableAsset.imageId,
registry: .vulnerableAsset.registry.name,
repository: .vulnerableAsset.repository.name
},
tags: .vulnerableAsset.tags
},

severity_id: (
if .vendorSeverity == "MEDIUM" then 2
elif .vendorSeverity == "HIGH" then 3
elif .vendorSeverity == "LOW" then 1
elif .vendorSeverity == "CRITICAL" then 5
else 0
end
),

time: (if .firstDetectedAt then (.firstDetectedAt | gsub("\\.[0-9]+"; "") | fromdateiso8601) else 0 end),
start_time: (if .firstDetectedAt then (.firstDetectedAt | gsub("\\.[0-9]+"; "") | fromdateiso8601) else 0 end),
end_time: (if .lastDetectedAt then (.lastDetectedAt | gsub("\\.[0-9]+"; "") | fromdateiso8601) else 0 end),

type_uid: 200200,

vulnerabilities: [{
cve: {
uid: .name,
description: .CVEDescription
},
title: .name,
desc: .description,
remediation: {
desc: .remediation,
fixed_version: .fixedVersion
},
severity: .vendorSeverity,
scores: {
cvss_severity: .CVSSSeverity,
epss: {
percentile: .epssPercentile,
probability: .epssProbability,
severity: .epssSeverity
},
exploitability: .exploitabilityScore,
impact: .impactScore
},
package: {
name: .detailedName,
version: .version
},
metadata: {
has_exploit: .hasExploit,
has_cisa_kev_exploit: .hasCisaKevExploit
}
}]
}

OCSF Mapping Details for Container Image

Core Fields

  • Class UID: Set to 2002 (Vulnerability Finding)
  • Category UID: Set to 2 (Findings)
  • Type UID: Set to 200200 (Vulnerability Finding: Unknown)
  • Activity ID: Set to 0 (Unknown)
  • Time: Extracted from firstDetectedAt field
    • Strips milliseconds from ISO timestamp
    • Converts to Unix timestamp format
  • Severity ID: Maps from vendorSeverity with the following conversion:
    • CRITICAL → 5
    • HIGH → 3
    • MEDIUM → 2
    • LOW → 1
    • Others → 0

Cloud Information

  • Provider: Maps from vulnerableAsset.cloudPlatform
  • Subscription: Maps subscription details including:
    • ID: subscriptionId
    • Name: subscriptionName
    • External ID: subscriptionExternalId
  • Region: Maps from vulnerableAsset.region

Finding Information

  • Title: Maps from vulnerability name
  • Description: Maps from vulnerability description
  • UID: Maps from vulnerability ID
  • Status: Direct mapping from status field
  • Resolution: Includes both reason and timestamp

Resource Details

  • Type: Maps from vulnerableAsset.type
  • Name: Maps from vulnerableAsset.name
  • ID: Maps from vulnerableAsset.id
  • Image Information:
    • ID: Maps from imageId
    • Registry: Maps from registry.name
    • Repository: Maps from repository.name

Vulnerability Details

  • CVE Information:
    • UID: Maps from vulnerability name
    • Description: Maps from CVE description
  • Scores:
    • CVSS Severity
    • EPSS Details (percentile, probability, severity)
    • Exploitability Score
    • Impact Score
  • Package Information:
    • Name: Maps from detailedName
    • Version: Direct version mapping

Serverless Asset Type

JQ Transformation

def normalize_status:
if . == "Active" or . == "OPEN" then "Open"
elif . == "RESOLVED" then "Resolved"
elif . == "IN_PROGRESS" then "InProgress"
else .
end;

def normalize_severity:
if . == "CRITICAL" then "Critical"
elif . == "HIGH" then "High"
elif . == "MEDIUM" then "Medium"
elif . == "LOW" then "Low"
elif . == "INFORMATIONAL" or . == "NONE" then "Informational"
else .
end;

def clean_timestamp:
if . then
capture("^(?<date>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2})(?:\\.[0-9]+)?(?<tz>Z|[+-][0-9]{2}:[0-9]{2})?$") |
.date + (.tz // "Z")
else
null
end;

def get_first_detected:
if .FirstDetected then (.FirstDetected | clean_timestamp)
elif .firstDetectedAt and .firstDetectedAt != null then (.firstDetectedAt | clean_timestamp)
else (now | strftime("%Y-%m-%dT%H:%M:%SZ"))
end;

def get_severity:
if .Severity then .Severity
elif .vendorSeverity then (.vendorSeverity | normalize_severity)
else "Unknown"
end;

def get_status:
if .Status then (.Status | normalize_status)
elif .status then (.status | normalize_status)
else "Unknown"
end;

def get_cloud_platform:
if .CloudPlatform then .CloudPlatform
elif .vulnerableAsset.cloudPlatform then .vulnerableAsset.cloudPlatform
else "Unknown"
end;

def get_subscription_name:
if .SubscriptionName then .SubscriptionName
elif .vulnerableAsset.subscriptionName then .vulnerableAsset.subscriptionName
else "Unknown"
end;

def get_subscription_id:
if .SubscriptionExternalId then .SubscriptionExternalId
elif .vulnerableAsset.subscriptionExternalId then .vulnerableAsset.subscriptionExternalId
else "Unknown"
end;

def get_asset_id:
if .AssetID then .AssetID
elif .vulnerableAsset.id then .vulnerableAsset.id
else "Unknown"
end;

def get_asset_name:
if .AssetName then .AssetName
elif .vulnerableAsset.name then .vulnerableAsset.name
else "Unknown"
end;

def get_tags:
if .Tags then (.Tags | fromjson)
elif .vulnerableAsset.tags then .vulnerableAsset.tags
else {}
end;

{
category_uid: 2,
category_name: "Findings",
class_uid: 2002,
class_name: "Vulnerability Finding",

activity_id: (
if (get_status) == "Open" then 1
elif (get_status) == "Resolved" then 3
elif (get_status) == "InProgress" then 2
else 0
end
),

type_uid: (2002 * 100 + (
if (get_status) == "Open" then 1
elif (get_status) == "Resolved" then 3
elif (get_status) == "InProgress" then 2
else 0
end
)),

type_name: (
if (get_status) == "Open" then "Vulnerability Finding: Create"
elif (get_status) == "InProgress" then "Vulnerability Finding: Update"
elif (get_status) == "Resolved" then "Vulnerability Finding: Close"
else "Vulnerability Finding: Unknown"
end
),

severity_id: (
if (get_severity) == "Critical" then 5
elif (get_severity) == "High" then 4
elif (get_severity) == "Medium" then 3
elif (get_severity) == "Low" then 2
elif (get_severity) == "Informational" then 1
else 0
end
),
severity: get_severity,

time: (get_first_detected | if . then fromdateiso8601 else now end),
time_dt: get_first_detected,

cloud: {
provider: get_cloud_platform,
account: {
name: get_subscription_name,
uid: get_subscription_id
}
},

finding_info: {
uid: (.ID // .id),
title: (.Name // .name),
desc: (.Name // .name),
types: ["vulnerability"]
},

vulnerabilities: [{
uid: (.Name // .name),
title: (.Name // .name),
desc: (.Name // .name),
severity: (get_severity | ascii_downcase),
severity_id: (
if (get_severity) == "Low" then 0
elif (get_severity) == "Medium" then 1
elif (get_severity) == "High" then 2
elif (get_severity) == "Critical" then 3
else 99
end
)
}],

resources: [{
uid: get_asset_id,
name: get_asset_name,
labels: get_tags
}],
raw_data: (. | tostring),
metadata: {
version: "1.1.0",
product: {
name: "Wiz",
vendor_name: "Wiz",
feature: {
name: "Vulnerability Scanner"
}
}
}
}

OCSF Mapping Details for Serverless

Core Fields

  • Category: ID 2 (Findings)
  • Class: ID 2002 (Vulnerability Finding)
  • Activity ID: Determined by status:
    • Open → 1 (Create)
    • InProgress → 2 (Update)
    • Resolved → 3 (Close)
    • Others → 0 (Unknown)
  • Type UID: Calculated as (2002 * 100 + activity_id)
  • Severity ID: Maps from Severity with the following conversion:
    • Critical → 5
    • High → 4
    • Medium → 3
    • Low → 2
    • Informational → 1
    • Others → 0

Finding Information

  • UID: Maps from ID
  • Title: Maps from Name
  • Description: Maps from Name
  • Types: Fixed as ["vulnerability"]

Cloud Information

  • Provider: Maps from CloudPlatform
  • Account:
    • Name: Maps from SubscriptionName
    • UID: Maps from SubscriptionExternalId

Resource Information

  • UID: Maps from AssetID
  • Name: Maps from AssetName
  • Labels: Parsed from JSON Tags

Metadata

  • Version: Set to "1.1.0"
  • Product:
    • Name: "Wiz"
    • Vendor Name: "Wiz"
    • Feature Name: "Vulnerability Scanner"

Customization Notes

Both transformations serve as starting points and can be modified to accommodate specific requirements while maintaining OCSF compliance. The mappings prioritize essential vulnerability and asset information while providing appropriate handling of status transitions and severity levels.

Sample Record

{
"ID": "256446d3-ee8b-d072-ef09-39404db0e529",
"WizURL": "https://app.wiz.io/graph#~(query~(type~(~'SECURITY_TOOL_FINDING)~select~true~relationships~(~(type~(~(type~'ALERTED_ON))~with~(type~(~'CLOUD_RESOURCE)~select~true~where~(_vertexID~(EQUALS~(~'8dbbcefd-bd73-5d7c-affc-80557fb625d5))))))~where~(_vertexID~(EQUALS~(~'c47be128-6366-5752-aedf-60b9c7bb4b18)))))",
"Name": "Jane Jones",
"CVEDescription": "A use after free vulnerability exists in curl <7.87.0. Curl can be asked to *tunnel* virtually all protocols it supports through an HTTP proxy. HTTP proxies can (and often do) deny such tunnel operations. When getting denied to tunnel the specific protocols SMB or TELNET, curl would use a heap-allocated struct after it had been freed, in its transfer shutdown code path.",
"CVSSSeverity": "Medium",
"Score": 8.1,
"ExploitabilityScore": 10,
"ImpactScore": 8.1,
"HasExploit": false,
"HasCisaKevExploit": false,
"FindingStatus": "Open",
"VendorSeverity": "Low",
"FirstDetected": "2025-08-11T23:46:39.030697Z",
"LastDetected": "2025-08-11T23:46:39.030702Z",
"ResolvedAt": null,
"ResolutionReason": null,
"Description": "The package `curl` version `7.76.1-19.el9` was detected in `YUM/DNF package manager` on a machine running `RedHat 9.1` is vulnerable to `CVE-2022-43552`, which exists in `all current versions`.",
"Remediation": null,
"LocationPath": null,
"DetailedName": "curl",
"Version": "7.76.1-19.el9",
"FixedVersion": null,
"DetectionMethod": "Package",
"Link": "https://access.redhat.com/security/cve/CVE-2022-43552",
"Projects": [
"Project 2",
"project 4",
"Project1"
],
"AssetID": "d6ab3d20-b2cb-56d9-e79e-c8398e5a0353",
"AssetName": "test-12",
"AssetRegion": "us-east-1",
"ProviderUniqueId": "arn:aws:ec2:us-east-1:998231069301:instance/i-087bbaed3305df222",
"CloudProviderURL": "https://us-east-1.console.aws.amazon.com/ec2/v2/home?region=us-east-1#InstanceDetails:instanceId=i-087bbaed3305df222",
"CloudPlatform": "AWS",
"Status": "Active",
"SubscriptionExternalId": "998231000000",
"SubscriptionId": "94e76baa-85fd-5928-b829-1669a2ca9660",
"SubscriptionName": "wiz-integrations",
"Tags": {
"Name": "test-12"
},
"OperatingSystem": "Linux",
"IpAddresses": [
"43.205.164.184",
"175.186.149.232"
]
}