optionValue in <g:select> is not escaped when message() is used in a closure
- Dominant language
- Groovy
- Stars
- 2.9k
- Forks
- 975
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 92
Description
### Expected Behavior
When using a closure to transform the `optionValue` attribute in a `` element, the resulting string returned from `message()` should be escaped as per [section 16.2](https://docs.grails.org/6.1.2/guide/security.html#xssPrevention) of the documentation:
> By default, Grails plays it safe and escapes all content in `${}` expressions in GSPs. All the standard GSP tags are also safe by default, escaping any relevant attribute values.
### Actual Behaviour
The resulting string from `message()` is ***not*** escaped which can lead to XSS.
Additionally, using `.encodeAsHTML()` on the value passed to the code parameter causes the string to be escaped. However, using `.encodeAsHTML()` on the string returned from message does ***not*** escape the string.
### Steps To Reproduce
1. Create a new Grails app
2. Prepend the `index.gsp` page with:
```gsp
<% def bug = [[id: 1, value: "alert('This is probably a bug');"]] %>
```
3. Add a `` element to the GSP body that attempts to transform the value in a closure using `message()`
```gsp
```
4. XSS is acheived causing a browser alert to appear
### Environment Information
Operating System: Kubuntu Mantic 23.10
JDK Version: Eclipse Temurin 17.0.10
### Example Application
_No response_
### Version
Grails 6.1.2
Contributor guide
Research direction
Start with the index.gsp reproducer and the g:select optionValue closure that calls message(). Trace how the returned value is rendered, then verify that the message content is escaped and the supplied XSS example no longer executes.
Written by the indexing model from the issue text.
Assessment
- Domain
- security, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100