Work With Lists - Administrator Guide - 6.6 - Cortex XSOAR - Cortex - Security Operations

Cortex XSOAR Administrator Guide

Product
Cortex XSOAR
Version
6.6
Creation date
2022-09-29
Last date published
2024-03-21
End_of_Life
EoL
Category
Administrator Guide
Abstract

Manage lists in Cortex XSOAR that can be accessed by automations, playbooks, etc.

A list is a data container where you can globally store data within Cortex XSOAR. Despite the name lists, the data can be in any text format, and can even store files. You can use lists to manage important users in your organization, sensitive endpoints, SOC shifts, and more. These lists can be used dynamically within different investigations to provide global context to each relevant incident type.

The data within lists can be accessed in automations, playbooks, or any other place where the context button appears (double-curly brackets). In a playbook, you can access the data in a list via the context button under Lists, or by using the path ${lists.<list_name>}. You can use a list in a playbook to modify, filter, or transform parts of a list and then update the list with the changes or use the changed data in subsequent playbook tasks. You can also use a playbook task to iterate over list items.

Note

The maximum list size is 209715 characters.

  • Create a list

    When creating a list, you can select the content type (Text, Markdown, HTML, JSON or CSS) and whether you want to limit permissions for read and write or read only.

    Note

    You can change the content type without editing the list. You cannot edit truncated lists that are too large to display, but you can download a truncated list.

    If a valid JSON is stored within a list, it will automatically be parsed as a JSON object when you access it from within a playbook. Depending on how you store the data, you may need to transform a list into an array.

    When you access a list using the built-in list or base pack commands, the data is considered to be comma-separated unless you specifically define a custom separator for the list. When using built-in commands, you do not need to split the list. However, if you want to use non-built-in commands, such as in an automation or to loop over list items, you need to split the list using a transformer.

  • Upload/download a list.

  • In a remote repository, lists can be pushed to a production environment. When the list is pushed to production, you cannot edit the list in the production environment. If a list has been pushed to production that already exists with the same name, you can resolve the conflict. You can still create lists in production.

  • (Multi-tenant) You can propagate lists from the Main Account to tenants.

Lists can be included in a content pack and be installed from the Marketplace.

Use cases

These are some common use cases for creating and using lists in Cortex XSOAR.

  • A list of allowed executable files against which to check potentially malicious executable files.

  • An HTML template that you can define to use as part of a Communication task.

  • Store data object, for example JSON, that you can call as inputs for scripts and playbooks.

  • Use the getList or addToList commands in a script to take action based on the list data, for example, res = demisto.executeCommand("getList", {"listName": demisto.args()["listName"]}) will return all list entries in the script.

List commands

You can use the following list commands in scripts and playbook tasks.

Command

Description

Arguments

getList

Retrieves the contents of the specified list.

listName: The name of the list for which to retrieve the contents.

createList

Creates a list with the supplied data.

  • listName: The name of the list to which to add items.

  • listData: The data to add to the new list.

addToList

Appends the supplied items to the specified list. If you add multiple items, make sure you use the same list separator that the list currently uses, for example a comma or a semicolon.

  • listName: The name of the list to which to append items.

  • listData: The data to add to the specified list. The data will be appended to the existing data in the list.

setList

Adds the supplied data to the specified list and overwrites existing list data.

  • listName: The name of the list to which to add items.

  • listData: The data to add to the specified list. The data overwrites the existing data in the list.

removeFromList

Removes a single item from the specified list.

  • listName: The name of the list from which to remove an item.

  • listData: The item to remove from the specified list.

Example

For example, the ManageOOOUsers script uses the getList, createList, and setList commands.

register_module_line('ManageOOOusers', 'start', __line__())

def _get_current_user():
    current_username = demisto.executeCommand("getUsers", {"current": True})
    if isError(current_username):
        demisto.debug(f"failed to get current username - {get_error(current_username)}")
        return
    else:
        return current_username[0]["Contents"][0]['username']

def main():
    # get current time
    now = datetime.now()

    # args
    list_name = demisto.getArg("listname")
    username = demisto.getArg("username")

    option = demisto.getArg("option")
    days_off = now + timedelta(days=int(demisto.getArg("daysoff")))
    off_until = days_off.strftime("%Y-%m-%d")

    # update list name to start with 'OOO', so we can't overwrite other lists with this
    if not list_name.startswith("OOO"):
        list_name = f"OOO {list_name}"

    current_user = _get_current_user()
    if not current_user and not username:
        return_error('Failed to get current user. Please set the username argument in the script.')

    if not username:
        # Current user was found, running script on it.
        username = current_user
    else:
        # check if provided username is a valid xsoar user
        users = demisto.executeCommand("getUsers", {})
        if isError(users):
            return_error(f'Failed to get users: {str(get_error(users))}')
        users = users[0]['Contents']

        users = [x['username'] for x in users]
        if username not in users:
            return_error(message=f"{username} is not a valid user")

    # get the out of office list, check if the list exists, if not create it:
    ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"]
    if isError(ooo_list):
        return_error(f'Failed to get users out of office: {str(get_error(ooo_list))}')

    if "Item not found" in ooo_list:
        demisto.results(demisto.executeCommand("createList", {"listName": list_name, "listData": []}))
        ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"]

    # check status of the list, and add/remove the user from it.
    if not ooo_list:
        list_data = []
    else:
        list_data = json.loads(ooo_list)
    if option == "add":
        # check if user is already in the list, and remove, to allow updating
        list_data = [i for i in list_data if not (i['user'] == username)]
        list_data.append({"user": username,
                          "offuntil": off_until,
                          "addedby": current_user if current_user else 'DBot'})
    else:
        # remove the user from the list.
        list_data = [i for i in list_data if not (i['user'] == username)]

    set_list_res = demisto.executeCommand("setList", {"listName": list_name, "listData": json.dumps(list_data)})
    if isError(set_list_res):
        return_error(f'Failed to update the list {list_name}: {str(get_error(set_list_res))}')

    # welcome back, or see ya later!
    if option == "add":
        demisto.results(f"Vacation mode engaged until {off_until}, enjoy the time off {username}")
    else:
        demisto.results(f"Welcome back {username}, it's like you never left!")

if __name__ in ('__builtin__', 'builtins', '__main__'):
    main()

register_module_line('ManageOOOusers', 'end', __line__())