-
-
Notifications
You must be signed in to change notification settings - Fork 953
Default Codecs
lhotari edited this page Mar 7, 2013
·
27 revisions
A default codec of HTML for GSPs is useful to protect applications from Cross Site Scripting (XSS) attacks. The trouble is, the default codec applies to all GSPs, including those provided by plugins. Since it's the application developer that controls the settings, how does a plugin know whether to encode a value as HTML or not? What if a value should be encoded as Javascript rather than HTML?
You can currently override the default codec for a GSP through a defaultCodec
page directive, but finer-grained control would be nice.
The problems can be expressed as the following:
- Out of the box, apps and plugins should be immune to such XSS attacks, unless the developers explicitly take action to change the default behaviour.
- There is a risk of double-encoding of data when the developer is not aware of encodings already applied.
- Plugins cannot have their pages break because the app developer changes default codec setting. Currently they do.
- Ideally the user should never need to explicitly think about codecs or calling them except in rare situations. Normally we have all the contextual information we need (i.e. inside g:javascript defaulting to HTML codec is pretty stupid)
- Behaviour is inconsistent.
<% ... %>
and<%= ... %>
do not apply default codec.${g.xxx([:])}
does apply codec.<g:xxx/>
does not apply codec.
These items work together to create a coherent environment:
- Deprecate the existing global default codec in favour of smart context-sensitive default codecs and explicit page directive
- GSPs always default to HTML codec. The page defaultCodec directive can be used to alter this.
- Add a function/tag to switch the current default codec - effectively pushing and popping a default codec stack. This could take the form of a withCodec(name, Closure) method in tags.
- Use this function/tag in core tags like
<g:javascript>
and<r:script>
to automatically set an appropriate codec - Add some smarts to throw exception if same codec is applied multiple times (without specifying an override for this behaviour). i.e. attach applied codec names as a Set to the stream char buffers or similar
-
<g:render>
and similar tags would need to set default codec to HTML again when including another GSP, pushing whatever was default onto a stack - Change
<% ... %>
and<%= ... %>
to apply current default codec, as currently this is a little known security hole. Possible breaking change, but are people really using these with pre-escaped HTML right now? - Add support for an optional
encodeAs
attribute to all tags automatically, such that the result will be encoded with that codec if specified i.e.var s = ${g.createLink(...., encodeAs:'JavaScript')}
The rationale for the above is the simplicity and removal of confusion:
- All GSPs in app or plugins default to HTML codec unless developer does something to change that using directive/tag
- All outputs of expressions/inline code apply the current default codec
- Tags are responsible for the correct encoding of their output, unless specified in
encodeAs=
attribute