grails-core
grails-core copied to clipboard
optionValue in <g:select> is not escaped when message() is used in a closure
Expected Behavior
When using a closure to transform the optionValue
attribute in a <g:select>
element, the resulting string returned from message()
should be escaped as per section 16.2 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
- Create a new Grails app
- Prepend the
index.gsp
page with:
<% def bug = [[id: 1, value: "<script>alert('This is probably a bug');</script>"]] %>
- Add a
<g:select>
element to the GSP body that attempts to transform the value in a closure usingmessage()
<g:select name="bugSelect" from="${bug}" optionKey="id" optionValue="${{message(code: it.value)}}" />
- 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