Skip to content

Commit

Permalink
Snowflake Brute Force Tuning (#1477)
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-githubs authored Jan 17, 2025
1 parent faebb96 commit 7362dd2
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
15 changes: 14 additions & 1 deletion rules/snowflake_rules/snowflake_stream_brute_force_by_ip.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
def rule(event):
# Return true for any login attempt; Let Panther's dedup and threshold handle the brute force
# detection.
return event.get("EVENT_TYPE") == "LOGIN" and event.get("IS_SUCCESS") == "NO"
return (
event.get("EVENT_TYPE") == "LOGIN"
and event.get("IS_SUCCESS") == "NO"
and event.get("ERROR_MESSAGE") != "OVERFLOW_FAILURE_EVENTS_ELIDED"
# ^^ OVERFLOW_FAILURE_EVENTS_ELIDED are placeholder logs -> no point in alerting
)


def title(event):
Expand All @@ -12,6 +17,14 @@ def title(event):
)


def severity(event):
# If the error appears to be caused by an automation issue, downgrade to INFO
common_errors = {"JWT_TOKEN_INVALID_PUBLIC_KEY_FINGERPRINT_MISMATCH"}
if event.get("ERROR_MESSAGE") in common_errors:
return "INFO"
return "DEFAULT"


def dedup(event):
return event.get("CLIENT_IP", "<UNKNOWN IP>") + event.get(
"REPORTED_CLIENT_TYPE", "<UNKNOWN CLIENT TYPE>"
Expand Down
39 changes: 39 additions & 0 deletions rules/snowflake_rules/snowflake_stream_brute_force_by_ip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,42 @@ Tests:
"REPORTED_CLIENT_VERSION": "1.11.1",
"USER_NAME": "luthor@lexcorp.com"
}
- Name: Unsuccessful Login due to Invalid JWT Fingerprint
ExpectedResult: true
Log:
{
"p_event_time": "2024-10-08 14:38:46.061000000",
"p_log_type": "Snowflake.LoginHistory",
"p_source_label": "Snowflake Prod",
"CLIENT_IP": "1.2.3.4",
"ERROR_CODE": 394304,
"ERROR_MESSAGE": "JWT_TOKEN_INVALID_PUBLIC_KEY_FINGERPRINT_MISMATCH",
"EVENT_ID": "393754014361778",
"EVENT_TIMESTAMP": "2024-10-08 14:38:46.061000000",
"EVENT_TYPE": "LOGIN",
"FIRST_AUTHENTICATION_FACTOR": "PASSWORD",
"IS_SUCCESS": "NO",
"RELATED_EVENT_ID": "0",
"REPORTED_CLIENT_TYPE": "OTHER",
"REPORTED_CLIENT_VERSION": "1.11.1",
"USER_NAME": "luthor@lexcorp.com"
}
- Name: Overflow Failure
ExpectedResult: false
Log:
{
"p_event_time": "2024-11-15 00:12:24.288000000",
"p_log_type": "Snowflake.LoginHistory",
"p_parse_time": "2024-11-15 02:46:25.862374468",
"CLIENT_IP": "0.0.0.0",
"ERROR_CODE": 390156,
"ERROR_MESSAGE": "OVERFLOW_FAILURE_EVENTS_ELIDED",
"EVENT_ID": "16592193114297018",
"EVENT_TIMESTAMP": "2024-11-15 00:12:24.288000000",
"EVENT_TYPE": "LOGIN",
"IS_SUCCESS": "NO",
"RELATED_EVENT_ID": "0",
"REPORTED_CLIENT_TYPE": "OTHER",
"REPORTED_CLIENT_VERSION": "0",
"USER_NAME": "luthor@lexcorp.com"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
def rule(event):
# Return true for any login attempt; Let Panther's dedup and threshold handle the brute force
# detection.
return event.get("EVENT_TYPE") == "LOGIN" and event.get("IS_SUCCESS") == "NO"
return (
event.get("EVENT_TYPE") == "LOGIN"
and event.get("IS_SUCCESS") == "NO"
and event.get("ERROR_MESSAGE") != "OVERFLOW_FAILURE_EVENTS_ELIDED"
# ^^ OVERFLOW_FAILURE_EVENTS_ELIDED are placeholder logs -> no point in alerting
)


def title(event):
Expand All @@ -10,6 +15,14 @@ def title(event):
)


def severity(event):
# If the error appears to be caused by an automation issue, downgrade to INFO
common_errors = {"JWT_TOKEN_INVALID_PUBLIC_KEY_FINGERPRINT_MISMATCH"}
if event.get("ERROR_MESSAGE") in common_errors:
return "INFO"
return "DEFAULT"


def dedup(event):
return event.get("USER_NAME", "<UNKNOWN USER>") + event.get(
"REPORTED_CLIENT_TYPE", "<UNKNOWN CLIENT TYPE>"
Expand Down
39 changes: 39 additions & 0 deletions rules/snowflake_rules/snowflake_stream_brute_force_by_username.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,42 @@ Tests:
"REPORTED_CLIENT_VERSION": "1.11.1",
"USER_NAME": "luthor@lexcorp.com"
}
- Name: Unsuccessful Login due to Invalid JWT Fingerprint
ExpectedResult: true
Log:
{
"p_event_time": "2024-10-08 14:38:46.061000000",
"p_log_type": "Snowflake.LoginHistory",
"p_source_label": "Snowflake Prod",
"CLIENT_IP": "1.2.3.4",
"ERROR_CODE": 394304,
"ERROR_MESSAGE": "JWT_TOKEN_INVALID_PUBLIC_KEY_FINGERPRINT_MISMATCH",
"EVENT_ID": "393754014361778",
"EVENT_TIMESTAMP": "2024-10-08 14:38:46.061000000",
"EVENT_TYPE": "LOGIN",
"FIRST_AUTHENTICATION_FACTOR": "PASSWORD",
"IS_SUCCESS": "NO",
"RELATED_EVENT_ID": "0",
"REPORTED_CLIENT_TYPE": "OTHER",
"REPORTED_CLIENT_VERSION": "1.11.1",
"USER_NAME": "luthor@lexcorp.com"
}
- Name: Overflow Failure
ExpectedResult: false
Log:
{
"p_event_time": "2024-11-15 00:12:24.288000000",
"p_log_type": "Snowflake.LoginHistory",
"p_parse_time": "2024-11-15 02:46:25.862374468",
"CLIENT_IP": "0.0.0.0",
"ERROR_CODE": 390156,
"ERROR_MESSAGE": "OVERFLOW_FAILURE_EVENTS_ELIDED",
"EVENT_ID": "16592193114297018",
"EVENT_TIMESTAMP": "2024-11-15 00:12:24.288000000",
"EVENT_TYPE": "LOGIN",
"IS_SUCCESS": "NO",
"RELATED_EVENT_ID": "0",
"REPORTED_CLIENT_TYPE": "OTHER",
"REPORTED_CLIENT_VERSION": "0",
"USER_NAME": "luthor@lexcorp.com"
}

0 comments on commit 7362dd2

Please sign in to comment.