GCP Firewall Rule Created


Description

This rule detects creations of GCP firewall rules.

Query · python

from panther_gcp_helpers import gcp_alert_context

RULE_CREATED_PARTS = [
    ".Firewall.Create",
    ".compute.firewalls.insert",
]


def rule(event):
    method = event.deep_get("protoPayload", "methodName", default="")
    return any(part in method for part in RULE_CREATED_PARTS)


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    resource = event.deep_get(
        "protoPayload",
        "resourceName",
        default="<RESOURCE_NOT_FOUND>",
    )
    resource_id = event.deep_get(
        "resource",
        "labels",
        "firewall_rule_id",
        default="<RESOURCE_ID_NOT_FOUND>",
    )
    if resource_id != "<RESOURCE_ID_NOT_FOUND>":
        return f"[GCP]: [{actor}] created firewall rule with resource ID [{resource_id}]"
    return f"[GCP]: [{actor}] created firewall rule for resource [{resource}]"


def dedup(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    return actor


def alert_context(event):
    return gcp_alert_context(event)

Analyst notes

Ensure that the rule creation was expected. Firewall rule creations can expose [vulnerable] resoures to the internet.

Raw source GCP Firewall Rule Created · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
DedupPeriodMinutes: 90
DisplayName: GCP Firewall Rule Created
Enabled: true
Filename: gcp_firewall_rule_created.py
RuleID: "GCP.Firewall.Rule.Created"
Severity: Low
LogTypes:
  - GCP.AuditLog
Tags:
  - GCP
  - Firewall
  - Networking
  - Infrastructure
Description: >
  This rule detects creations of GCP firewall rules.
Runbook: >
  Ensure that the rule creation was expected. Firewall rule creations can expose [vulnerable] resoures to the internet.
Reference: https://cloud.google.com/firewall/docs/about-firewalls
Tests:
  - Name: compute.firewalls.create-should-alert
    LogType: GCP.AuditLog
    ExpectedResult: true
    Log:
      {
        "insertid": "-xxxxxxxxxxxx",
        "logname": "projects/test-project-123456/logs/cloudaudit.googleapis.com%2Factivity",
        "operation":
          {
            "first": true,
            "id": "operation-1684869580331-5fc6144d418a9-e1332ca3-59c615ac",
            "producer": "compute.googleapis.com",
          },
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "user@domain.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "compute.firewalls.update",
                  "resourceAttributes":
                    {
                      "name": "projects/test-project-123456/global/firewalls/firewall-create",
                      "service": "compute",
                      "type": "compute.firewalls",
                    },
                },
                {
                  "granted": true,
                  "permission": "compute.networks.updatePolicy",
                  "resourceAttributes":
                    {
                      "name": "projects/test-project-123456/global/networks/default",
                      "service": "compute",
                      "type": "compute.networks",
                    },
                },
              ],
            "methodName": "v1.compute.firewalls.insert",
            "request":
              {
                "@type": "type.googleapis.com/compute.firewalls.insert",
                "denieds": [{ "IPProtocol": "all" }],
              },
            "requestMetadata":
              {
                "callerIP": "12.12.12.12",
                "callerSuppliedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe)",
                "destinationAttributes": {},
                "requestAttributes":
                  {
                    "auth": {},
                    "reason": "8uSywAYQGg5Db2xpc2V1bSBGbG93cw",
                    "time": "2023-05-23T19:19:41.154751Z",
                  },
              },
            "resourceName": "projects/test-project-123456/global/firewalls/firewall-create",
            "response":
              {
                "@type": "type.googleapis.com/operation",
                "id": "896785227463044899",
                "insertTime": "2023-05-23T12:19:40.876-07:00",
                "name": "operation-1684869580331-5fc6144d418a9-e1332ca3-59c615ac",
                "operationType": "patch",
                "progress": "0",
                "selfLink": "https://www.googleapis.com/compute/v1/projects/test-project-123456/global/operations/operation-1684869580331-5fc6144d418a9-e1332ca3-59c615ac",
                "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/test-project-123456/global/operations/896785227463044899",
                "startTime": "2023-05-23T12:19:40.888-07:00",
                "status": "RUNNING",
                "targetId": "6563507997690081088",
                "targetLink": "https://www.googleapis.com/compute/v1/projects/test-project-123456/global/firewalls/firewall-create",
                "user": "user@domain.com",
              },
            "serviceName": "compute.googleapis.com",
          },
        "receivetimestamp": "2023-05-23 19:19:41.238",
        "resource":
          {
            "labels":
              {
                "firewall_rule_id": "6563507997690081088",
                "project_id": "test-project-123456",
              },
            "type": "gce_firewall_rule",
          },
        "severity": "NOTICE",
        "timestamp": "2023-05-23 19:19:40.353",
      }
  - Name: appengine.firewall.create-should-alert
    LogType: GCP.AuditLog
    ExpectedResult: true
    Log:
      {
        "insertid": "-xxxxxxxxxxxx",
        "logname": "projects/test-project-123456/logs/cloudaudit.googleapis.com%2Factivity",
        "protopayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "user@domain.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "appengine.applications.update",
                  "resource": "apps/test-project-123456",
                  "resourceAttributes": {},
                },
              ],
            "methodName": "google.appengine.v1.Firewall.CreateIngressRule",
            "requestMetadata":
              {
                "callerIP": "12.12.12.12",
                "destinationAttributes": {},
                "requestAttributes":
                  { "auth": {}, "time": "2023-05-23T19:28:35.172216Z" },
              },
            "resourceName": "apps/test-project-123456",
            "serviceData":
              {
                "@type": "type.googleapis.com/google.appengine.v1beta4.AuditData",
              },
            "serviceName": "appengine.googleapis.com",
            "status": {},
          },
        "receivetimestamp": "2023-05-23 19:28:35.479",
        "resource":
          {
            "labels":
              {
                "module_id": "",
                "project_id": "test-project-123456",
                "version_id": "",
                "zone": "",
              },
            "type": "gae_app",
          },
        "severity": "NOTICE",
        "timestamp": "2023-05-23 19:28:35.049",
      }
  - Name: compute.non-create.firewall.method-should-not-alert
    LogType: GCP.AuditLog
    ExpectedResult: false
    Log: { "methodName": "v1.compute.firewalls.patch" }
  - Name: appengine.compute.non-create.firewall.method-should-not-alert
    LogType: GCP.AuditLog
    ExpectedResult: false
    Log: { "methodName": "appengine.compute.v1.Firewall.PatchIngressRule" }
  - Name: randomservice.firewall-create.method-should-alert
    LogType: GCP.AuditLog
    ExpectedResult: true
    Log:
      {
        "protoPayload":
          {
            "authenticationInfo": { "principalEmail": "user@domain.com" },
            "methodName": "randomservice.compute.v1.Firewall.CreateIngressRule",
            "resourceName": "randomservice/test-project-123456/firewall/ingressRules/1000",
            "requestMetadata":
              {
                "callerIP": "12.12.12.12",
                "destinationAttributes": {},
                "requestAttributes":
                  { "auth": {}, "time": "2023-05-23T19:28:44.663413Z" },
              },
          },
        "resource":
          {
            "labels":
              {
                "firewall_rule_id": "6563507997690081088",
                "project_id": "test-project-123456",
              },
            "type": "gce_firewall_rule",
          },
      }


# ------ paired body: gcp_firewall_rule_created.py ------

from panther_gcp_helpers import gcp_alert_context

RULE_CREATED_PARTS = [
    ".Firewall.Create",
    ".compute.firewalls.insert",
]


def rule(event):
    method = event.deep_get("protoPayload", "methodName", default="")
    return any(part in method for part in RULE_CREATED_PARTS)


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    resource = event.deep_get(
        "protoPayload",
        "resourceName",
        default="<RESOURCE_NOT_FOUND>",
    )
    resource_id = event.deep_get(
        "resource",
        "labels",
        "firewall_rule_id",
        default="<RESOURCE_ID_NOT_FOUND>",
    )
    if resource_id != "<RESOURCE_ID_NOT_FOUND>":
        return f"[GCP]: [{actor}] created firewall rule with resource ID [{resource_id}]"
    return f"[GCP]: [{actor}] created firewall rule for resource [{resource}]"


def dedup(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    return actor


def alert_context(event):
    return gcp_alert_context(event)

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.