Snyk Role Change


Description

Detects when Snyk Roles are changed

Query · python

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.role.create",
    "group.role.edit",
    "group.user.role.create",
    "group.user.role.delete",
    "group.user.role.edit",
    "org.user.role.create",
    "org.user.role.delete",
    "org.user.role.details.edit",
    "org.user.role.edit",
    "org.user.role.permissions.edit",
]


def rule(event):

    action = event.get("event", "<NO_EVENT>")
    return action in ACTIONS


def title(event):
    group_or_org = "<GROUP_OR_ORG>"
    crud_operation = "<NO_OPERATION>"
    action = event.get("event", "<NO_EVENT>")
    if "." in action:
        group_or_org = action.split(".")[0].title()
        crud_operation = action.split(".")[-1].title()
    return (
        f"Snyk: [{group_or_org}] Role "
        f"[{crud_operation}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    a_c = snyk_alert_context(event)
    role = event.deep_get("content", "after", "role", default=None)
    if not role and "afterRoleName" in event.get("content", {}):
        role = event.deep_get("content", "afterRoleName", default=None)
    if role:
        a_c["role_permission"] = role
    return a_c


def dedup(event):
    return (
        f"{event.deep_get('userId', default='<NO_USERID>')}"
        f"{event.deep_get('orgId', default='<NO_ORGID>')}"
        f"{event.deep_get('groupId', default='<NO_GROUPID>')}"
        f"{event.deep_get('event', default='<NO_EVENT>')}"
    )


def severity(event):
    role = event.deep_get("content", "after", "role", default=None)
    if not role and "afterRoleName" in event.get("content", {}):
        role = event.deep_get("content", "afterRoleName", default=None)
    if role == "ADMIN":
        return "CRITICAL"
    return "MEDIUM"

Analyst notes

These actions in the Snyk Audit logs indicate that a ServiceAccount has been created/deleted/modified.

All events where the Role is marked as ADMIN have CRITICAL severity Other events are marked with MEDIUM severity

Raw source Snyk Role Change · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: snyk_role_change.py
RuleID: "Snyk.Role.Change"
DisplayName: "Snyk Role Change"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects when Snyk Roles are changed
Runbook: |
  These actions in the Snyk Audit logs indicate that a ServiceAccount
  has been created/deleted/modified.

  All events where the Role is marked as ADMIN have CRITICAL severity
  Other events are marked with MEDIUM severity

Reference: https://docs.snyk.io/snyk-admin/manage-users-and-permissions/member-roles
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event
Tests:
  - Name: Snyk Group Role Edit -  ADMIN role ( CRIT )
    ExpectedResult: true
    Log:
      {
        "content":
          {
            "after":
              {
                "role": "ADMIN",
                "rolePublicId": "8ddddddd-fbbb-4fff-8111-5eeeeeeeeeee",
              },
            "before":
              {
                "role": "MEMBER",
                "rolePublicId": "6aaaaaaa-c000-4ddd-9ddd-c55555555555",
              },
            "userPublicId": "05555555-3333-4ddd-8ccc-755555555555",
          },
        "created": "1999-04-04 18:38:19.843",
        "event": "group.user.role.edit",
        "groupId": "8fffffff-1555-4444-b000-b55555555555",
        "userId": "05555555-3333-4ddd-8ccc-755555555555",
      }
  - Name: Snyk Org Role Edit -  ADMIN role ( CRIT )
    ExpectedResult: true
    Log:
      {
        "content":
          {
            "afterRoleName": "ADMIN",
            "afterRolePublicId": "d8999999-aaaa-4999-9f0b-9bbbbbbbbbbb",
            "beforeRoleName": "Org Collaborator",
            "beforeRolePublicId": "b0000000-dbbb-4000-addd-1ddddddddddd",
            "userPublicId": "05555555-3333-4ddd-8ccc-755555555555",
          },
        "created": "1999-03-08 16:24:02.616",
        "event": "org.user.role.edit",
        "groupId": "8fffffff-1555-4444-b000-b55555555555",
        "userId": "05555555-3333-4ddd-8ccc-755555555555",
        "orgId": "21111111-a222-4eee-8ddd-a99999999999",
      }
  - Name: Snyk Group Role Edit -  MEMBER role ( MEDIUM )
    ExpectedResult: true
    Log:
      {
        "content":
          {
            "before":
              {
                "role": "ADMIN",
                "rolePublicId": "8ddddddd-fbbb-4fff-8111-5eeeeeeeeeee",
              },
            "after":
              {
                "role": "MEMBER",
                "rolePublicId": "6aaaaaaa-c000-4ddd-9ddd-c55555555555",
              },
            "userPublicId": "05555555-3333-4ddd-8ccc-755555555555",
          },
        "created": "1999-04-04 18:38:19.843",
        "event": "group.user.role.edit",
        "groupId": "8fffffff-1555-4444-b000-b55555555555",
        "userId": "05555555-3333-4ddd-8ccc-755555555555",
      }
  - Name: Snyk Group SSO Membership sync
    ExpectedResult: false
    Log:
      {
        "content": {},
        "created": "2023-03-15 13:13:13.133",
        "event": "group.sso.membership.sync",
        "groupId": "8fffffff-1555-4444-b000-b55555555555",
      }


# ------ paired body: snyk_role_change.py ------

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.role.create",
    "group.role.edit",
    "group.user.role.create",
    "group.user.role.delete",
    "group.user.role.edit",
    "org.user.role.create",
    "org.user.role.delete",
    "org.user.role.details.edit",
    "org.user.role.edit",
    "org.user.role.permissions.edit",
]


def rule(event):

    action = event.get("event", "<NO_EVENT>")
    return action in ACTIONS


def title(event):
    group_or_org = "<GROUP_OR_ORG>"
    crud_operation = "<NO_OPERATION>"
    action = event.get("event", "<NO_EVENT>")
    if "." in action:
        group_or_org = action.split(".")[0].title()
        crud_operation = action.split(".")[-1].title()
    return (
        f"Snyk: [{group_or_org}] Role "
        f"[{crud_operation}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    a_c = snyk_alert_context(event)
    role = event.deep_get("content", "after", "role", default=None)
    if not role and "afterRoleName" in event.get("content", {}):
        role = event.deep_get("content", "afterRoleName", default=None)
    if role:
        a_c["role_permission"] = role
    return a_c


def dedup(event):
    return (
        f"{event.deep_get('userId', default='<NO_USERID>')}"
        f"{event.deep_get('orgId', default='<NO_ORGID>')}"
        f"{event.deep_get('groupId', default='<NO_GROUPID>')}"
        f"{event.deep_get('event', default='<NO_EVENT>')}"
    )


def severity(event):
    role = event.deep_get("content", "after", "role", default=None)
    if not role and "afterRoleName" in event.get("content", {}):
        role = event.deep_get("content", "afterRoleName", default=None)
    if role == "ADMIN":
        return "CRITICAL"
    return "MEDIUM"

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.