In Grails (<2.3), if I leave grails.views.default.code='none' in the grails Config.groovy, it's up to me to HTML encode my expressions explicitly in the GSP files: ${myValue?.encodeAsHTML()}.
If I set grails.views.default.codec='html" in the Config.groovy, then the HTML encoding happens automatically for every expression: ${myValue}.
My question: If I set the default to 'html', how do I get back to 'none' for one expression when I don't want the HTML encoding behavior?
To summarize the various levels at which the codec can be applied:
Set Config.groovy's grails.views.default.codec='html' to get HTML escaping by default on all ${expressions} in the application.
Then when you want to default a whole page back to none, use the directive:
<%#page defaultCodec="none" %>
or
<%# defaultCodec="none" %>
To disable HTML encoding for one expression in a page that is otherwise defaulting to HTML, use <%=expression%> notation instead of ${...}.
If default encoding level is set to html using
grails.views.default.codec = "html"
then for removing the html encoding for one expression in a page you can use
${raw(expression)}
Try using ${raw(myValue)} , you do not need to declare page codecs etc
From GRAILS-1827, it looks like you can override the default codec for a specific page with
<%# defaultCodec="HTML" %>
or
<%#page defaultCodec="HTML" %>
in some versions (see the referenced issue).
I may have a solution. I'm not sure how accepted it is, though.
I can set the default codec for expressions to HTML, but then use <%=myValue%> notation in GSP instead of ${} expressions to get the unescaped values onto the page.
Write your own tag and write the expression direct to the output stream:
class YourTagLib {
static namespace = "x"
def unescaped = { attrs, body ->
out << attrs.value
}
}
Use it in your GSP:
<x:unescaped value="${yourexpression}"/>
Related
I am trying to use Yeoman to create a generator for a web app and I have *.jsp and *.gradle files which I want to be generated (sometimes just copied) during bootstrapping. Unfortunately Yeoman throws an error when there are JSP comments in *.jsp files like <%# ... %> or when there are placeholders like ${ .. } in *.gradle files.
I guess the reason of the error is that Yeoman treats this entries like placeholders to be processed but it cannot find appropriate values so it throws.
How can I overcome this? How can I escape or disable processing of some kind of placeholders?
I still want to use EJS-styled placeholder <%= .. %> in the same files though.
I had the same problem on maven properties where I have to use ${propertyname}.
I solved it by using the following for templates.
this.template('_pom.xml', 'pom.xml', null, { 'interpolate': /<%=([\s\S]+?)%>/g });
I'm new to yeoman so I don't know what { 'interpolate': /<%=([\s\S]+?)%>/g } does but it worked.
If you want to render jsp tags like:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
you could use <%% which prints a literal <%
So change the previous line for:
<%%#page contentType="text/html" pageEncoding="UTF-8"%>
That solved my code without making adhocs. The same solution can be applied to other scenarios.
When I use url helper to generate url for route with query params and then add that url to link href, validator warns me, that there is unescaped & in attribute:
▲
I tried to search but still I'm not sure who is responsible for escaping that.
Router generates url but that might be used anywhere, not only in html attribute, so it correctly does no escaping in his case.
Url helper does not change anything in that url but it is meand for use in html so it might done here
View template - there url is put inside href attribute, so it might be here too
I couldn't find any clue how to decide this and if fill an issue with zf2 about this.
EDIT: html/php code from paginator
<<
generates html
<<
and from what I found it should be
<<
I would argue that the current behavior (not HTML entity encoding) is correct and it is up to the developer to encode HTML entities, when appropriate.
For instance you may want to use the view helper inside a <script> tag, where the HTML entities would be uncalled for.
According to Marc Palmer
Preventing XSS attacks
In a nutshell, to protect your app from code injection XSS exploits
you must:
Set the default grails.views.default.codec in config to "HTML"
OK.
So if I have this below in my Config.groovy
grails.views.default.codec = "none"
And in my Controller, I add:
def afterInterceptor = { model ->
model.headerJs = "alert('bingo for '+[$params.unitId]);"
}
And in my GSP:
<r:script disposition="head">${headerJs}</r:script>
It works. I see the expected javascript alert when I do View Source and I get my alert when the page serves.
But, if in Config.groovy I apply the recommended change:
grails.views.default.codec = "html"
My GSP renders
<script type="text/javascript">alert('halooba for '+[1]);</script>
which I can see is very secure.
My goal with this app is to have custom JS snippets, various properties and other values stored for the customer in the Domain. These values would be entered by our Admins (not the customer). Based on who invokes the page with an HTTP request, such as www.mydomain.com/ThisApp/?customerId=13423 (but an encoded customerId) I'd make calls to Services from my Controller to fetch the associated settings for the customer from the Domain and inject them into the GSP.
I know that I can put JS and CSS into files and then use the Resources Plugin to bring them in properly, but I'm also looking at this method for specific customizations.
So, to follow this security method, I either need to be able to unencode this, or I need to determine another method for including javascript into the GSP that does not encode it.
Any suggestions?
THANKS!
You can suggest Grails not to escape by using raw() available in GSP as:
<r:script disposition="head">${raw(headerJs)}</r:script>
For Grails 2.2.x and below, you can put the recommended encoding in your Config.groovy:
grails.views.default.codec = "html"
and use a Taglib to bring in values that are SAFE and should not be HTML encoded:
<r:script><com_myapp:getJSDeferred unitId="${params.unitId}" /></r:script>
and it will be rendered raw.
FYI: Above solution will not allow for JSON output to assign to javascript variable.
My workaround, say you have model.data defined as hashmap:
var someVar= ${raw(data as JSON).toString())};
I was just wondering how you use the underscore templates in a .aspx view since the <%= %> tags that underscore uses get picked up by the .aspx rendering engine and give me errors.
For instance:
<script type="text/template" id="my-template">
<span class="event" title="<%= description %>">
<%= title %>
</span>
</script>
This template gives me an error since the .aspx rendering engine thinks I'm trying to bind this stuff to the Model.
Thanks.
From the fine manual:
template _.template(templateString, [data], [settings])
[...]
If ERB-style delimiters aren't your cup of tea, you can change Underscore's template settings to use different symbols to set off interpolated code. Define an interpolate regex to match expressions that should be interpolated verbatim, an escape regex to match expressions that should be inserted after being HTML escaped, and an evaluate regex to match expressions that should be evaluated without insertion into the resulting string.
So if the default <%=...%>, <%-...%>, and <%...%> delimiters aren't working for you then you can use different ones with a simple configuration change. For example, if you wanted to use {%...%} instead of <%...%>, then do this after underscore.js is loaded and before you use _.template:
_.templateSettings = {
interpolate: /\{%=(.+?)%\}/g,
escape: /\{%-(.+?)%\}/g,
evaluate: /\{%(.+?)%\}/g
};
Demo: http://jsfiddle.net/ambiguous/TfB5M/
I'm using the Gravatar helper class from Microsoft.Web.Helpers like so
<%: Gravatar.GetHtml("me#domain.com", 80, "identicon") %>
which produces in the source
<img src="http://www.gravatar.com/avatar/0ff2e377be7d73b15f0b48022a755717?s=80&d=identicon" alt="gravatar" />
The image URL does work but shouldn't it be &d=identicon and not &d=identicon? It appears to have encoded the ampersand. This is also the same when using Gravatar.GetUrl()
How can I stop it encoding the ampersand without rewriting my own version?
<%:Gravatar.GetHtml("me#domain.com", 80, "identicon") %>
Your telling it to encode the output, ":" is short hand for this. If you do not want to encode the output, do this
<%=Gravatar.GetHtml("me#domain.com", 80, "identicon") %>
As far as I am aware ":" is shorthand for outputting via Html.Encode()
=========Edit
What the Helper is doing is correct, it should be encoding the ampersand, more info at the link below
XHTML and & (Ampersand) encoding
In code (say in the controller action... and not in the *.aspx or *.cshtml markup), when I do this:
var avatarUrl = Gravatar.GetUrl("someone#somewhere.com", defaultImage: "identicon");
This will return the following string:
http://www.gravatar.com/avatar/923d10bc97028030e8e67e7db62658d1?s=80&d=identicon
Note the encoded ampersand (&) where there shouldn't be any encoding. I think this is not working as intended. The reason it matters, is because instead of getting the identicon (or gravatar) that we want, we get the default gravatar logo, which we dont want (the whole point of the identicon fallback). Remember, this was done from the controller, vice the view markup.