From c5d19aae55be158676eb0914bd5d0701f7d3fd3a Mon Sep 17 00:00:00 2001 From: Alexandru DAMIAN Date: Tue, 11 Nov 2014 17:01:09 +0000 Subject: bitbake: toastergui: fix XSS injection points in projects page We close XSS injection points in Projects page. * modify the json filter to properly escape HTML tags in strings * enable $sanitize to automatically sanitize dangerous HTML in user-supplied input * clean dangerous characters in targets field, as that field contents will be directly passed to a shell command Based on the vulnerability discovered and the patch provided by Michael Wood. (Bitbake rev: 23c440db9c076ca37e651bdbbdbefee54998e1dc) Signed-off-by: Alexandru DAMIAN Signed-off-by: Richard Purdie --- .../lib/toaster/toastergui/static/js/projectapp.js | 7 ++-- .../lib/toaster/toastergui/templates/project.html | 16 ++++---- .../toaster/toastergui/templatetags/projecttags.py | 6 ++- bitbake/lib/toaster/toastergui/views.py | 48 +++++++++++----------- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js index f0569de04d..9f9a06476a 100644 --- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js +++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js @@ -101,7 +101,7 @@ function _diffArrays(existingArray, newArray, compareElements, onAdded, onDelete } -var projectApp = angular.module('project', ['ngCookies', 'ngAnimate', 'ui.bootstrap' ], angular_formpost); +var projectApp = angular.module('project', ['ngCookies', 'ngAnimate', 'ui.bootstrap', 'ngRoute', 'ngSanitize'], angular_formpost); // modify the template tag markers to prevent conflicts with Django projectApp.config(function($interpolateProvider) { @@ -128,7 +128,7 @@ projectApp.filter('timediff', function() { // main controller for the project page -projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce, $anchorScroll, $animate) { +projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce, $anchorScroll, $animate, $sanitize) { $scope.getSuggestions = function(type, currentValue) { var deffered = $q.defer(); @@ -475,6 +475,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc var alertText = undefined; var alertZone = undefined; var oldLayers = []; + switch(elementid) { case '#select-machine': alertText = "You have changed the machine to: " + $scope.machineName + ""; @@ -594,7 +595,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc var crtid = zone.maxid ++; angular.forEach(zone, function (o) { o.close() }); o = { - id: crtid, text: $sce.trustAsHtml(text), type: type, + id: crtid, text: text, type: type, close: function() { zone.splice((function(id){ for (var i = 0; i < zone.length; i++) if (id == zone[i].id) { return i}; return undefined;})(crtid), 1); }, diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html index 38863a3ac6..4e8a7e29aa 100644 --- a/bitbake/lib/toaster/toastergui/templates/project.html +++ b/bitbake/lib/toaster/toastergui/templates/project.html @@ -11,6 +11,8 @@ vim: expandtab tabstop=2 + + @@ -365,13 +367,13 @@ angular.element(document).ready(function() { scope.urls.layers = "{% url 'layers' %}"; scope.urls.targets = "{% url 'targets' %}"; scope.urls.importlayer = "{% url 'importlayer'%}" - scope.project = {{prj|safe}}; - scope.builds = {{builds|safe}}; - scope.layers = {{layers|safe}}; - scope.targets = {{targets|safe}}; - scope.frequenttargets = {{freqtargets|safe}}; - scope.machine = {{machine|safe}}; - scope.releases = {{releases|safe}}; + scope.project = {{prj|json}}; + scope.builds = {{builds|json}}; + scope.layers = {{layers|json}}; + scope.targets = {{targets|json}}; + scope.frequenttargets = {{freqtargets|json}}; + scope.machine = {{machine|json}}; + scope.releases = {{releases|json}}; var now = (new Date()).getTime(); scope.todaydate = now - (now % 86400000); diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py index 4a97eb7ac4..99fd4cf287 100644 --- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py +++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py @@ -25,6 +25,7 @@ from django import template from django.utils import timezone from django.template.defaultfilters import filesizeformat import json as JsonLib +from django.utils.safestring import mark_safe register = template.Library() @@ -49,7 +50,10 @@ def mapselect(value, argument): @register.filter(name = "json") def json(value): - return JsonLib.dumps(value) + # JSON spec says that "\/" is functionally identical to "/" to allow for HTML-tag embedding in JSON strings + # unfortunately, I can't find any option in the json module to turn on forward-slash escaping, so we do + # it manually here + return mark_safe(JsonLib.dumps(value, ensure_ascii=False).replace('