# GCS Bucket CORS Not Configured

> Missing CORS configuration on a GCS bucket only matters when browsers call the bucket cross-origin; ZopNight reports it as a low-severity RC-1230 finding, not a vulnerability. Detection fires solely on the discoverer's explicit cors_configured=false flag, so buckets that were never enriched are skipped rather than accused.

Source: https://zop.dev/integrations/gcp/recommendations/gcs-bucket-cors-not-configured
Updated: 2026-08-19

---

## A finding about browsers, not attackers

Honesty first: an absent CORS configuration is not an exposure. CORS is the mechanism by
which a bucket tells browsers which foreign origins may read its responses from JavaScript;
with no configuration, browsers simply block those cross-origin reads. Server-side clients,
`gcloud`, and signed-URL downloads opened directly are unaffected. So the rule describes a
functionality gap with a compliance-hygiene edge, and ZopNight rates it low accordingly. The
gap bites in one specific shape: a web app starts fetching objects from
`storage.googleapis.com` via XHR or `fetch`, requests fail with CORS errors, and someone
"fixes" it under deadline pressure with a wildcard `*` origin, which is the actual
misconfiguration worth preventing. Flagging unconfigured buckets early is a nudge to decide
the origin list deliberately instead of in an outage.

## When leaving it unconfigured is correct

Most buckets never serve a browser. For backups, data-lake zones, build artifacts, and log
sinks, no CORS entries is the right end state, and adding permissive entries would only
widen the surface. If a flagged bucket is in that category, resolve the finding
by confirming the bucket has no browser consumers, not by adding configuration for its own
sake.

## Inspect and set the CORS entries

```bash
gcloud storage buckets describe gs://BUCKET --format="json(cors_config)"
```

`null` reproduces the finding. For a bucket that does serve web apps, write a minimal
policy with named origins, narrow methods, and a sane cache time:

```bash
cat > cors.json <<'EOF'
[{"origin": ["https://app.example.com"], "method": ["GET"], "maxAgeSeconds": 3600}]
EOF
gcloud storage buckets update gs://BUCKET --cors-file=cors.json
```

Avoid `"origin": ["*"]` anywhere credentials or non-public data are involved.

## How the rule decides, and when it abstains

The discoverer computes `cors_configured` as a boolean (whether the bucket's CORS array has
at least 1 entry) and writes it into resource metadata. The rule fires only on the explicit
string false; an absent key means the bucket was never enriched, and the rule skips it
rather than firing on unknown state. Historically this was the only one of the six GCS
bucket rules still reading the legacy tags mirror of that value; it now reads metadata
directly like its siblings. Everything involved is a read (`storage.buckets.get` for
enrichment, discovery under `roles/cloudasset.viewer`). ZopNight never writes CORS policy
for you.
