__Steps to reproduce__: 0. Open Firefox and make sure your browser is NOT logged in to https://laiva/ 1. Open the following link in the browser: https://laiva/univention/login/?location=%2Funivention%2Fmanagement%2F%3Fmodule%3Duvmm%26username%3D%253Ca%2520href%253D%2522javascript%253Aalert%2528%2527You%2520have%2520been%2520hacked%2520my%2520friend%2521%2527%2529%253B%2522%253EFree%2520beer%2520if%2520you%2520click%2520here%2521%253C%252Fa%253E%26overview%3D1%23module%3Duvmm%3A%3A0&username=%3Ca%20href%3D%22javascript%3Aalert(%27You%20have%20been%20hacked%20my%20friend!%27)%3B%22%3EFree%20beer%20if%20you%20click%20here!%3C%2Fa%3E&lang=de-DE 2. Delete the username field, and proceed with a valid login. 3. Click on the Hamburger Icon (the three stripes) which turns into an arrow after hovering. Click on the "Free beer if you click here!" link which appears in the upper right corner.
Also works in Chromium 87.0.4280.66
(In reply to Ferenc Géczi from comment #0) > __Steps to reproduce__: Great finding. Let's analyze this: > 0. Open Firefox and make sure your browser is NOT logged in to https://laiva/ We need to make sure, no Cookie UMCUsername is set. > 1. Open the following link in the browser: > > https://laiva/univention/login/ > ?location=%2Funivention%2Fmanagement%2F%3Fmodule%3Duvmm%26username%3D%253Ca%2 > 520href%253D%2522javascript%253Aalert%2528%2527You%2520have%2520been%2520hack > ed%2520my%2520friend%2521%2527%2529%253B%2522%253EFree%2520beer%2520if%2520yo > u%2520click%2520here%2521%253C%252Fa%253E%26overview%3D1%23module%3Duvmm%3A%3 > A0&username=%3Ca%20href%3D%22javascript%3Aalert(%27You%20have%20been%20hacked > %20my%20friend!%27)%3B%22%3EFree%20beer%20if%20you%20click%20here! > %3C%2Fa%3E&lang=de-DE This URI consists of the following query string parameter: {'username': ['<a href="javascript:alert(\'You have been hacked my friend!\');">Free beer if you click here!</a>'], 'lang': ['de-DE\n'], 'location': ['/univention/management/?module=uvmm&username=%3Ca%20href%3D%22javascript%3Aalert%28%27You%20have%20been%20hacked%20my%20friend%21%27%29%3B%22%3EFree%20beer%20if%20you%20click%20here%21%3C%2Fa%3E&overview=1#module=uvmm::0']} where the value of "location" is again a URI with the following query string parameter: {'username': ['<a href="javascript:alert(\'You have been hacked my friend!\');">Free beer if you click here!</a>'], 'overview': ['1'], 'module': ['uvmm']} The link sets the "UMCUsername" cookie to the value of the "username" query string argument. > 2. Delete the username field, and proceed with a valid login. After the login one is redirected back to the "location" URL, which again sets (and overwrites) the "UMCUsername" cookie to the payload. > 3. Click on the Hamburger Icon (the three stripes) which turns into an arrow > after hovering. Click on the "Free beer if you click here!" link which > appears in the upper right corner. Now we experience a simple Cross Site Scripting (XSS) issue where the username is entered into the dom node. This was introduced in git:fb7e4cb96ae42c562219f73c0a0c8332fe61c7ea (Bug #43528). A patch is: diff --git a/management/univention-web/js/menu/Menu.js b/management/univention-web/js/menu/Menu.js index f53351d8fa..52a0035b7e 100644 --- a/management/univention-web/js/menu/Menu.js +++ b/management/univention-web/js/menu/Menu.js @@ -41,13 +41,14 @@ define([ "dijit/PopupMenuItem", "dijit/MenuSeparator", "umc/tools", + "dojox/html/entities", "umc/menu/MenuItem", "umc/menu/SubMenuItem", "umc/menu/_Button", "umc/widgets/ContainerWidget", "umc/widgets/Text", "umc/i18n!" -], function(declare, lang, array, on, Deferred, topic, tap, domClass, DijitMenuItem, PopupMenuItem, MenuSeparator, tools, MenuItem, SubMenuItem, _Button, ContainerWidget, Text, _) { +], function(declare, lang, array, on, Deferred, topic, tap, domClass, DijitMenuItem, PopupMenuItem, MenuSeparator, tools, entities, MenuItem, SubMenuItem, _Button, ContainerWidget, Text, _) { // require umc/menu here in order to avoid circular dependencies var menuDeferred = new Deferred(); @@ -62,8 +63,8 @@ define([ login.onLogin(function() { // user has logged in -> set username and host in menu header mobileMenuDeferred.then(function(menu) { - menu.informationHeader.username.set('content', tools.status('username')); - menu.informationHeader.host.set('content', lang.replace('@{0}', [tools.status('hostname')])); + menu.informationHeader.username.set('content', entities.encode(tools.status('username'))); + menu.informationHeader.host.set('content', lang.replace('@{0}', [entities.encode(tools.status('hostname'))])); }); });
Let's keep it with this patch. The other problem is only a race condition with rendering the menu. After the rendering is done umc.tool.status('username') contains the correct username. Changing the rendering process might cause other side effects. univention-web (3.0.6-2) 5f3c24a4253d | Bug #52665: fix XSS vulnerability in Menu univention-management-console.yaml c73dc9e3d7b7 | YAML Bug #52665
FAIL - yaml, should be univention-web.yaml i guess (not univention-management-console.yaml( OK - reproducible OK - merged to 5.0-0
Oh right, fixed in: b58e50b8fc11 | move YAML Bug #52665
I found two other occurrences of unescaped HTML insertions. Fixed them in: univention-management-console.yaml 7ae84026862c | YAML Bug #52665 univention-management-console-module-passwordchange.yaml 7ae84026862c | YAML Bug #52665 univention-management-console-module-passwordchange (4.0.0-5) afa4c125a00d | Bug #52665: fix XSS vulnerability univention-management-console (11.0.6-5) 175da87e67fd | Bug #52665: fix XSS vulnerability
OK - univention-web.yaml * fixed * merged OK - univention-management-console.yaml * fixed * merged OK - univention-management-console-module-passwordchange.yaml * fixed * merged
<https://errata.software-univention.de/#/?erratum=4.4x881> <https://errata.software-univention.de/#/?erratum=4.4x882> <https://errata.software-univention.de/#/?erratum=4.4x883>