Google Safe Browsing v2
Search Safe Browsing, The Safe Browsing APIs (v4) let your client applications check URLs against Google's constantly updated lists of unsafe web resources.
Data Enrichment & Threat Intelligence · Google Safe Browsing
Details
| ID | Google Safe Browsing v2 |
|---|---|
| Provider | |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Search Safe Browsing v4
Configure GoogleSafeBrowsing in Cortex
| Parameter | Description | Required |
|---|---|---|
| API Key | True | |
| Client ID | True | |
| Client Version | True | |
| Base URL | True | |
| Source Reliability | Reliability of the source providing the intelligence data. | True |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False |
Commands
You can execute these commands from the 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.
url
Check URL Reputation
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | URL to check. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | string | The indicator that was tested. |
| DBotScore.Type | string | The indicator type. |
| DBotScore.Vendor | string | The vendor used to calculate the score. |
| DBotScore.Score | int | The actual score. |
| DBotScore.Reliability | string | Reliability of the source providing the intelligence data. |
| GoogleSafeBrowsing.URL.cacheDuration | string | The URL cache duration time. |
| GoogleSafeBrowsing.URL.threatType | string | The URL threat type. |
| GoogleSafeBrowsing.URL.threatEntryType | string | The URL threat entry type. |
| GoogleSafeBrowsing.URL.platformType | string | The URL platform type. |
| URL.Data | string | Bad URLs found |
| URL.Malicious.Vendor | string | For malicious URLs, the vendor that made the decision |
| URL.Malicious.Description | string | For malicious URLs, the reason for the vendor to make the decision |
Command Example
!url url="http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"
Context Example
{
"DBotScore": {
"Indicator": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/",
"Reliability": "C - Fairly reliable",
"Score": 3,
"Type": "url",
"Vendor": "GoogleSafeBrowsing"
},
"URL": {
"Data": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/",
"Malicious": {
"Description": "Match found: MALWARE/ANY_PLATFORM,MALWARE/WINDOWS,MALWARE/LINUX,MALWARE/ALL_PLATFORMS,MALWARE/OSX,MALWARE/CHROME",
"Vendor": "GoogleSafeBrowsing"
}
}
}
Human Readable Output
Google Safe Browsing APIs - URL Query
Found matches for URL http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/
cacheDuration platformType threat threatEntryType threatType 300s ANY_PLATFORM {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE 300s WINDOWS {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE 300s LINUX {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE 300s ALL_PLATFORMS {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE 300s OSX {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE 300s CHROME {“url”:”http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/”} URL MALWARE
Configuration parameters
url— Your server URL (required)client_id— The Client IDclient_version— The Client Versionapi_key— API Keyapi_creds— The Client IDintegrationReliability— Source Reliability (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (1)
-
urlSearches for the specified URL on lists.
from typing import Any import demistomock as demisto import urllib3 from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa # Disable insecure warnings urllib3.disable_warnings() TYPES = { "threatTypes": ["MALWARE", "SOCIAL_ENGINEERING", "POTENTIALLY_HARMFUL_APPLICATION", "UNWANTED_SOFTWARE"], "platformTypes": ["ANY_PLATFORM", "WINDOWS", "LINUX", "ALL_PLATFORMS", "OSX", "CHROME", "IOS", "ANDROID"], } INTEGRATION_NAME = "GoogleSafeBrowsing" URL_OUTPUT_PREFIX = "GoogleSafeBrowsing.URL" class Client(BaseClient): def __init__(self, proxy: bool, verify: bool, reliability: str, base_url: str, params: dict): headers = {"Content-Type": "application/json", "Accept": "application/json"} super().__init__(proxy=proxy, verify=verify, base_url=base_url, headers=headers) self.base_url = base_url self.client_body = { "clientId": params.get("api_creds", {}).get("identifier") or params.get("client_id"), "clientVersion": params.get("client_version"), } if DBotScoreReliability.is_valid_type(reliability): self.reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability) else: raise Exception("Google Safe Browsing v2 error: Please provide a valid value for the Source Reliability parameter.") def build_request_body(self, client_body: dict, list_url: List) -> dict: """build the request body according to the client body and the urls. Args: client_body: client body to add it in the request body list_url: The urls list Returns: (dict) The request body, in the right format. """ list_urls = [] for url in list_url: list_urls.append({"url": url}) body: dict = { "client": client_body, "threatInfo": { "threatTypes": TYPES.get("threatTypes"), "platformTypes": TYPES.get("platformTypes"), "threatEntryTypes": ["URL"], "threatEntries": list_urls, }, } return body def url_request(self, client_body, list_url) -> dict: """send the url request. Args: client_body: client body to add it in the request body list_url: The urls list Returns: (dict) The response from the request. """ body = self.build_request_body(client_body, list_url) result = self._http_request(method="POST", json_data=body, full_url=self.base_url) return result def test_module(client: Client) -> str: """ Performs basic get request to get sample URL details. """ try: # testing a known malicious URL to check if we get matches test_url = "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/" res = client.url_request(client.client_body, [test_url]) if res.get("matches"): # matches - There is a match for the URL we were looking for message = "ok" else: message = "Error querying Google Safe Browsing. Expected matching respons, but received none" except DemistoException as e: if "Forbidden" in str(e) or "Authorization" in str(e): message = "Authorization Error: please make sure the API Key is set correctly." else: raise e return message def handle_errors(result: dict) -> None: """ Handle errors, raise Exception when there is errors in the response. """ status_code = result.get("StatusCode", 0) result_body = result.get("Body") if result_body == "" and status_code == 204: raise Exception("No content received. Possible API rate limit reached.") if 200 < status_code < 299: raise Exception(f"Failed to perform request, request status code: {status_code}.") if result_body == "": raise Exception("No content received. Maybe you tried a private API?.") if result.get("error"): error_massage = result.get("error", {}).get("message") error_code = result.get("error", {}).get("code") raise Exception(f"Failed accessing Google Safe Browsing APIs. Error: {error_massage}. Error code: {error_code}") def arrange_results_to_urls(results: List, url_list: List) -> dict: """Arrange and filter the URLs results according to the URLs list that we asked information on. Args: results: the API response. url_list: The URLs list that we asked information on. Returns: (dict) The results according the urls. """ urls_results: dict[str, list] = {} for url in url_list: urls_results[url] = [] for result in results: url = result.get("threat", {}).get("url") urls_results[url].append(result) return urls_results def url_command(client: Client, args: dict[str, Any]) -> Union[List[CommandResults], CommandResults]: """ url command: Returns URL details for a list of URL """ url = argToList(args.get("url")) result = client.url_request(client.client_body, url) if not result: dbot_score = Common.DBotScore( indicator=url, indicator_type=DBotScoreType.URL, integration_name=INTEGRATION_NAME, score=0, reliability=client.reliability, ) url_standard_context = Common.URL(url=url, dbot_score=dbot_score) return CommandResults( readable_output=f"No information was found for url {url}", outputs_prefix=URL_OUTPUT_PREFIX, outputs_key_field="IndicatorValue", outputs=result, indicator=url_standard_context, ) if result.get("StatusCode"): handle_errors(result) urls_data = arrange_results_to_urls(result.get("matches"), url) # type: ignore url_data_list = [] for url_key, url_data in urls_data.items(): if url_data: dbot_score = Common.DBotScore( indicator=url_key, indicator_type=DBotScoreType.URL, integration_name=INTEGRATION_NAME, score=3, reliability=client.reliability, ) url_standard_context = Common.URL(url=url_key, dbot_score=dbot_score) url_data_list.append( CommandResults( readable_output=tableToMarkdown(f"Google Safe Browsing APIs - URL Query: {url_key}", url_data), outputs_prefix=URL_OUTPUT_PREFIX, outputs_key_field="IndicatorValue", outputs=url_data, indicator=url_standard_context, ) ) else: dbot_score = Common.DBotScore( indicator=url_key, indicator_type=DBotScoreType.URL, integration_name=INTEGRATION_NAME, score=0, reliability=client.reliability, ) url_standard_context = Common.URL(url=url_key, dbot_score=dbot_score) url_data_list.append( CommandResults( readable_output=f"No matches for URL {url_key}", outputs_prefix=URL_OUTPUT_PREFIX, outputs_key_field="IndicatorValue", outputs=result, indicator=url_standard_context, ) ) return url_data_list def build_base_url(params: dict) -> str: api_key = params.get("api_creds", {}).get("password") or params.get("api_key") base_url = params.get("url", "") if not base_url.endswith("/"): base_url += "/" return f"{base_url}?key={api_key}" def main() -> None: params = demisto.params() verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) base_url = build_base_url(params) reliability = params.get("integrationReliability") reliability = reliability if reliability else DBotScoreReliability.B demisto.debug(f"Command being called is {demisto.command()}") try: client = Client(params=params, base_url=base_url, verify=verify_certificate, proxy=proxy, reliability=reliability) if demisto.command() == "test-module": result = test_module(client) return_results(result) elif demisto.command() == "url": return_results(url_command(client, demisto.args())) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()