HashIncidentsFields
Hash fields from the incident list. Search for incidents by arguments with an option to hash some of its fields.
python · Machine Learning
Source
import base64 import hashlib import pickle import uuid from CommonServerPython import * RANDOM_UUID = str(demisto.args().get("addRandomSalt", "")) # Memo for key matching CACHE = {} # type: ignore def hash_value(simple_value): if not isinstance(simple_value, str): simple_value = str(simple_value) if simple_value.lower() in ["none", "null"]: return None if RANDOM_UUID: simple_value += RANDOM_UUID return hashlib.md5(simple_value.encode("utf8")).hexdigest() # nosec def pattern_match(pattern, s): regex = re.compile(pattern.replace("*", ".*")) return re.match(regex, s) is not None def is_key_match_fields_to_hash(key, fields_to_hash): if key is None: return False if key in CACHE: return CACHE[key] for field in fields_to_hash: if pattern_match(field, key): CACHE[key] = True return True CACHE[key] = False return False def hash_incident_labels(incident_labels, fields_to_hash): labels = [] if isinstance(incident_labels, list): for label in incident_labels: if is_key_match_fields_to_hash(label.get("type"), fields_to_hash): value = label.get("value") or "" if value: label["value"] = hash_value(value) labels.append(label) return labels def hash_multiple(value, fields_to_hash, to_hash=False): if isinstance(value, list): return [hash_multiple(x, fields_to_hash, to_hash) for x in value] if isinstance(value, dict): for k, v in value.items(): _hash = to_hash or is_key_match_fields_to_hash(k, fields_to_hash) value[k] = hash_multiple(v, fields_to_hash, _hash) return value else: try: if isinstance(value, int | float | bool): to_hash = False if not isinstance(value, str): value = str(value) except Exception: value = "" if to_hash and value: return hash_value(value) else: return value def output_file(data, description, output_format): data_encoded = b"" file_name = str(uuid.uuid4()) if output_format == "pickle": pickled_incidents = [] for i in data: pickled_incident = base64.b64encode(pickle.dumps(i)) pickled_incidents.append(pickled_incident) data_encoded = pickle.dumps(pickled_incidents) elif output_format == "json": data_encoded = json.dumps(data).encode("utf8") else: return_error(f"Invalid output format: {output_format}") entry = fileResult(file_name, data_encoded) entry["Contents"] = data entry["HumanReadable"] = description entry["EntryContext"] = { "HashIncidentsFields": { "Filename": file_name, "FileFormat": output_format, } } return entry def copy_key_from_context(ctx, context_keys): new_ctx = {} if not ctx: return {} for key in context_keys: new_ctx[key] = demisto.dt(ctx, key) return new_ctx def get_context(incident_id): res = demisto.executeCommand("getContext", {"id": incident_id}) try: return res[0]["Contents"].get("context") or {} except Exception: return {} def hash_incident(fields_to_hash, un_populate_fields): args = demisto.args() remove_labels = demisto.args().get("removeLabels", "") == "true" context_keys = [x for x in argToList(demisto.args().get("contextKeys", "")) if x] # load incidents res = demisto.executeCommand("GetIncidentsByQuery", args) if is_error(res): return_error(get_error(res)) incident_list = json.loads(res[0]["Contents"]) # filter incidents new_incident_list = [] for incident in incident_list: if context_keys: incident["context"] = copy_key_from_context(get_context(incident["id"]), context_keys) # remove CustomFields incident.pop("CustomFields", None) incident = hash_multiple(incident, fields_to_hash) # filter out fields if un_populate_fields: incident = {k: v for k, v in incident.items() if k not in un_populate_fields} # remove or hash incident labels incident_labels = incident.pop("labels") if not remove_labels: incident["labels"] = hash_incident_labels(incident_labels, fields_to_hash) new_incident_list.append(incident) # Output desc = f"Fetched {len(new_incident_list)} incidents successfully by the query: {args.get('query')}" entry = output_file(new_incident_list, desc, args["outputFormat"]) return entry if __name__ in ["__main__", "__builtin__", "builtins"]: args = demisto.args() fields_to_hash = frozenset([x for x in argToList(args.get("fieldsToHash", "")) if x]) un_populate_fields = frozenset([x for x in argToList(args.get("unPopulateFields", "")) if x]) entry = hash_incident(fields_to_hash, un_populate_fields) demisto.results(entry)
README
Hash fields from the incident list.
Search for incidents by arguments with an option to hash some of its fields.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | incidents, ml |
| Cortex XSOAR Version | 5.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| query | Additional text by which to query incidents. |
| incidentTypes | A comma-separated list of incident types by which to filter. |
| fromDate | The start date by which to filter incidents. Date format will be the same as in the incidents query page, for example: “3 days ago”, ““2019-01-01T00:00:00 +0200”). |
| toDate | The end date by which to filter incidents. Date format will be the same as in the incidents query page, for example: “3 days ago”, ““2019-01-01T00:00:00 +0200”). |
| limit | The maximum number of incidents to fetch. The default value is 3000. |
| timeField | The incident field to specify for the date range. Can be “created” or “modified”. The default is “created”. |
| NonEmptyFields | A comma-separated list of non-empty value incident field names by which to filter incidents. |
| outputFormat | The output file format. |
| populateFields | A comma-separated list of fields in the object to poplulate. |
| fieldsToHash | A comma-separated list of fields to hash. Support wildcards. |
| contextKeys | A comma-separated list of context keys to keep. |
| removeLabels | Remove incident labels |
| unPopulateFields | A comma-separated list of fields in the object to un-poplulate. |
| addRandomSalt | Random salt to the hash function |
Outputs
| Path | Description | Type |
|---|---|---|
| HashIncidentsFields.Filename | The output file name. | String |
| HashIncidentsFields.FileFormat | The output file format. | String |