apache / apache/grails-core

CORS support broken in Grails 4

Open
#11,786 3 comments 1 reaction 0 assignees View on GitHub
info: no example attached status: awaiting feedback
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

From some investigation, it's possible this is a documentation bug, possibly caused by changes in underlying Spring. But not being an expert in grails/cors, someone should look at it, and at the very least, update the doco.

Here's the situation...

I have a working Angular / Grails 3 app. It has the most basic CORS setup in application.yml:

```
grails:
cors:
enabled: true
```

If I look at what happens in Fiddler, the server responds with these headers:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:4200

Good stuff.

But in Grails 4 the server responds like this:

Access-Control-Allow-Origin: *

This results in the browser failing like this:

Access to XMLHttpRequest at 'http://localhost:8080/plant/sectionData/' from origin 'http://localhost:4200' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

But it turns out if I turn on "allowedCredentials" it starts to work...

```
grails:
cors:
enabled: true
allowCredentials: true
```

However the documentation claims that merely settings grails.cors.enabled=true results in a mapping of "/**" with "allowCredentials= true".

As far as I can see, the reason for this change in behaviour is found in Spring's CorsConfiguration.java: applyPermitDefaultValues, where Spring4 used to have a line:

```
public CorsConfiguration applyPermitDefaultValues() {
//blah blah
if (this.allowCredentials == null) {
this.setAllowCredentials(true);
}
//blah blah
}
```

But Spring 5 doesn't have that line in the code.

So I'm assuming this is for some reason deliberate, and I guess maybe the correct thing is to update this table in the documentation: https://docs.grails.org/4.0.10/guide/single.html#cors
allowedOrigins | ['*']
-- | --
allowedMethods | ['*']
allowedHeaders | ['*']
exposedHeaders | null
maxAge | 1800
allowCredentials | true

to align with what is currently existing in CorsConfiguration.applyPermitDefaultValues()

and present some examples that actually work.

### Task List

Create an Angular or javascript app, that makes grails requests. Use this config:
```

grails:
cors:
enabled: true
```

Observe the wrong headers.

### Expected Behaviour

Headers returned by Grails 3, as per above

### Actual Behaviour

The headers make browsers CORS security fail.

### Environment Information

- **Operating System**: Windows 10
- **Grails Version:** 4.0.0 through 4.0.9 fail
- **JDK Version:** 1.8.0

### Example Application

Contributor guide

Open the contributing guide

Research direction

Start with the CORS configuration in application.yml, the Grails 4 CORS section at guide/single.html#cors, and Spring's CorsConfiguration.applyPermitDefaultValues. Reproduce the headers with the minimal Angular or JavaScript request, determine whether the behavior or documentation is incorrect, and finish with working behavior and documentation that matches the observed configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, groovy, spring
Domain
api, backend, documentation, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.