Browser API CORS Allowlist and Credential Exposure Gate avatar

Browser API CORS Allowlist and Credential Exposure Gate

Pricing

from $10.00 / 1,000 cors gate run starts

Go to Apify Store
Browser API CORS Allowlist and Credential Exposure Gate

Browser API CORS Allowlist and Credential Exposure Gate

Sends a real OPTIONS preflight and a real cross-origin GET from each origin that you name, against each API path that you name. Reports which origins the API accepts, which accept credentials, and every violation class: wildcard with credentials, origin r

Pricing

from $10.00 / 1,000 cors gate run starts

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Send a real preflight request and a real cross-origin request from each origin that you name, against each API path that you name. The report says which origins your API accepts, which of them may send credentials, and what changed since the last run.

Every incumbent in the store grades response headers on one GET request. This Actor sends an OPTIONS preflight from a named origin, so it finds the two faults that a header grade cannot see: an API that copies any origin into Access-Control-Allow-Origin while it allows credentials, and an API that accepts an origin which you never wanted.

HTTP only. No browser, no proxy and no external database.

What the Actor sends

For each origin and path pair:

  1. OPTIONS <path> with Origin, Access-Control-Request-Method and Access-Control-Request-Headers. This is the preflight that a browser sends.
  2. GET <path> with Origin. This is the real cross-origin request.

The Actor never sends a state-changing request. POST, PUT and DELETE are only named in the preflight and compared against Access-Control-Allow-Methods. The response body is never read; only the headers carry the CORS policy.

When a path reflects the sent origin, the Actor sends two more calls from a control origin (https://cors-probe-reflection-check.example.net). That pair separates a real origin reflection from a static wildcard and from a static allow list that happens to hold your origin.

Input

Run it with empty input to see the default fixture against a stable public API. That target answers with Access-Control-Allow-Origin: *, so the fixture run ends with a failed gate and one deny_list_origin_accepted record for each deny-list origin. The run itself succeeds: a gate verdict is a result, never a failed run.

FieldDefaultMeaning
apiBaseUrlhttps://api.github.comThe base URL of an API that you own or may test. Private, loopback and reserved addresses are refused.
paths["/", "/rate_limit"]1 to 25 endpoint paths.
expectedAllowOrigins["https://app.example.com"]Origins that must be accepted.
expectedDenyOrigins["https://evil.example.com", "null", "http://attacker.example"]Origins that must be refused.
includeSubdomainProbetrueAdd https://cors-probe.<your domain> to the deny list.
methods["GET", "POST", "PUT", "DELETE"]Methods to request in the preflight. The first one is sent in Access-Control-Request-Method.
requestHeaders["authorization", "content-type"]Headers to request in the preflight.
authorizationStatementsee schemaFree text. You confirm ownership. The Actor writes it to the run log and to the summary.
trackMatrixtrueKeep the verdict matrix in the key-value store and report the diff.
matrixKey""Empty means: derive the key from the base URL.
timeoutSeconds15Timeout of one request.
maxConcurrency5Pairs probed at the same time.
maxRequests900Hard bound on the run.
maxRedirects0A browser preflight does not follow a redirect. Each hop that the Actor follows takes the public-address test again.

An origin that stands in both lists is treated as an allow-list origin.

Output

The dataset holds four record types.

probe — one row for each origin and path pair: origin, path, method, preflightStatus, actualStatus, allowOrigin, reflectsOrigin, allowCredentials, allowedMethods, allowedHeaders, missingMethods, missingHeaders, varyOrigin, maxAge, accepted, changeSinceLastRun and a verdict of expected_allow_ok, expected_deny_ok, unexpected_allow or unexpected_deny.

violation — the violation list. Each item carries a named class:

ClassSeverityMeaning
origin_reflection_with_credentialscriticalThe API copies the sent origin and allows credentials. A control origin was reflected too, so any site can read the answer of a signed-in user.
wildcard_with_credentialshighAccess-Control-Allow-Origin: * together with Access-Control-Allow-Credentials: true. A browser refuses that pair, so your own credentialed call fails.
null_origin_acceptedhighThe API accepts the origin value null, which a sandboxed frame sends.
deny_list_origin_acceptedhighAn origin of your deny list is accepted.
allow_list_origin_refusedmediumAn origin of your allow list is refused, so your application breaks.
missing_vary_originlowAn origin-dependent Access-Control-Allow-Origin without Vary: Origin. A shared cache can then give one origin the header of another.

The three classes that describe the endpoint itself (wildcard_with_credentials, origin_reflection_with_credentials, missing_vary_origin) are written once for each path. The three classes that describe one pair are written for each pair.

change — the diff against the last run: became_accepted, became_refused, credentials_enabled or credentials_disabled. The first run writes the matrix and reports no diff.

summary — one record with gatePass, the counts, status, note and your authorizationStatement. The gate passes when there is no violation, no failed pair and no skipped pair.

A business verdict is never a failed run. A failed gate, a refused target, an unreachable API and zero violations all end with a SUCCEEDED run, a dataset record and a status message. Only a malfunction, for example an input that cannot be parsed, gives a failed run.

Pay per event

EventUnitPrice
cors-gate-run-startone runUSD 0.01
origin-endpoint-probedone origin and path pair, preflight plus actual requestUSD 0.003
violation-recordedone confirmed violation in the violation listUSD 0.03

A pair that was skipped by the request bound, and a pair that never reached the API, are not charged. A matrix of 8 origins by 25 paths is 200 pairs, which is USD 0.60 plus the run start and the violations.

Repeat use

Run it once after each deployment of the API or of the gateway, through your build pipeline, and once a week as a regression run. CORS policy lives in gateway configuration, so it drifts silently at each infrastructure change. The change records name the drift.

Authorization

The Actor sends requests to a live API. Run it only against an API that you own, or that you are authorized to test. State that in authorizationStatement; the Actor keeps the text with the report.

Development

uv sync
uv run pytest
uv run ruff check .