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())};
Related
I'm a web app developer with ASP.NET MVC 5 in server-side and AngularJS in client-side. The navigation, in client-side, is managed with module UI-Router. In server-side I've configured my custom authentication and authorization. When I excecute the app can see a navigation bar with many links. In particular, I have a link named "Overview" that redirects to controller Overview.
Code client (html):
<a ui-sref="Overview">Overview</a>
Code client to redirect (angular):
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("Home/Index");
$stateProvider
.state("Overview", {
templateUrl: "Home/Overview",
url: "/overview"
})
Controller code:
[OutputCache(Duration=0, NoStore=true)]
[AllowAnonymous]
public ActionResult Overview()
{
return PartialView();
}
With a breakpoint in line "return PartialView()" to controller code, I can see that controller returns partial view when I click over "overview" in menu app. But when I click second time, the breakpoint does not trigger. I think it's a caching issue.
I have read that caching issue can be generated:
* In server-side.
* In client-side.
* Even IIS.
I have tried many solutions: In server side I use attribute [OutputCache].
When i read in my browser the http headers i can see
In client side i could not find a solution to avoid caching, but i think that UI-Router shouldn't cache anything.
As additional measures I put in my web.config:
<system.webServer>
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
even, I created my own custom ActionFilterAttribute but did not work.
i don't know what else to do.
PS: sorry for my english
If there is any other plugin which does caches its templates, then your solution will clean those templates and make those plugins unusable.. hence your solution is not good.
To solve problem of html caching you should add random query string at the end of html filename... the other solutions you mentioned are for non-caching of api responses and not for static content (html/js/css files)
To add random query string to ur html. either you can use modules like grunt-cache-busting or gulp-rev or use query string as param query-string-cache-busting.
Please note that datetime/file-hash are best cache-busting param
Ok, I've found the solution.
Despite avoid caching from server side with attributes like OutputCache, or avoid caching from IIS setting my web.config, the issue persisted.
AngularJS was the guilty. In other post I found the solution.
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
This solution is provided by Mark Rajcok and Valentyn Shybanov. So thanks to both.
any idea for this
var elemVal = $("#element").val();
var finalVal = "${someTagLib(attr: elemVal)}";
The element is a select option, so I am getting the value that the user selected to pass into a taglib function. It seems that search isn't being passed into the taglib. Anyone have a suggestion?
This is not possible at all. You are trying to mix server side code with client side code which is a common mistake.
When you use gsp's they first compiled on server i.e. in JVM, but there javascript can not be executed. Similarly when compiled gsp content is rendered as html in the browser, there will be no ${} since that is an groovy expression.
So the thing you are trying to achieve is not possible.
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.
I have an app that uses Backbone on the client side and Rails on the back end.
My Backbone code calls an underscore template in this manner:
var todo = Backbone.View.extend({
.
template : _.template( $('#todo_rows').html() ),
.
}
However, there's only one page on the site which would need to call this template, and the Backbone js loads on every page. That means that there will be a JS error on the other pages which don't have the "#todo_rows" underscore template defined.
One solution would be to create a blank "#todo_rows" template section for all the other pages, but this strikes me as a major hack and not the best way to deal with this problem.
What is the best way to disable the code to call a template in Backbone? It needs to be disabled if you are not on the home page OR if you are not logged in.
Underscore's template is happy with receiving an empty string as argument. As $('#todo_rows').html() returns null if the #todo_rows element does not exist, you can easily avoid the JS error by using the or-operator idiom:
template : _.template( $('#todo_rows').html() || '' ),
which means "use an empty string as dummy template if the real one is not available".
Another, Rails-specific workaround for this problem (and a neat approach in general) is to add the ejs gem to your project's Gemfile, which allows you to put each template in a separate .jst.ejs file in app/assets and have the Asset Pipleline compile it to a JST object that can be accessed by your view to get the template content:
templates/todo_rows.jst.ejs
<% // Your template (content of former "#todo_rows") here %>
todo_rows_view.js
//= require templates/todo_rows
var todo = Backbone.View.extend({
template : _.template(JST['templates/todo_rows']),
// ...
}
This avoids the roundtrip to the DOM and makes it possible to nicely organize the templates into multiple files, but has the drawback that the template string will be sent as part of the JavaScript code for every page including it.
I need to implement an application with multi-language support using an AngularJS front-end and a Ruby on Rails server.
I am looking for a reasonable approach to render translated templates in multiple languages. I have come up with an approach I would like feedback on.
In the Angular routes definitions, set the template property to an html partial that just has an ng-include with the src attribute value set by the controller. This approach is needed to dynamically modify the path to the template to be fetched from the server; it is described here:
AngularJS - How to use $routeParams in generating the templateUrl?
So the Angular route config would look like:
angular.module('myApp', []).
config(function ($routeProvider) {
$routeProvider.when('/sites/new', {
template: '<div ng-include src="templateUrl"></div>',
controller: 'RouteController'
});
});
And the controller would look like:
// Set a prefix on the URL path, something like “es”
function RouteController($scope, $routeParams) {
$scope.templateUrl = $routeParams.locale + "/template/sites/site";
}
Here $routeParams.locale is used to set the locale, but could be a variable set by user action. The approach for dynamically modifying the template URL path to add a locale prefix seems a bit convoluted, but I know of no other way.
On the Rails side, in routes.rb, add a route:
match '/:locale/template/*template' => 'template#get'
The route uses route globbing so the params[:template] value can be a multi-level path.
The TemplateController#get action just renders the partial determined by params[:template]
The Template controller code is something like:
class TemplateController < ApplicationController
layout false
caches_page :get
def get
render(template: "template/#{params[:template]}")
end
end
The Rails I18n support for translations is used in the erb templates, translating according to the locale parameter.
In production, caching would be turned on. This would avoid incurring translation overhead. The locale prefix of the URL path would result in a per language set of translated templates to be cached.
This approach pushes translations processing to the server side as much as possible.
Is there any fundamental problems with this approach?
Could it be done better?
You may be interested in the angular-translate module.
We achieved client side internationalization in AngularJS with the i18next JQuery plugin http://i18next.com/ and created a filter called i18n.
When you initialize the Angular Application, you initialize the i18n plugin where you can provide a pattern to locate the file containing labels, and in the template use this as an example for binding labels and values.
{{'mynamespace:labels.firstname' | i18n}}
where "mynamespace" is used to separate your labels logically and used to locate JSON files with the labels. Within json files you can have one or more JSON objects with labels as properties. In the above example, the file called mynamespace-i18n-en-US.js if you provided a pattern __ns-i18n-__lng__.js
Is there a reason why the translation has to happen on the server?
Do you really need to translate the entire template?