Vulnerability: Cross-site scripting (XSS) vulnerability in app/assets/javascripts/host_edit_interfaces.js in Foreman before 1.12.2 allows remote authenticated users to inject arbitrary web script or HTML via the network interface device identifier in the host interface form.
Vulnerability ID: CVE-2016-6320
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/theforeman/foreman
Published: 2016-08-19
File: app/assets/javascripts/host_edit_interfaces.js
Commit message: Fixes #16022 - Prevent stored XSS in host interface form

The host interface form may contain a stored XSS in the identifier field
allowing a user allowed to edit a host's interfaces to cause code
execution by another user viewing that host's edit form.
Commit author: Tomer Brisker

Vulnerable version (before fix):
 function show_interface_modal(modal_content) {    modal_window.find('.modal-body').html('');   modal_window.find('.modal-body').append(modal_content.contents());   modal_window.find('.modal-title').html(__('Interface') + ' ' + String(identifier));   modal_window.modal({'show': true});    modal_window.find('a[rel="popover-modal"]').popover(); function update_interface_row(row, interface_form) {   type += '</div>'   row.find('.type').html(type);    row.find('.identifier').html(interface_form.find('.interface_identifier').val());   row.find('.mac').html(interface_form.find('.interface_mac').val());   row.find('.ip').html(interface_form.find('.interface_ip').val());   row.find('.ip6').html(interface_form.find('.interface_ip6').val());    var flags = '', primary_class = '', provision_class = '';   if (interface_form.find('.interface_primary').is(':checked')) function update_interface_row(row, interface_form) {    row.find('.flags').html(flags);    row.find('.fqdn').html(fqdn(     interface_form.find('.interface_name').val(),     interface_form.find('.interface_domain option:selected').text()   ));

Fixed version (after fix):
 function show_interface_modal(modal_content) {    modal_window.find('.modal-body').html('');   modal_window.find('.modal-body').append(modal_content.contents());   modal_window.find('.modal-title').text(__('Interface') + ' ' + String(identifier));   modal_window.modal({'show': true});    modal_window.find('a[rel="popover-modal"]').popover(); function update_interface_row(row, interface_form) {   type += '</div>'   row.find('.type').html(type);    row.find('.identifier').text(interface_form.find('.interface_identifier').val());   row.find('.mac').text(interface_form.find('.interface_mac').val());   row.find('.ip').text(interface_form.find('.interface_ip').val());   row.find('.ip6').text(interface_form.find('.interface_ip6').val());    var flags = '', primary_class = '', provision_class = '';   if (interface_form.find('.interface_primary').is(':checked')) function update_interface_row(row, interface_form) {    row.find('.flags').html(flags);    row.find('.fqdn').text(fqdn(     interface_form.find('.interface_name').val(),     interface_form.find('.interface_domain option:selected').text()   ));

Patch:
patch: @@ -27,7 +27,7 @@ function show_interface_modal(modal_content) {
 
   modal_window.find('.modal-body').html('');
   modal_window.find('.modal-body').append(modal_content.contents());
-  modal_window.find('.modal-title').html(__('Interface') + ' ' + String(identifier));
+  modal_window.find('.modal-title').text(__('Interface') + ' ' + String(identifier));
   modal_window.modal({'show': true});
 
   modal_window.find('a[rel="popover-modal"]').popover();
@@ -158,10 +158,10 @@ function update_interface_row(row, interface_form) {
   type += '</div>'
   row.find('.type').html(type);
 
-  row.find('.identifier').html(interface_form.find('.interface_identifier').val());
-  row.find('.mac').html(interface_form.find('.interface_mac').val());
-  row.find('.ip').html(interface_form.find('.interface_ip').val());
-  row.find('.ip6').html(interface_form.find('.interface_ip6').val());
+  row.find('.identifier').text(interface_form.find('.interface_identifier').val());
+  row.find('.mac').text(interface_form.find('.interface_mac').val());
+  row.find('.ip').text(interface_form.find('.interface_ip').val());
+  row.find('.ip6').text(interface_form.find('.interface_ip6').val());
 
   var flags = '', primary_class = '', provision_class = '';
   if (interface_form.find('.interface_primary').is(':checked'))
@@ -180,7 +180,7 @@ function update_interface_row(row, interface_form) {
 
   row.find('.flags').html(flags);
 
-  row.find('.fqdn').html(fqdn(
+  row.find('.fqdn').text(fqdn(
     interface_form.find('.interface_name').val(),
     interface_form.find('.interface_domain option:selected').text()
   ));
path: app/assets/javascripts/host_edit_interfaces.js