Detection rules › Panther
Panther rules: snyk
Snyk Miscellaneous Settings
#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
eventis one ofgroup.cloud_config.settings.edit,group.feature_flags.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one ofgroup.create,group.delete,group.edit,group.feature_flags.edit,group.org.add
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one oforg.integration.create,org.integration.delete,org.integration.edit,org.integration.settings.edit,org.request_access_settings.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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.descriptionis notNo new Code Analysis issues foundeventis one oforg.sast_settings.edit,org.project.attributes.edit,org.project.add,org.project.delete,org.project.fix_pr.manual_open
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
content.after.description | ne |
| field:"content.after.description" kind:ne value:"No new Code Analysis issues found" |
event | in |
| 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
#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
eventis one ofgroup.role.create,group.role.edit,group.user.role.create,group.user.role.delete,group.user.role.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one ofgroup.service_account.create,group.service_account.delete,group.service_account.edit,org.service_account.create,org.service_account.delete
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one ofgroup.request_access_settings.edit,org.request_access_settings.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| field:"event" kind:in |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
isEnabled | content.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
#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
eventis one ofgroup.policy.create,group.policy.delete,group.policy.edit,org.policy.edit,org.ignore_policy.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one ofgroup.sso.auth0_connection.create,group.sso.auth0_connection.edit,group.sso.create,group.sso.edit
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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
#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
eventis one ofgroup.user.add,group.user.provision.accept,group.user.provision.create,group.user.provision.delete,group.user.remove
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event | in |
| 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"
}