gcp-composer-web-server-exposed-internet

Airflow web server in Composer 2 environment is internet-accessible when config.webServerNetworkAccessControl.allowedIpRanges includes 0.0.0.0/0.

derived gcp emits ExposedToInternet

match (record)

{ "field": "config.webServerNetworkAccessControl.allowedIpRanges", "resource_type": "google.composer.Environment" }

where

config.webServerNetworkAccessControl.allowedIpRanges includes '0.0.0.0/0' OR '::/0' config.webServerConfig.machineType is set (Composer 2 only; Composer 1 web server is internal)

emit

source typeData
target typeAnonymousIdentity
source<Composer Environment node (Airflow web server)>
target<anonymous internet principal (0.0.0.0/0 ingress)>
state logicACTIVE: the environment's Airflow web server is directly reachable from the internet at https://<env-id>-<project>-web.<zone>.composer.googleusercontent.com. This is a data-plane exposure, not requiring any IAM permission to observe or interact with. BLOCKED only if a VPC Service Controls perimeter or a firewall rule explicitly restricts internet ingress to the web server endpoint.

Narrative

Composer environment {env.name}'s Airflow web server is accessible from the internet at https://{env_id}-{project}-web.{zone}.composer.googleusercontent.com. Any internet user can browse DAGs, view execution history, and trigger runs (executeAirflowCommand perm not required for basic web UI access). Combined with a CanModifyCode or CanTrigger capability on the environment, this is a critical attack vector.

Raw rule rules/derived/gcp/composer.yaml

id: gcp-composer-web-server-exposed-internet
emits: ExposedToInternet
description: Airflow web server in Composer 2 environment is internet-accessible when config.webServerNetworkAccessControl.allowedIpRanges
  includes 0.0.0.0/0.
match_record:
  resource_type: google.composer.Environment
  field: config.webServerNetworkAccessControl.allowedIpRanges
where:
- config.webServerNetworkAccessControl.allowedIpRanges includes '0.0.0.0/0' OR '::/0'
- config.webServerConfig.machineType is set (Composer 2 only; Composer 1 web server is internal)
emit:
  source_type: Data
  target_type: AnonymousIdentity
  source: <Composer Environment node (Airflow web server)>
  target: <anonymous internet principal (0.0.0.0/0 ingress)>
  permissions: []
  conditions: []
  state_logic: 'ACTIVE: the environment''s Airflow web server is directly reachable from the internet
    at https://<env-id>-<project>-web.<zone>.composer.googleusercontent.com. This is a data-plane exposure,
    not requiring any IAM permission to observe or interact with. BLOCKED only if a VPC Service Controls
    perimeter or a firewall rule explicitly restricts internet ingress to the web server endpoint.'
  confidence: 1.0
  derived_from:
  - <config.webServerNetworkAccessControl.allowedIpRanges from google.composer.Environment>
  false_positive_note: 'Verify that allowedIpRanges is set at the environment level; if it is not set,
    the default is to allow 0.0.0.0/0 (world accessible). Check if a VPC Service Controls perimeter or
    an organization policy restricts Composer web access at the org/folder/project level. Note: Composer
    1 web servers are internal by default; this rule applies to Composer 2 only. The web server URL is
    publicly discoverable by querying the GCP project''s public metadata.'
  narrative: Composer environment {env.name}'s Airflow web server is accessible from the internet at https://{env_id}-{project}-web.{zone}.composer.googleusercontent.com.
    Any internet user can browse DAGs, view execution history, and trigger runs (executeAirflowCommand
    perm not required for basic web UI access). Combined with a CanModifyCode or CanTrigger capability
    on the environment, this is a critical attack vector.
move · open · esc close