Cross-Origin Resource Sharing (CORS)
Enable and configure CORS in Quarkus to specify allowed origins, methods, and headers, guiding browsers in handling cross-origin requests safely.
Cross-Origin Resource Sharing (CORS) uses HTTP headers to manage browser requests for resources from external origins securely. By specifying permitted origins, methods, and headers, Quarkus servers can use the CORS filter to enable browsers to request resources across domains while maintaining controlled access. This mechanism enhances security and supports legitimate cross-origin requests. For more on origin definitions, see the Web Origin Concept.
Enabling the CORS filter
To enforce CORS policies in your application, enable the Quarkus CORS filter by adding the following line to the src/main/resources/application.properties file:
quarkus.http.cors.enabled=true
The filter intercepts all incoming HTTP requests to identify cross-origin requests and applies the configured policy. The filter then adds CORS headers to the HTTP response, informing browsers about allowed origins and access parameters. For preflight requests, the filter returns an HTTP response immediately. For regular CORS requests, the filter denies access with an HTTP 403 status if the request violates the configured policy; otherwise, the filter forwards the request to the destination if the policy allows it.
|
Despite its name, the CORS filter can also prevent CSRF attacks based on Origin verification. Therefore, since the browser is expected to set an Origin header for cross-origin JavaScript and HTML form requests, you might want to consider using the CORS filter instead of the REST CSRF filter. You must confirm that the browser sets an |
For detailed configuration options, see the following Configuration Properties section.
Example CORS configuration
The following example shows a complete CORS filter configuration, including a regular expression to define one of the origins.
quarkus.http.cors.enabled=true (1)
quarkus.http.cors.origins=http://example.com,http://www.example.io,/https://([a-z0-9\\-_]+)\\\\.app\\\\.mydomain\\\\.com/ (2)
quarkus.http.cors.methods=GET,PUT,POST (3)
quarkus.http.cors.headers=X-Custom (4)
quarkus.http.cors.exposed-headers=Content-Disposition (5)
quarkus.http.cors.access-control-max-age=24H (6)
quarkus.http.cors.access-control-allow-credentials=true (7)
| 1 | Enables the CORS filter. |
| 2 | Specifies allowed origins, including a regular expression. When not specified, CORS is not permitted, and only same-origin requests are allowed. |
| 3 | Lists allowed HTTP methods for cross-origin requests. |
| 4 | Declares custom headers that clients can include in requests. |
| 5 | Identifies response headers that clients can access. |
| 6 | Sets how long preflight request results are cached. |
| 7 | Allows cookies or credentials in cross-origin requests. |
When using regular expressions in an application.properties file, escape special characters with four backward slashes (\\\\) to ensure proper behavior.
For example:
-
\\\\.matches a literal.character. -
\\.matches any single character as a regular expression metadata character.
|
Incorrectly escaped patterns can lead to unintended behavior or security vulnerabilities. Always verify regular expression syntax before deployment. |
When to accept all origins
|
Allowing unrestricted origins with |
The only exception where accepting all origins might be appropriate in production is for read-only public API applications that have no side effects of any kind, such as managing cookies, saving request data on the disk, or similar operations.
In such cases, to improve the HTTP cache performance, you might want to return a literal * origin by setting quarkus.http.cors.return-exact-origins=false to avoid the Vary: Origin response header.
Also, since configuring origins during development can be challenging, consider allowing all origins in development mode:
quarkus.http.cors.enabled=true
%dev.quarkus.http.cors.origins=/.*/
Configuring the CORS filter programmatically
|
Configure the CORS filter by using configuration properties or programmatically, but not both. |
To enforce CORS policies in your application, enable the Quarkus CORS filter with the io.quarkus.vertx.http.security.HttpSecurity CDI event:
package org.acme.http.security;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;
public class CorsProgrammaticConfig {
void configure(@Observes HttpSecurity httpSecurity) {
httpSecurity.cors("https://example.com");
}
}
Use the io.quarkus.vertx.http.security.CORS builder to create a complete CORS configuration:
package org.acme.http.security;
import io.quarkus.vertx.http.security.CORS;
import io.quarkus.vertx.http.security.HttpSecurity;
import jakarta.enterprise.event.Observes;
public class CorsProgrammaticConfig {
void configure(@Observes HttpSecurity httpSecurity) {
httpSecurity.cors(CORS.builder()
.origin("https://example.com")
.method("POST")
.build());
}
}