Skip to content

Commit

Permalink
InsightVM - 273 - Updated the documentation with links related to que…
Browse files Browse the repository at this point in the history
…ry builder and operators | Updated the SDK (#2153)
  • Loading branch information
igorski-r7 authored Nov 29, 2023
1 parent e0d555d commit 6208c37
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 141 deletions.
2 changes: 1 addition & 1 deletion plugins/rapid7_insightvm_cloud/.CHECKSUM
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"spec": "6898a8d3dcf35326c62bafd1839a3e31",
"spec": "816005aeeca47b3dc400aeb7bcb867d2",
"manifest": "9b38d02526a7afbb04657bcaccec85e2",
"setup": "553502e1e832fa699fdc97d3d133ae51",
"schemas": [
Expand Down
2 changes: 1 addition & 1 deletion plugins/rapid7_insightvm_cloud/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rapid7/insightconnect-python-3-plugin:5
FROM rapid7/insightconnect-python-3-slim-plugin:5

LABEL organization=rapid7
LABEL sdk=python
Expand Down
107 changes: 71 additions & 36 deletions plugins/rapid7_insightvm_cloud/help.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self):
self.session = None
self.region = None

def connect(self, params):
def connect(self, params={}):
self.logger.info("Connect: Connecting...")
self.region = params.get(Input.REGION)
self.api_url = f"https://{self.region}.api.insight.rapid7.com/vm/v4/integration/"
Expand Down
55 changes: 32 additions & 23 deletions plugins/rapid7_insightvm_cloud/plugin.spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ support: rapid7
supported_versions: ["InsightVM Cloud Integration API v4", "2023-11-24"]
status: []
cloud_ready: true
sdk:
type: slim
version: 5
user: nobody
resources:
source_url: https://github.com/rapid7/insightconnect-plugins/tree/master/plugins/rapid7_insightvm_cloud
license_url: https://github.com/rapid7/insightconnect-plugins/blob/master/LICENSE
Expand All @@ -22,7 +26,6 @@ hub_tags:
use_cases: [asset_inventory, vulnerability_management]
keywords: [insightvm, rapid7, cloud, cloud_enabled]
features: []

types:
link:
href:
Expand Down Expand Up @@ -988,7 +991,6 @@ connection:
- au
- ap
example: us

actions:
start_scan:
title: Start Scan
Expand All @@ -998,42 +1000,45 @@ actions:
title: Asset IDs
description: IDs of the assets to scan
type: "[]string"
example: ["abc978-5678-abc-a5a94a1234b8-asset"]
required: false
example: '["abc978-5678-abc-a5a94a1234b8-asset"]'
name:
title: Name
description: The name of the scan
type: string
example: "test cloud scan"
required: true
example: "test cloud scan"
ips:
title: IPs
description: List of IPv4 or IPv6 addresses to scan
type: "[]string"
example: ["2001:db8:1:1:1:1:1:1"]
required: false
example: '["2001:db8:1:1:1:1:1:1"]'
hostnames:
title: Hostnames
description: List of hostnames to scan
type: "[]string"
example: ["rapid7.com"]
required: false
example: '["rapid7.com"]'
output:
ids:
description: List of identifiers of the scans started
title: Scan IDs
type: "[]string"
required: false
example: '["5058b0b4-701a-414e-9630-430d2cddbf4d"]'
asset_ids:
description: List of identifiers of the assets scanned
title: Asset IDs
type: "[]string"
required: false
example: '["5058b0b4-701a-414e-9630-430d2cddbf4d"]'
data:
description: Information received about the scan
title: Data
type: object
required: false
example: '{"scans":[{"engine_id":"5058b0b4-701a-414e-9630-430d2cddbf4d","id":"5058b0b4-701a-414e-9630-430d2cddbf4d","name":"TestScan","asset_ids":["5058b0b4-701a-414e-9630-430d2cddbf4d"]}],"unscanned_assets":[{"id":"5058b0b4-701a-414e-9630-430d2cddbf4d","reason":"Asset has never been scanned with an InsightVM Platform registered engine."}]}'
get_scan:
title: Get Scan
description: Get the status of a scan
Expand All @@ -1042,45 +1047,45 @@ actions:
title: Scan ID
description: ID of the scan to obtain
type: string
example: "abb37782-df95-4cf6-b4c2-8d466ca57349"
required: true
example: "abb37782-df95-4cf6-b4c2-8d466ca57349"
output:
asset_ids:
description: List of IDs of the scanned assets
title: Asset IDs
type: "[]string"
example: ["abc978-5678-abc-a5a94a1234b8-asset"]
required: false
example: '["abc978-5678-abc-a5a94a1234b8-asset"]'
scan_id:
description: ID of the scan
title: Scan ID
type: string
example: "a9870dce1234180e202af83b66cd0c4b"
required: false
example: "a9870dce1234180e202af83b66cd0c4b"
name:
description: User-driven scan name for the scan
title: Name
type: string
example: "testing scan action"
required: false
example: "testing scan action"
status:
description: Current status of the retrieved scan
title: Status
type: string
example: "Stopped"
required: false
example: "Stopped"
started:
description: When the scan was started
title: Started
type: date
example: "2021-04-15T17:56:47Z"
required: false
example: "2021-04-15T17:56:47Z"
finished:
description: When the scan was finished
title: Finished
type: date
example: "2021-04-15T18:00:33Z"
required: false
example: "2021-04-15T18:00:33Z"
asset_search:
title: Asset Search
description: Search for assets using filtered asset search
Expand All @@ -1097,37 +1102,38 @@ actions:
description: JSON object for sorting by criteria. Multiple criteria can be specified with an order of 'asc' (ascending) or 'desc' (descending)
type: object
required: false
example: "{'risk-score': 'asc', 'criticality-tag': 'desc'}"
example: '{"risk-score": "asc", "criticality-tag": "desc"}'
asset_criteria:
title: Asset Criteria
description: Filters to apply to the asset search such as IPv4 or IPv6 addresses and hostnames
type: string
example: "asset.ipv4 = 2001:db8:1:1:1:1:1:1 || asset.name STARTS WITH 'example'"
required: false
example: "asset.ipv4 = 2001:db8:1:1:1:1:1:1 || asset.name STARTS WITH 'example'"
vuln_criteria:
title: Vulnerability Criteria
description: Vulnerability criteria to filter by
type: string
example: "vulnerability.categories IN ['example']"
required: false
example: "vulnerability.categories IN ['example']"
current_time:
title: Current Time
description: The current date and time to compare against the asset state to detect changes
type: date
example: "2021-04-15T17:56:47Z"
required: false
example: "2021-04-15T17:56:47Z"
comparison_time:
title: Comparison Time
description: The date and time to compare the asset current state against to detect changes
type: date
example: "2021-04-15T17:56:47Z"
required: false
example: "2021-04-15T17:56:47Z"
output:
assets:
title: Assets
description: List of asset details returned by the search
type: '[]asset'
required: true
example: '[{"assessed_for_policies":false,"assessed_for_vulnerabilities":true,"credential_assessments":[],"critical_vulnerabilities":12,"exploits":5,"id":"cdc978de-4178-a1d9-d5a94a114b87-example","ip":"2001:db8:1:1:1:1:1:1","last_assessed_for_vulnerabilities":"2020-06-25T15:19:51.543Z","last_scan_end":"2020-10-26T22:35:53.590Z","last_scan_start":"2020-10-26T22:35:53.564Z","mac":"00:50:56:94:52:04","malware_kits":0,"moderate_vulnerabilities":4,"new":[],"os_architecture":"","os_description":"Linux 2.6.32","os_family":"Linux","os_name":"Linux","os_system_name":"Linux","os_type":"General","os_vendor":"Linux","os_version":"2.6.32","remediated":[],"risk_score":9304.376953125,"severe_vulnerabilities":21,"tags":[{"name":"integrations discovery","type":"SITE"}],"total_vulnerabilities":37,"unique_identifiers":[]},{"assessed_for_policies":false,"assessed_for_vulnerabilities":true,"credential_assessments":[],"critical_vulnerabilities":12,"exploits":5,"id":"cdc978de-4178-a1d9-d5a94a114b87-example","ip":"2001:db8:1:1:1:1:1:1","last_assessed_for_vulnerabilities":"2020-06-25T15:19:51.543Z","last_scan_end":"2020-10-26T22:35:53.590Z","last_scan_start":"2020-10-26T22:35:53.564Z","mac":"00:50:56:94:52:04","malware_kits":0,"moderate_vulnerabilities":4,"new":[],"os_architecture":"","os_description":"Linux 2.6.32","os_family":"Linux","os_name":"Linux","os_system_name":"Linux","os_type":"General","os_vendor":"Linux","os_version":"2.6.32","remediated":[],"risk_score":9304.376953125,"severe_vulnerabilities":21,"tags":[{"name":"integrations discovery","type":"SITE"}],"total_vulnerabilities":37,"unique_identifiers":[]}]'
get_asset:
title: Get Asset
description: Gets an asset by ID
Expand All @@ -1151,11 +1157,13 @@ actions:
description: Asset details
type: asset
required: true
example: '{"assessed_for_policies":false,"assessed_for_vulnerabilities":true,"credential_assessments":[{"port":22,"protocol":"TCP","status":"NO_CREDS_SUPPLIED"}],"critical_vulnerabilities":1,"exploits":2,"host_name":"example.rapid7.com","id":"cdc978de-4178-a1d9-d5a94a114b87-example","ip":"2001:db8:1:1:1:1:1:1","last_assessed_for_vulnerabilities":"2021-04-26T08:04:28.536Z","last_scan_end":"2021-04-26T08:04:28.536Z","last_scan_start":"2021-04-26T08:00:56.006Z","mac":"00:50:56:94:42:6B","malware_kits":0,"moderate_vulnerabilities":7,"new":[],"remediated":[],"risk_score":9006.3388671875,"severe_vulnerabilities":19,"tags":[{"name":"sn_pt_LDAP Admins","type":"OWNER"},{"name":"sn_CAB Approval","type":"OWNER"},{"name":"integrations","type":"CUSTOM"},{"name":"ck_test_site_2","type":"SITE"},{"name":"integrations","type":"SITE"},{"name":"ck_test_site_3","type":"SITE"},{"name":"integrations discovery","type":"SITE"},{"name":"ck_test_site_1","type":"SITE"}],"total_vulnerabilities":27,"unique_identifiers":[]}'
vulnerabilities:
title: Vulnerabilities
description: Vulnerabilities associated with the asset
type: '[]asset_vulnerability'
required: false
example: []
stop_scan:
title: Stop Scan
description: Stop a scan in progress
Expand All @@ -1171,20 +1179,20 @@ actions:
title: Success
description: Was operation successful
type: boolean
example: true
required: true
example: true
status_code:
title: Status Code
description: Code returned by API call
type: integer
example: 400
required: false
example: 400
message:
title: Message
description: Reason why the action failed
type: string
example: "The scan could not be stopped"
required: false
example: "The scan could not be stopped"
vuln_search:
title: Vulnerability Search
description: Search for vulnerabilities using filtered vulnerability search
Expand All @@ -1201,16 +1209,17 @@ actions:
description: JSON object for sorting by criteria. Multiple criteria can be specified with an order of 'asc' (ascending) or 'desc' (descending)
type: object
required: false
example: "{'risk-score': 'asc', 'criticality-tag': 'desc'}"
example: '{"risk-score": "asc", "criticality-tag": "desc"}'
vuln_criteria:
title: Vulnerability Criteria
description: Vulnerability criteria to filter by
type: string
example: "vulnerability.categories IN ['example']"
required: false
example: "vulnerability.categories IN ['example']"
output:
vulnerabilities:
title: Vulnerabilities
description: Vulnerabilities associated with the asset
type: '[]vulnerability'
required: true
example: '[{"added":"2018-05-16T00:00:00Z","categories":"7-Zip","cves":"CVE-1234-5678","cvss_v2_access_complexity":"low","cvss_v2_access_vector":"network","cvss_v2_authentication":"none","cvss_v2_availability_impact":"complete","cvss_v2_confidentiality_impact":"complete","cvss_v2_exploit_score":9.996799945831299,"cvss_v2_impact_score":10.000845454680942,"cvss_v2_integrity_impact":"complete","cvss_v2_score":10,"cvss_v2_vector":"(AV:N/AC:L/Au:N/C:C/I:C/A:C)","cvss_v3_attack_complexity":null,"cvss_v3_attack_vector":null,"cvss_v3_availability_impact":null,"cvss_v3_confidentiality_impact":null,"cvss_v3_exploit_score":0,"cvss_v3_impact_score":null,"cvss_v3_integrity_impact":null,"cvss_v3_privileges_required":null,"cvss_v3_scope":null,"cvss_v3_score":0,"cvss_v3_user_interaction":null,"cvss_v3_vector":null,"denial_of_service":false,"description":"Unspecified vulnerability in 7-zip before 4.5.7 has unknown impact and remote attack vectors, as demonstrated by the PROTOS GENOME test suite for Archive Formats (c10).","exploits":[],"id":"7-zip-cve-1234-5678","links":[{"href":"http://www.example.com","id":"http://www.example.com","source":"url"}],"malware_kits":[],"modified":"2018-06-08T00:00:00Z","pci_cvss_score":10,"pci_fail":true,"pci_severity_score":5,"pci_special_notes":"","pci_status":"fail","published":"2009-03-29T00:00:00Z","references":"http://www.example.com","risk_score":898.76,"severity":"critical","severity_score":10,"title":"7-Zip: CVE-1234-5678: Unspecified vulnerability in 7-zip before 4.5.7"},{"added":"2018-05-16T00:00:00Z","categories":"7-Zip,Remote Execution","cves":"CVE-1234-5678","cvss_v2_access_complexity":"medium","cvss_v2_access_vector":"network","cvss_v2_authentication":"none","cvss_v2_availability_impact":"complete","cvss_v2_confidentiality_impact":"complete","cvss_v2_exploit_score":8.588799953460693,"cvss_v2_impact_score":10.000845454680942,"cvss_v2_integrity_impact":"complete","cvss_v2_score":9.3,"cvss_v2_vector":"(AV:N/AC:M/Au:N/C:C/I:C/A:C)","cvss_v3_attack_complexity":"low","cvss_v3_attack_vector":"local","cvss_v3_availability_impact":"high","cvss_v3_confidentiality_impact":"high","cvss_v3_exploit_score":1.8345765900000002,"cvss_v3_impact_score":5.873118720000001,"cvss_v3_integrity_impact":"high","cvss_v3_privileges_required":"none","cvss_v3_scope":"unchanged","cvss_v3_score":7.8,"cvss_v3_user_interaction":"required","cvss_v3_vector":"CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","denial_of_service":false,"description":"Heap-based buffer overflow in the NArchive::NHfs::CHandler::ExtractZlibFile method in 7zip before 16.00 and p7zip allows remote attackers to execute arbitrary code via a crafted HFS+ image.","exploits":[],"id":"7-zip-cve-1234-5678","links":[{"href":"http://www.example.com","id":"http://www.example.com","source":"url"}],"malware_kits":[],"modified":"2018-06-08T00:00:00Z","pci_cvss_score":9.3,"pci_fail":true,"pci_severity_score":5,"pci_special_notes":"","pci_status":"fail","published":"2016-12-13T00:00:00Z","references":"http://www.example.com","risk_score":718.8,"severity":"critical","severity_score":9,"title":"7-Zip: CVE-1234-5678: Heap-based buffer overflow vulnerability"}]'
13 changes: 9 additions & 4 deletions plugins/rapid7_insightvm_cloud/unit_test/mock.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import json
import os

from utils import DEFAULT_ENCODING

STUB_ASSET_ID = "5058b0b4-701a-414e-9630-430d2cddbf4d"
STUB_BAD_ASSET_ID = "5058b0b4-701a-414e-9630-430d2cddbf4e"
STUB_SEARCH_ID = "86a8abc0-95f3-4353-adf5-abb631c1f824"
STUB_BAD_ASSET_CRITERIA = "invalid asset criteria"
STUB_BAD_VULN_CRITERIA = "invalid vuln criteria"
STUB_SCAN_ID = "5058b0b4-701a-414e-9630-430d2cddbf4d"
STUB_BAD_SCAN_ID = "invalid scan id"
STUB_BAD_SECRET_KEY = "secret_key_invalid"
STUB_SECRET_KEY_SERVER_ERROR = "secret_key_server_error"
STUB_BAD_SECRET_KEY = "secret_key_invalid" # nosec B105
STUB_SECRET_KEY_SERVER_ERROR = "secret_key_server_error" # nosec B105
STUB_SCAN_NAME = "TestScan"
STUB_SCAN_NAME_NO_ASSET_IDS = "TestScanNoAssetIDs"
STUB_SCAN_NAME_INVALID_ASSET_IDS = "TestScanInvalidAssetIDs"
Expand All @@ -31,7 +33,8 @@ def __init__(self, filename: str, status_code: int) -> None:
self.status_code = status_code
if filename:
with open(
os.path.join(os.path.dirname(os.path.realpath(__file__)), f"payloads/{filename}.json.resp")
os.path.join(os.path.dirname(os.path.realpath(__file__)), f"payloads/{filename}.json.resp"),
encoding=DEFAULT_ENCODING,
) as file:
self.text = file.read()
else:
Expand All @@ -41,7 +44,8 @@ def json(self):
return json.loads(self.text)


def mock_request_post(url, params, headers, data):
def mock_request_post(url, params, headers, data): # noqa: MC0001
# pylint: disable=unused-argument
if headers.get("x-api-key") == STUB_BAD_SECRET_KEY:
return MockResponse("unauthorized", 401)
if headers.get("x-api-key") == STUB_SECRET_KEY_SERVER_ERROR:
Expand Down Expand Up @@ -72,6 +76,7 @@ def mock_request_post(url, params, headers, data):


def mock_request_get(url, params, headers, data):
# pylint: disable=unused-argument
if headers.get("x-api-key") == STUB_BAD_SECRET_KEY:
return MockResponse("unauthorized", 401)
if headers.get("x-api-key") == STUB_SECRET_KEY_SERVER_ERROR:
Expand Down
26 changes: 13 additions & 13 deletions plugins/rapid7_insightvm_cloud/unit_test/test_asset_search.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import sys
import os
import sys

from insightconnect_plugin_runtime.exceptions import PluginException

sys.path.append(os.path.abspath("../"))

from unittest import TestCase
from jsonschema import validate
from unittest.mock import MagicMock, patch

from icon_rapid7_insightvm_cloud.actions.asset_search import AssetSearch
from icon_rapid7_insightvm_cloud.actions.asset_search.schema import Input, AssetSearchOutput
from icon_rapid7_insightvm_cloud.actions.asset_search.schema import AssetSearchOutput, Input
from icon_rapid7_insightvm_cloud.connection.schema import Input as ConnectionInput
from unittest.mock import patch
from jsonschema import validate

from mock import mock_request
from utils import Utils
from mock import (
mock_request,
)


class TestAssetSearch(TestCase):
Expand All @@ -36,7 +36,7 @@ def setUp(self) -> None:

# test finding event via all inputs
@patch("requests.request", side_effect=mock_request)
def test_asset_search_all_inputs(self, _mock_req):
def test_asset_search_all_inputs(self, _mock_req: MagicMock) -> None:
actual = self.action.run(
{
Input.ASSET_CRITERIA: self.params.get("asset_criteria"),
Expand All @@ -51,15 +51,15 @@ def test_asset_search_all_inputs(self, _mock_req):

# test finding event via all inputs
@patch("requests.request", side_effect=mock_request)
def test_asset_search_no_input(self, _mock_req):
def test_asset_search_no_input(self, _mock_req: MagicMock) -> None:
actual = self.action.run()
expected = Utils.read_file_to_dict("expected_responses/asset_search.json.resp")
self.assertEqual(expected, actual)
validate(actual, AssetSearchOutput.schema)

# test finding event via all inputs
@patch("requests.request", side_effect=mock_request)
def test_asset_invalid_asset_criteria(self, _mock_req):
def test_asset_invalid_asset_criteria(self, _mock_req: MagicMock) -> None:
with self.assertRaises(PluginException) as context:
self.action.run(
{
Expand All @@ -78,7 +78,7 @@ def test_asset_invalid_asset_criteria(self, _mock_req):

# test finding event via all inputs
@patch("requests.request", side_effect=mock_request)
def test_asset_vuln_criteria_invalid(self, _mock_req):
def test_asset_vuln_criteria_invalid(self, _mock_req: MagicMock) -> None:
with self.assertRaises(PluginException) as context:
self.action.run(
{
Expand All @@ -96,7 +96,7 @@ def test_asset_vuln_criteria_invalid(self, _mock_req):
self.assertEqual(str(data), context.exception.data)

@patch("requests.request", side_effect=mock_request)
def test_asset_search_invalid_secret_key(self, _mock_req):
def test_asset_search_invalid_secret_key(self, _mock_req: MagicMock) -> None:
self.connection, self.action = Utils.default_connector(
AssetSearch(),
{ConnectionInput.REGION: "us", ConnectionInput.CREDENTIALS: {"secretKey": "secret_key_invalid"}},
Expand All @@ -109,7 +109,7 @@ def test_asset_search_invalid_secret_key(self, _mock_req):
self.assertEqual(assistance, context.exception.assistance)

@patch("requests.request", side_effect=mock_request)
def test_asset_search_server_error(self, _mock_req):
def test_asset_search_server_error(self, _mock_req: MagicMock) -> None:
self.connection, self.action = Utils.default_connector(
AssetSearch(),
{ConnectionInput.REGION: "us", ConnectionInput.CREDENTIALS: {"secretKey": "secret_key_server_error"}},
Expand Down
Loading

0 comments on commit 6208c37

Please sign in to comment.