Detection rules › Panther

Panther rules: snyk

Snyk Miscellaneous Settings

#
Severity
low
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk settings that lack a clear security impact are changed

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.cloud_config.settings.edit",
    "group.feature_flags.edit",
]


def rule(event):

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


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


def alert_context(event):
    return snyk_alert_context(event)


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>')}"
    )

Rule specification

AnalysisType: rule
Filename: snyk_misc_settings.py
RuleID: "Snyk.Misc.Settings"
DisplayName: "Snyk Miscellaneous Settings"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Reference: https://docs.snyk.io/snyk-admin/manage-settings
Severity: Low
Description: >
  Detects when Snyk settings that lack a clear security impact are changed
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.cloud_config.settings.edit, group.feature_flags.edit

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.cloud_config.settings.edit
  • group.feature_flags.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "created": "2023-04-11 23:32:14.173",
  "event": "group.feature_flags.edit",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk Org or Group Settings Change

#
Severity
high
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Group or Organization Settings are changed.

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.create",
    "group.delete",
    "group.edit",
    "group.feature_flags.edit",
    "group.org.add",
    "group.org.remove",
    "group.settings.edit",
    "group.settings.feature_flag.edit",
    "org.create",
    "org.delete",
    "org.edit",
    "org.settings.feature_flag.edit",
]


def rule(event):

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


def title(event):
    group_or_org = "<GROUP_OR_ORG>"
    action = event.get("event", "<NO_EVENT>")
    if "." in action:
        group_or_org = action.split(".")[0].title()
    return (
        f"Snyk: [{group_or_org}] Organizational Unit settings have been modified "
        f"via [{action}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    return snyk_alert_context(event)


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):
    action = event.get("event", "<NO_EVENT>")
    if action.endswith((".remove", ".delete")):
        return "HIGH"
    if action.endswith((".edit")):
        return "MEDIUM"
    return "INFO"

Rule specification

AnalysisType: rule
Filename: snyk_ou_change.py
RuleID: "Snyk.OU.Change"
DisplayName: "Snyk Org or Group Settings Change"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects when Snyk Group or Organization Settings are changed.
Runbook: |
  These actions in the Snyk Audit logs indicate that a Organization or
  Group setting has changed, including Group and Org creation/deletion.
  Deletion events are marked with HIGH severity
  Creation events are marked with INFO severity
  Edit events are marked with MEDIUM Severity

Reference: https://docs.snyk.io/snyk-admin/introduction-to-snyk-administration
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.create, group.delete, group.edit, group.feature_flags.edit, group.org.add (+7 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.create
  • group.delete
  • group.edit
  • group.feature_flags.edit
  • group.org.add
  • group.org.remove
  • group.settings.edit
  • group.settings.feature_flag.edit
  • org.create
  • org.delete
  • org.edit
  • org.settings.feature_flag.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
event
userId

Response runbook

These actions in the Snyk Audit logs indicate that a Organization or

Group setting has changed, including Group and Org creation/deletion.

Deletion events are marked with HIGH severity

Creation events are marked with INFO severity

Edit events are marked with MEDIUM Severity

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "orgName": "expendable-org"
  },
  "created": "2023-04-09T23:32:14.649Z",
  "event": "org.delete",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk Org Settings

#
Severity
medium
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Organization settings, like Integrations and Webhooks, are changed

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "org.integration.create",
    "org.integration.delete",
    "org.integration.edit",
    "org.integration.settings.edit",
    "org.request_access_settings.edit",
    "org.target.create",
    "org.target.delete",
    "org.webhook.add",
    "org.webhook.delete",
]


def rule(event):

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


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


def alert_context(event):
    return snyk_alert_context(event)


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>')}"
    )

Rule specification

AnalysisType: rule
Filename: snyk_org_settings.py
RuleID: "Snyk.Org.Settings"
DisplayName: "Snyk Org Settings"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Reference: https://docs.snyk.io/snyk-admin/manage-settings/organization-general-settings
Severity: Medium
Description: >
  Detects when Snyk Organization settings, like Integrations and Webhooks, are changed
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of org.integration.create, org.integration.delete, org.integration.edit, org.integration.settings.edit, org.request_access_settings.edit (+4 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • org.integration.create
  • org.integration.delete
  • org.integration.edit
  • org.integration.settings.edit
  • org.request_access_settings.edit
  • org.target.create
  • org.target.delete
  • org.webhook.add
  • org.webhook.delete
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "after": {
      "integrationSettings": {
        "autoDepUpgradeIgnoredDependencies": [],
        "autoDepUpgradeLimit": 5,
        "autoRemediationPrs": {
          "usePatchRemediation": true
        },
        "isMajorUpgradeEnabled": true,
        "manualRemediationPrs": {
          "useManualPatchRemediation": true
        },
        "pullRequestAssignment": {
          "assignees": [
            "github_handle",
            "github_handle2"
          ],
          "enabled": true,
          "type": "manual"
        },
        "pullRequestTestEnabled": true,
        "reachableVulns": {}
      }
    },
    "before": {
      "integrationSettings": {
        "autoDepUpgradeIgnoredDependencies": [],
        "autoDepUpgradeLimit": 5,
        "autoRemediationPrs": {
          "usePatchRemediation": true
        },
        "isMajorUpgradeEnabled": true,
        "manualRemediationPrs": {
          "useManualPatchRemediation": true
        },
        "pullRequestAssignment": {
          "assignees": [
            "github_handle",
            "github_handle2"
          ],
          "enabled": true,
          "type": "manual"
        },
        "reachableVulns": {}
      }
    },
    "integrationPublicId": "81111111-cccc-4eee-bfff-3ccccccccccc",
    "interface": "ui"
  },
  "created": "2023-03-24 14:53:51.334",
  "event": "org.integration.settings.edit",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk Project Settings

#
Severity
medium
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Project settings are changed

Detection logic

from panther_snyk_helpers import snyk_alert_context

# The bodies of these actions are quite diverse.
# When projects are added, the logged detail is the sourceOrgId.
# org.project.stop_monitor is logged for individual files
#   that are ignored.


ACTIONS = [
    "org.sast_settings.edit",
    "org.project.attributes.edit",
    "org.project.add",
    "org.project.delete",
    "org.project.fix_pr.manual_open",
    "org.project.ignore.create",
    "org.project.ignore.delete",
    "org.project.ignore.edit",
    "org.project.monitor",
    "org.project.pr_check.edit",
    "org.project.remove",
    "org.project.settings.delete",
    "org.project.settings.edit",
    "org.project.stop_monitor",
    # AND the equivalent for licenses",
    "org.license_rule.create",
    "org.license_rule.delete",
    "org.license_rule.edit",
]


def rule(event):

    if event.deep_get("content", "after", "description") == "No new Code Analysis issues found":
        return False
    action = event.get("event", "<NO_EVENT>")
    return action in ACTIONS


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


def alert_context(event):
    a_c = snyk_alert_context(event)
    # merge event in for the alert_context
    a_c.update(event)
    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):
    action = event.get("event", "<NO_EVENT>")
    if action == "org.project.fix_pr.manual_open":
        return "INFO"
    return "LOW"

Rule specification

AnalysisType: rule
Filename: snyk_project_settings.py
RuleID: "Snyk.Project.Settings"
DisplayName: "Snyk Project Settings"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Reference: https://docs.snyk.io/snyk-admin/introduction-to-snyk-projects/view-and-edit-project-settings
Severity: Medium
Description: >
  Detects when Snyk Project settings are changed
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when all of the conditions below hold.

Condition

  • content.after.description is not No new Code Analysis issues found
  • event is one of org.sast_settings.edit, org.project.attributes.edit, org.project.add, org.project.delete, org.project.fix_pr.manual_open (+12 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
content.after.descriptionne
  • No new Code Analysis issues found
field:"content.after.description" kind:ne value:"No new Code Analysis issues found"
eventin
  • org.license_rule.create
  • org.license_rule.delete
  • org.license_rule.edit
  • org.project.add
  • org.project.attributes.edit
  • org.project.delete
  • org.project.fix_pr.manual_open
  • org.project.ignore.create
  • org.project.ignore.delete
  • org.project.ignore.edit
  • org.project.monitor
  • org.project.pr_check.edit
  • org.project.remove
  • org.project.settings.delete
  • org.project.settings.edit
  • org.project.stop_monitor
  • org.sast_settings.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "origin": "github",
    "target": {
      "branch": "some-branch",
      "id": 222222222,
      "name": "repo-name",
      "owner": "github-org"
    },
    "targetFile": "go.mod",
    "type": "gomodules"
  },
  "created": "2023-03-30 15:38:18.58",
  "event": "org.project.stop_monitor",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "projectId": "05555555-8555-2333-5aaa-600000000000",
  "userId": "05555555-3333-4ddd-8ccc-75555555555"
}

Snyk Role Change

#
Severity
high
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Roles are changed

Detection logic

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"

Rule specification

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

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.role.create, group.role.edit, group.user.role.create, group.user.role.delete, group.user.role.edit (+5 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • 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
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Response 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

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "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"
}

Snyk Service Account Change

#
Severity
high
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Service Accounts are changed

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.service_account.create",
    "group.service_account.delete",
    "group.service_account.edit",
    "org.service_account.create",
    "org.service_account.delete",
    "org.service_account.edit",
    "org.service_account.membership.upsert",
]


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}] Service Account "
        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", "role", "role", default=None)
    if not role:
        role = event.deep_get("content", "role", 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):
    action = event.get("event", "<NO_EVENT>")
    role = event.deep_get("content", "role", "role", default=None)
    if not role:
        role = event.deep_get("content", "role", default=None)
    if all(
        [role == "ADMIN", action.endswith((".service_account.create", ".service_account.delete"))]
    ):
        return "CRITICAL"
    if action.endswith((".service_account.create", ".service_account.delete")):
        return "HIGH"
    return "MEDIUM"

Rule specification

AnalysisType: rule
Filename: snyk_svcacct_change.py
RuleID: "Snyk.ServiceAccount.Change"
DisplayName: "Snyk Service Account Change"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects when Snyk Service Accounts are changed
Runbook: |
  These actions in the Snyk Audit logs indicate that a ServiceAccount
  has been created/deleted/modified.

  Service Accounts are system user accounts with an API token
  associated to it in place of standard user credentials.
  All events where the Service Account's role is ADMIN have CRITICAL severity
  Deletion events are marked with HIGH severity
  Creation events are marked with HIGH severity
  Edit events are marked with MEDIUM Severity

Reference: https://docs.snyk.io/snyk-admin/service-accounts
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.service_account.create, group.service_account.delete, group.service_account.edit, org.service_account.create, org.service_account.delete (+2 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.service_account.create
  • group.service_account.delete
  • group.service_account.edit
  • org.service_account.create
  • org.service_account.delete
  • org.service_account.edit
  • org.service_account.membership.upsert
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Response runbook

These actions in the Snyk Audit logs indicate that a ServiceAccount

has been created/deleted/modified.

Service Accounts are system user accounts with an API token

associated to it in place of standard user credentials.

All events where the Service Account's role is ADMIN have CRITICAL severity

Deletion events are marked with HIGH severity

Creation events are marked with HIGH severity

Edit events are marked with MEDIUM Severity

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "role": "ADMIN",
    "rolePublicId": "d8999999-aaaa-4444-9fff-955555555555",
    "serviceAccountPublicId": "9ddddddd-4444-4111-9eee-188888888888"
  },
  "created": "2023-04-05 22:22:57.488",
  "event": "org.service_account.create",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk System External Access Settings Changed

#
Severity
high
Group by
groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Settings that control access for external parties have been changed.

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.request_access_settings.edit",
    "org.request_access_settings.edit",
]


def rule(event):

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


def title(event):
    current_setting = event.deep_get("content", "after", "isEnabled", default=False)
    action = event.get("event", "<NO_EVENT>")
    if "." in action:
        action = action.split(".")[0].title()
    return (
        f"Snyk: [{action}] External Access settings have been modified "
        f"to PermitExternalUsers:[{current_setting}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    a_c = snyk_alert_context(event)
    current_setting = event.deep_get("content", "after", "isEnabled", default=False)
    a_c["current_setting"] = current_setting
    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>')}"
    )


def severity(event):
    current_setting = event.deep_get("content", "after", "isEnabled", default=False)
    if current_setting:
        return "HIGH"
    return "INFO"

Rule specification

AnalysisType: rule
Filename: snyk_system_externalaccess.py
RuleID: "Snyk.System.ExternalAccess"
DisplayName: "Snyk System External Access Settings Changed"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects when Snyk Settings that control access for external parties have been changed.
Runbook: |
  This action in the Snyk Audit logs indicate that the setting for allowing external
  parties to request access to your Snyk installation have changed.
Reference: https://docs.snyk.io/snyk-admin/manage-users-and-permissions/organization-access-requests
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.request_access_settings.edit, org.request_access_settings.edit

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.request_access_settings.edit
  • org.request_access_settings.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
isEnabledcontent.after.isEnabled
userId

Response runbook

This action in the Snyk Audit logs indicate that the setting for allowing external

parties to request access to your Snyk installation have changed.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "after": {
      "isEnabled": true
    },
    "before": {}
  },
  "created": "2023-03-03T19:52:01.628Z",
  "event": "group.request_access_settings.edit",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk System Policy Settings Changed

#
Severity
high
Group by
content.publicId, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects Snyk Policy Settings have been changed. Policies define Snyk's behavior when encountering security and licensing issues.

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.policy.create",
    "group.policy.delete",
    "group.policy.edit",
    "org.policy.edit",
    "org.ignore_policy.edit",
]


def rule(event):

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


def title(event):
    policy_type = "<NO_POLICY_TYPE_FOUND>"
    license_or_rule = event.deep_get("content", "after", "configuration", default={})
    if "rules" in license_or_rule:
        policy_type = "security"
    elif "licenses" in license_or_rule:
        policy_type = "license"
    return (
        f"Snyk: System [{policy_type}] Policy Setting event "
        f"[{event.deep_get('event', default='<NO_EVENT>')}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    a_c = snyk_alert_context(event)
    a_c["policy_type"] = "<NO_POLICY_TYPE_FOUND>"
    license_or_rule = event.deep_get("content", "after", "configuration", default={})
    if "rules" in license_or_rule:
        a_c["policy_type"] = "security"
    elif "licenses" in license_or_rule:
        a_c["policy_type"] = "license"
    return a_c


def dedup(event):
    # Licenses can apply at org or group levels
    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('content', 'publicId', default='<NO_PUBLICID>')}"
    )

Rule specification

AnalysisType: rule
Filename: snyk_system_policysetting.py
RuleID: "Snyk.System.PolicySetting"
DisplayName: "Snyk System Policy Settings Changed"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects Snyk Policy Settings have been changed.
  Policies define Snyk's behavior when encountering security and licensing issues.
Runbook: |
  Snyk Policies can cause alerts to raise or not based on found security and
  license issues. Validate that that this change is expected.
Reference: https://docs.snyk.io/manage-issues/policies/shared-policies-overview
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.policy.create, group.policy.delete, group.policy.edit, org.policy.edit, org.ignore_policy.edit

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.policy.create
  • group.policy.delete
  • group.policy.edit
  • org.ignore_policy.edit
  • org.policy.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
event
userId

Response runbook

Snyk Policies can cause alerts to raise or not based on found security and

license issues. Validate that that this change is expected.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "after": {
      "configuration": {
        "rules": [
          {
            "actions": [
              {
                "data": {
                  "severity": "high"
                },
                "type": "severity-override"
              }
            ],
            "conditions": {
              "AND": [
                {
                  "field": "exploit-maturity",
                  "operator": "includes",
                  "value": [
                    "mature"
                  ]
                }
              ]
            },
            "name": "Rule 1"
          }
        ]
      },
      "description": "This is a security policy",
      "group": "8fffffff-1555-4444-b000-b55555555555",
      "name": "Example Security Policy"
    },
    "before": {},
    "publicId": "21111111-a222-4eee-8ddd-a99999999999"
  },
  "created": "2023-03-03 00:13:45.497",
  "event": "group.policy.create",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk System SSO Settings Changed

#
Severity
high
Log types
Snyk.GroupAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects Snyk SSO Settings have been changed. The reference URL from Snyk indicates that these events are likely to originate exclusively from Snyk Support.

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.sso.auth0_connection.create",
    "group.sso.auth0_connection.edit",
    "group.sso.create",
    "group.sso.edit",
]


def rule(event):

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


def title(event):
    return (
        "Snyk: System SSO Setting event "
        f"[{event.deep_get('event', default='<NO_EVENT>')}] "
        f"performed by [{event.deep_get('userId', default='<NO_USERID>')}]"
    )


def alert_context(event):
    return snyk_alert_context(event)

Rule specification

AnalysisType: rule
Filename: snyk_system_sso.py
RuleID: "Snyk.System.SSO"
DisplayName: "Snyk System SSO Settings Changed"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
Tags:
  - Snyk
Severity: High
Description: >
  Detects Snyk SSO Settings have been changed.
  The reference URL from Snyk indicates that these events are likely to
  originate exclusively from Snyk Support.
Reference: https://docs.snyk.io/user-and-group-management/setting-up-sso-for-authentication/set-up-snyk-single-sign-on-sso
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event
  - p_any_ip_addresses
  - p_any_emails

Stages and Predicates

Fires on Snyk.GroupAudit events when the condition below holds.

Condition

  • event is one of group.sso.auth0_connection.create, group.sso.auth0_connection.edit, group.sso.create, group.sso.edit

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.sso.auth0_connection.create
  • group.sso.auth0_connection.edit
  • group.sso.create
  • group.sso.edit
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
event
userId

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "unknown": "contents"
  },
  "event": "group.sso.edit",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}

Snyk User Management

#
Severity
medium
Group by
event, groupId, orgId, userId
Log types
Snyk.GroupAudit, Snyk.OrgAudit
Tags
Snyk
Reference
docs.snyk.io
Source
github.com/panther-labs/panther-analysis

Detects when Snyk Users are changed

Detection logic

from panther_snyk_helpers import snyk_alert_context

ACTIONS = [
    "group.user.add",
    "group.user.provision.accept",
    "group.user.provision.create",
    "group.user.provision.delete",
    "group.user.remove",
    "org.user.add",
    "org.user.invite",
    "org.user.invite.accept",
    "org.user.invite.revoke",
    "org.user.invite_link.accept",
    "org.user.invite_link.create",
    "org.user.invite_link.revoke",
    "org.user.leave",
    "org.user.provision.accept",
    "org.user.provision.create",
    "org.user.provision.delete",
    "org.user.remove",
]


def rule(event):

    action = event.get("event", "<NO_EVENT>")
    # for org.user.add/group.user.add via SAML/SCIM
    # the attributes .userId and .content.publicUserId
    # have the same value
    if action.endswith(".user.add"):
        target_user = event.deep_get("content", "userPublicId", default="<NO_CONTENT_UID>")
        actor = event.get("userId", "<NO_USERID>")
        if target_user == actor:
            return False
    return action in ACTIONS


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


def alert_context(event):
    return snyk_alert_context(event)


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"

Rule specification

AnalysisType: rule
Filename: snyk_user_mgmt.py
RuleID: "Snyk.User.Management"
DisplayName: "Snyk User Management"
Enabled: true
LogTypes:
  - Snyk.GroupAudit
  - Snyk.OrgAudit
Tags:
  - Snyk
Severity: Medium
Description: >
  Detects when Snyk Users are changed
Runbook: |
  These actions in the Snyk Audit logs indicate that a User
  has been created/deleted/modified.

Reference: https://docs.snyk.io/snyk-admin/manage-users-and-permissions/member-roles
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
  - event

Stages and Predicates

Fires on Snyk.GroupAudit, Snyk.OrgAudit events when the condition below holds.

Condition

  • event is one of group.user.add, group.user.provision.accept, group.user.provision.create, group.user.provision.delete, group.user.remove (+12 more values, see Indicators below)

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
eventin
  • group.user.add
  • group.user.provision.accept
  • group.user.provision.create
  • group.user.provision.delete
  • group.user.remove
  • org.user.add
  • org.user.invite
  • org.user.invite.accept
  • org.user.invite.revoke
  • org.user.invite_link.accept
  • org.user.invite_link.create
  • org.user.invite_link.revoke
  • org.user.leave
  • org.user.provision.accept
  • org.user.provision.create
  • org.user.provision.delete
  • org.user.remove
field:"event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
userId

Response runbook

These actions in the Snyk Audit logs indicate that a User

has been created/deleted/modified.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "content": {
    "email": "user@example.com",
    "force": true,
    "name": "user@example.com",
    "userPublicId": "cccccccc-3333-4ddd-8ccc-755555555555",
    "username": "user@example.com"
  },
  "created": "2023-04-11 23:32:14.173",
  "event": "org.user.remove",
  "groupId": "8fffffff-1555-4444-b000-b55555555555",
  "orgId": "21111111-a222-4eee-8ddd-a99999999999",
  "userId": "05555555-3333-4ddd-8ccc-755555555555"
}