GCS buckets with an empty CORS configuration
What does ZopNight detect here?
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.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1230 |
| Category | compliance |
| Severity | low |
| Metric | none — pure configuration read |
| Source | bucket_cors.go |
Where it applies
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
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:
cat > cors.json <<'EOF'[{"origin": ["https://app.example.com"], "method": ["GET"], "maxAgeSeconds": 3600}]EOFgcloud storage buckets update gs://BUCKET --cors-file=cors.jsonAvoid "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.