Zafran API

The Zafran API provides a programmatic way to interact with the Zafran Exposure Management Platform for various use cases.

Utilities · Zafran

Details

IDZafran API
ProviderZafran Security
CategoryUtilities
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

In today’s complex security landscape, resource-constrained teams struggle to efficiently mitigate exposure risks across large infrastructures. The Zafran Integration with Palo XSOAR helps you implement Automated, High Impact Mitigations at scale. With this integration, teams can prioritize mitigation actions, trigger playbooks with a single click, and streamline their response efforts, all from within the Palo XSOAR environment.

Configure Zafran API on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for Zafran API.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Required
    Server URL (e.g. api.zafran.io) True
    API Key True
    Trust any certificate (not secure) False
    Use system proxy settings False
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

zafran-mitigation-performed


Update on mitigations performed

Base Command

zafran-mitigation-performed

Input

Argument Name Description Required
external_ticket_id External service ticket ID. Optional
external_ticket_url External service ticket link. Optional
id Mitigation ID. Required
state Mitigation status new - New mitigation pending_approval - Waiting for mitigation approval rejected - Mitigative action was rejected. in_progress - Mitigation approved and in progress. completed - Mitigation applied successfully. Possible values are: new, pending_approval, rejected, in_progress, completed. Required

Context Output

Path Type Description
Zafran.MitigationsPerformedResponse.internal_status_code Number Internal status code.
Zafran.MitigationsPerformedResponse.message String Error message.

zafran-mitigations-export


Export recommended mitigations

Base Command

zafran-mitigations-export

Input

Argument Name Description Required
filter ZQL filter. Optional

Context Output

Path Type Description
Zafran.UpstreamMitigation.assets_count Number Assets count.
Zafran.UpstreamMitigation.control_product String Control Product.
Zafran.UpstreamMitigation.exposure Number Exposure in days.
Zafran.UpstreamMitigation.id String Zafran mitigation unique id.
Zafran.UpstreamMitigation.mitigation_type String Mitigation type.
Zafran.UpstreamMitigation.recommendation String Recommendation.
Zafran.UpstreamMitigation.title String Title.
Zafran.UpstreamMitigation.vulnerabilities_count Number Vulnerabilities count.
Zafran.UpstreamMitigation.internal_status_code Number Internal status code.
Zafran.UpstreamMitigation.message String Error message

zafran-mitigations-performed


Update on mitigations performed

Base Command

zafran-mitigations-performed

Input

Argument Name Description Required
mitigation_id Mitigation ID. Optional
mitigation_ids Mitigation IDs. Optional
state Mitigation status new - New mitigation pending_approval - Waiting for mitigation approval rejected - Mitigative action was rejected. in_progress - Mitigation approved and in progress. completed - Mitigation applied successfully. Possible values are: new, pending_approval, rejected, in_progress, completed. Required

Context Output

Path Type Description
Zafran.MitigationsPerformedResponse.internal_status_code Number Internal status code.
Zafran.MitigationsPerformedResponse.message String Error message.

Configuration parameters

  • url — Server URL (e.g. api.zafran.io) (required)
  • api_key — API Key (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (3)

  • zafran-mitigation-performed

    Update on mitigations performed

  • zafran-mitigations-export

    Export recommended mitigations.

  • zafran-mitigations-performed

    Update on mitigations performed

import demistomock as demisto
from CommonServerPython import *


class Client(BaseClient):
    def __init__(self, server_url, verify, proxy, headers, auth):
        super().__init__(base_url=server_url, verify=verify, proxy=proxy, headers=headers, auth=auth)

    def findings_request(self, count):
        params = assign_params(count=count)
        headers = self._headers

        response = self._http_request("post", "findings", params=params, headers=headers, return_empty_response=True)

        return response

    def mitigation_performed_request(
        self,
        mitigationstatus_external_ticket_id,
        mitigationstatus_external_ticket_url,
        mitigationstatus_id,
        mitigationstatus_state,
    ):
        data = assign_params(
            external_ticket_id=mitigationstatus_external_ticket_id,
            external_ticket_url=mitigationstatus_external_ticket_url,
            id=mitigationstatus_id,
            state=mitigationstatus_state,
        )
        headers = self._headers

        response = self._http_request("post", "mitigations/performed", json_data=data, headers=headers)

        return response

    def mitigations_export_request(self, filter_):
        params = assign_params(filter=filter_)
        headers = self._headers

        response = self._http_request("get", "mitigations", params=params, headers=headers)

        return response

    def mitigations_performed_request(
        self, mitigationsstatus_mitigation_id, mitigationsstatus_mitigation_ids, mitigationsstatus_state
    ):
        data = assign_params(
            mitigation_id=mitigationsstatus_mitigation_id,
            mitigation_ids=mitigationsstatus_mitigation_ids,
            state=mitigationsstatus_state,
        )
        headers = self._headers

        response = self._http_request("post", "mitigations", json_data=data, headers=headers)

        return response


def mitigation_performed_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    mitigationstatus_external_ticket_id = args.get("external_ticket_id", "")
    mitigationstatus_external_ticket_url = args.get("external_ticket_url", "")
    mitigationstatus_id = args.get("id", "")
    mitigationstatus_state = args.get("state", "")

    response = client.mitigation_performed_request(
        mitigationstatus_external_ticket_id, mitigationstatus_external_ticket_url, mitigationstatus_id, mitigationstatus_state
    )
    command_results = CommandResults(
        outputs_prefix="Zafran.MitigationsPerformedResponse",
        outputs_key_field="",
        outputs=response,
        readable_output="Mitigation status updated successfully",
        raw_response=response,
    )

    return command_results


def mitigations_export_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    filter_arg = args.get("filter", "")

    response = client.mitigations_export_request(filter_arg)
    human_readable = tableToMarkdown("Zafran Mitigations", response, headerTransform=string_to_table_header)
    command_results = CommandResults(
        outputs_prefix="Zafran.UpstreamMitigation",
        outputs_key_field="id",
        outputs=response,
        readable_output=human_readable,
        raw_response=response,
    )

    return command_results


def mitigations_performed_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    mitigationsstatus_mitigation_id = args.get("mitigation_id", "")
    mitigationsstatus_mitigation_ids = argToList(args.get("mitigation_ids", []))
    mitigationsstatus_state = args.get("state", "")

    response = client.mitigations_performed_request(
        mitigationsstatus_mitigation_id, mitigationsstatus_mitigation_ids, mitigationsstatus_state
    )

    command_results = CommandResults(
        outputs_prefix="Zafran.MitigationsPerformedResponse",
        outputs_key_field="",
        outputs=response,
        readable_output="Mitigations status updated successfully",
        raw_response=response,
    )

    return command_results


def api_test_connection(client: Client) -> str:
    try:
        response = client.findings_request(0)
        # Test functions here
        if response.status_code == 204:
            return "ok"
    except DemistoException:
        pass
    return "API test failed"


def main() -> None:
    params: Dict[str, Any] = demisto.params()
    args: Dict[str, Any] = demisto.args()
    url = params.get("url")
    verify_certificate: bool = not params.get("insecure", False)
    proxy = params.get("proxy", False)
    headers = {}
    headers["Authorization"] = "Bearer " + params["api_key"]

    command = demisto.command()
    demisto.debug(f"Command being called is {command}")

    try:
        requests.packages.urllib3.disable_warnings()  # type: ignore
        client: Client = Client(urljoin(url, "/api/v2/"), verify_certificate, proxy, headers=headers, auth=None)

        commands = {
            "zafran-mitigation-performed": mitigation_performed_command,
            "zafran-mitigations-export": mitigations_export_command,
            "zafran-mitigations-performed": mitigations_performed_command,
        }

        if command == "test-module":
            return_results(api_test_connection(client))
        elif command in commands:
            return_results(commands[command](client, args))
        else:
            raise NotImplementedError(f"{command} command is not implemented.")

    except Exception as e:
        return_error(str(e))


if __name__ in ["__main__", "builtin", "builtins"]:
    main()