SpikerSoft.Api/Extensions/ServiceCollectionExtensions.csAddCorsConfiguration builds the CORS policy with AllowCredentials() + configured Origins, but the fallback when Origins is null/empty is:
else{// Fallback: Allow any origin when Origins is not configuredpolicy.SetIsOriginAllowed(_=>true);// reflects EVERY origin, + AllowCredentials()}
The developer worked around the framework's built-in guard (AllowAnyOrigin() can't be combined with AllowCredentials()) by using SetIsOriginAllowed(_ => true) — which reflects the request's origin for any site while credentials are allowed. That means any website can make credentialed cross-origin requests to the API and read the responses → authenticated-data exfiltration / CSRF-style abuse.
Why it matters even though prod sets Origins
In normal operation Origins is configured (per api-conventions rule; E2E allowlists https://localhost:4200), so the dangerous branch is dormant. But it's a silent fail-OPEN on a config gap: a missing env var, an empty array, or a typo in the Origins key drops the whole API to universal credentialed CORS with no error. For a platform serving minors at scale, a config slip shouldn't silently disable the same-origin boundary.
Fix (fail closed)
When Origins is unconfigured, refuse cross-origin (add no origins) and log a loud CRITICAL line telling the operator to set Origins, instead of reflecting all origins. Same-origin traffic is unaffected; a correctly-configured deployment is unchanged.
Verification
Extended ServiceCollectionExtensionsCorsAndSignalRTests to assert the actual policy behavior: with Origins set, the configured origin is allowed and an arbitrary origin is not; with Originsabsent, an arbitrary origin is not allowed (fail closed). Build clean.
Resolved by spikersoft-backend PR (linked below).
## Problem (fail-open default — same class as #408)
`SpikerSoft.Api/Extensions/ServiceCollectionExtensions.cs` `AddCorsConfiguration` builds the CORS policy with `AllowCredentials()` + configured `Origins`, but the **fallback** when `Origins` is null/empty is:
```csharp
else
{
// Fallback: Allow any origin when Origins is not configured
policy.SetIsOriginAllowed(_ => true); // reflects EVERY origin, + AllowCredentials()
}
```
The developer worked *around* the framework's built-in guard (`AllowAnyOrigin()` can't be combined with `AllowCredentials()`) by using `SetIsOriginAllowed(_ => true)` — which reflects the request's origin for **any** site while credentials are allowed. That means **any website can make credentialed cross-origin requests to the API and read the responses** → authenticated-data exfiltration / CSRF-style abuse.
## Why it matters even though prod sets `Origins`
In normal operation `Origins` is configured (per api-conventions rule; E2E allowlists `https://localhost:4200`), so the dangerous branch is dormant. But it's a **silent fail-OPEN on a config gap**: a missing env var, an empty array, or a typo in the `Origins` key drops the whole API to universal credentialed CORS with no error. For a platform serving minors at scale, a config slip shouldn't silently disable the same-origin boundary.
## Fix (fail closed)
When `Origins` is unconfigured, **refuse cross-origin** (add no origins) and log a loud `CRITICAL` line telling the operator to set `Origins`, instead of reflecting all origins. Same-origin traffic is unaffected; a correctly-configured deployment is unchanged.
## Verification
Extended `ServiceCollectionExtensionsCorsAndSignalRTests` to assert the actual policy behavior: with `Origins` set, the configured origin is allowed and an arbitrary origin is not; with `Origins` **absent**, an arbitrary origin is **not** allowed (fail closed). Build clean.
Resolved by spikersoft-backend PR (linked below).
Resolved in spikersoft-backend PR #129 (merged to master as e4ed404). CORS now fails closed when Origins is unconfigured (refuses cross-origin + logs CRITICAL) instead of reflecting any origin with credentials. 6/6 tests assert the actual policy behavior. Closing.
Resolved in spikersoft-backend PR #129 (merged to `master` as `e4ed404`). CORS now fails **closed** when `Origins` is unconfigured (refuses cross-origin + logs CRITICAL) instead of reflecting any origin with credentials. 6/6 tests assert the actual policy behavior. Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem (fail-open default — same class as #408)
SpikerSoft.Api/Extensions/ServiceCollectionExtensions.csAddCorsConfigurationbuilds the CORS policy withAllowCredentials()+ configuredOrigins, but the fallback whenOriginsis null/empty is:The developer worked around the framework's built-in guard (
AllowAnyOrigin()can't be combined withAllowCredentials()) by usingSetIsOriginAllowed(_ => true)— which reflects the request's origin for any site while credentials are allowed. That means any website can make credentialed cross-origin requests to the API and read the responses → authenticated-data exfiltration / CSRF-style abuse.Why it matters even though prod sets
OriginsIn normal operation
Originsis configured (per api-conventions rule; E2E allowlistshttps://localhost:4200), so the dangerous branch is dormant. But it's a silent fail-OPEN on a config gap: a missing env var, an empty array, or a typo in theOriginskey drops the whole API to universal credentialed CORS with no error. For a platform serving minors at scale, a config slip shouldn't silently disable the same-origin boundary.Fix (fail closed)
When
Originsis unconfigured, refuse cross-origin (add no origins) and log a loudCRITICALline telling the operator to setOrigins, instead of reflecting all origins. Same-origin traffic is unaffected; a correctly-configured deployment is unchanged.Verification
Extended
ServiceCollectionExtensionsCorsAndSignalRTeststo assert the actual policy behavior: withOriginsset, the configured origin is allowed and an arbitrary origin is not; withOriginsabsent, an arbitrary origin is not allowed (fail closed). Build clean.Resolved by spikersoft-backend PR (linked below).
Resolved in spikersoft-backend PR #129 (merged to
masterase4ed404). CORS now fails closed whenOriginsis unconfigured (refuses cross-origin + logs CRITICAL) instead of reflecting any origin with credentials. 6/6 tests assert the actual policy behavior. Closing.