else
@alerts = @profile.alerts.reload
errors = []
- @alert.errors.full_messages.each{|msg| errors<<msg + '<br/>'}
+ @alert.errors.full_messages.each{|msg| errors<<CGI.escapeHTML(msg) + '<br/>'}
render :text => errors, :status => 404
end
end
render :text => 'ok', :status => 200
else
errors = []
- alert.errors.full_messages.each{|msg| errors<<msg + '<br/>'}
+ alert.errors.full_messages.each{|msg| errors<<CGI.escapeHTML(msg) + '<br/>'}
render :text => errors, :status => 404
end
end
def render_bad_request(error)
message = error.respond_to?('message') ? error.message : error.to_s
- render :text => message, :status => 400
+ render :text => CGI.escapeHTML(message), :status => 400
end
def render_server_exception(exception)
message = (exception.getMessage ? exception.getMessage : Api::Utils.message(exception.l10nKey, :params => exception.l10nParams.to_a))
- render :text => message, :status => exception.httpCode
+ render :text => CGI.escapeHTML(message), :status => exception.httpCode
end
def render_native_access_denied(exception)
if request.xhr?
message = error.respond_to?('message') ? error.message : error.to_s
- render :text => message, :status => 500
+ render :text => CGI.escapeHTML(message), :status => 500
else
render :file => "#{Rails.public_path}/500.html", :status => 500
end
if resource_key && !resource_key.blank?
# the request comes from a project: let's select its 5 latest versions
project = Project.by_key(resource_key)
+ return render_not_found('Project not found') unless project
+
snapshots = project.events.select { |event| !event.snapshot_id.nil? && event.category==EventCategory::KEY_VERSION }[0..5].reverse.map {|e| e.snapshot}
# if last snapshot is not in the list, add it at the end (=> might be the case for views or developers which do not have events)
last_snapshot = project.last_snapshot
add_default_dashboards_if_first_user_dashboard(@dashboard.global?)
last_index=current_user.active_dashboards.max_by(&:order_index).order_index
current_user.active_dashboards.create(:dashboard => @dashboard, :user => current_user, :order_index => (last_index+1))
- render :text => params[:resource], :highlight => @dashboard.id, :status => 200
+ render :text => CGI.escapeHTML(params[:resource]), :highlight => @dashboard.id, :status => 200
else
render :partial => 'dashboards/create_form', :status => 400, :resource => params[:resource]
end
if @dashboard.editable_by?(current_user)
load_dashboard_from_params(@dashboard)
if @dashboard.save
- render :text => params[:resource], :status => 200
+ render :text => CGI.escapeHTML(params[:resource]), :status => 200
else
@dashboard.user = dashboard_owner
render :partial => 'dashboards/edit_form', :status => 400, :resource => params[:resource]
if @dashboard.destroy
flash[:warning]=Api::Utils.message('dashboard.default_restored') if ActiveDashboard.count(:conditions => {:user_id => current_user.id})==0
- render :text => params[:resource], :status => 200
+ render :text => CGI.escapeHTML(params[:resource]), :status => 200
else
@dashboard.errors.add(message('dashboard.error_delete_default'), ' ')
render :partial => 'dashboards/delete_form', :status => 400, :resource => params[:resource]
def render_measures_error(filter)
errors = []
- filter.errors.full_messages.each{|msg| errors<<msg + '<br/>'}
+ filter.errors.full_messages.each{|msg| errors<<CGI.escapeHTML(msg) + '<br/>'}
render :text => errors, :status => 400
end
end
<script>
$j("#bulk-change-form").modalForm({
success: function () {
- onBulkIssues(<%= params.to_json -%>);
+ onBulkIssues(<%= json_escape(params.to_json) -%>);
}
});
%>
<script type="text/javascript">
- var filterCriteria = <%= @issues_query_params.to_json -%>;
+ var filterCriteria = <%= json_escape(@issues_query_params.to_json) -%>;
function refreshList(sort, asc, page) {
$j('#issue-filter-foot_pages').hide();
<div id="measure_filter_list<%= widget_id -%>">
<% content_for :script do %>
<script>
- var filterCriteria<%= widget_id -%> = <%= filter.criteria.to_json -%>;
+ var filterCriteria<%= widget_id -%> = <%= json_escape(filter.criteria.to_json) -%>;
function refreshList<%= widget_id -%>(sort, asc, page) {
$j('#measure_filter_foot<%= widget_id -%>_pages').hide();
} -%>
<% end %>
</table>
-</div>
\ No newline at end of file
+</div>
<script>
- var filterCriteria<%= widget_id -%> = <%= filter.criteria.to_json -%>;
+ var filterCriteria<%= widget_id -%> = <%= json_escape(filter.criteria.to_json) -%>;
</script>
<%
treemap_id = widget_id.nil? ? 1 : widget_id
end
end
+class ActionView::Base
+
+ # Fix XSS - embed secure JSON in HTML
+ # http://jfire.io/blog/2012/04/30/how-to-securely-bootstrap-json-in-a-rails-view/
+ # Default implmentation of json_escape also removes double quote (") characters. It is documented to return invalid JSON !
+ def json_escape(s)
+ result = s.to_s.gsub('/', '\/')
+ s.html_safe? ? result.html_safe : result
+ end
+
+ alias j json_escape
+end
+
+
#
# other patches :
# - activerecord : fix Oracle bug when more than 1000 elements in IN clause. See lib/active_record/association_preload.rb