CVE-2019-1000010 (PHP, published 2019-02-04T21:29Z)
Description: value: phpIPAM version 1.3.2 and earlier contains a Cross Site Scripting (XSS) vulnerability in subnet-scan-telnet.php that can result in executing code in victims browser. This attack appears to be exploitable via victim visits link crafted by an attacker. This vulnerability appears to have been fixed in 1.4.
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/phpipam/phpipam
Files changed:
app/subnets/scan/subnet-scan-execute-scan-icmp.php
app/subnets/scan/subnet-scan-execute-scan-telnet.php
app/subnets/scan/subnet-scan-execute-snmp-arp.php
app/subnets/scan/subnet-scan-execute-snmp-mac.php
app/subnets/scan/subnet-scan-execute-update-icmp.php
app/subnets/scan/subnet-scan-execute-update-snmp-arp.php
app/subnets/scan/subnet-scan-execute.php
app/subnets/scan/subnet-scan-result.php
app/subnets/scan/subnet-scan.php
functions/version.php
js/magic.js
misc/CHANGELOG
Commit message: Bugfix: XSS in subnet-scan-telnet.php, CSRF in subnet-scan-execute.php. Fixes #2327


Vulnerable code:
# verify that user is logged in
$User->check_user_session();

# create csrf token
$csrf = $User->Crypto->csrf_cookie ("create", "scan");
# verify that user is logged in
$User->check_user_session();
if(strlen($_POST['port'])==0) 	  { $Result->show("danger", _('Please enter ports to scan').'!', true); }
		$Result->show("danger", _("Invalid port")." ($p)", true);
# verify that user is logged in
$User->check_user_session();

# create csrf token
$csrf = $User->Crypto->csrf_cookie ("create", "scan");
# verify that user is logged in
$User->check_user_session();

# create csrf token
$csrf = $User->Crypto->csrf_cookie ("create", "scan");
# verify that user is logged in
$User->check_user_session();
# scan
switch ($_POST['type']) {
        include("subnet-scan-execute-scan-icmp.php");
        break;
        include("subnet-scan-execute-scan-telnet.php");
        break;
        include("subnet-scan-execute-snmp-arp.php");
        break;
        include("subnet-scan-execute-snmp-mac.php");
        break;
        include("subnet-scan-execute-snmp-route-all.php");
        break;
        include("subnet-scan-execute-update-icmp.php");
        break;
        include("subnet-scan-execute-update-snmp-arp.php");
        include("subnet-scan-result-$type.php");
		<button class="btn btn-sm btn-default btn-success" id="subnetScanSubmit" data-subnetId='<?php print $_POST['subnetId']; ?>'><i class="fa fa-gears"></i> <?php print _('Scan subnet'); ?></button>
define("REVISION", "030");									//increment on static content changes (js/css) or point releases to avoid caching issues
	$.post('app/subnets/scan/subnet-scan-execute.php', {subnetId:subnetId, type:type, debug:debug, port:port}, function(data) {

Fixed code:
# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }
# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }
if(empty($_POST['port'])) 	  { $Result->show("danger", _('Please enter ports to scan').'!', true); }
		$Result->show("danger", _("Invalid port").' ('.escape_input($p).')', true);
# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }
# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }
# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }

# Check we have been included and not called directly
if (!isset($subnet_scan_execute_included)) { $Result->show("danger", _("Invalid request"), true); }
# validate csrf cookie
$User->Crypto->csrf_cookie ("validate", "scan", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : "";

$type = $_POST['type'];

switch ($type) {
#scan
        $csrf = $_POST['csrf_cookie'];
        $subnet_scan_execute_included = true;
        require("subnet-scan-execute-$type.php");
        require("subnet-scan-result-$type.php");
# create csrf token
$csrf = $User->Crypto->csrf_cookie ("create", "scan");
		<button class="btn btn-sm btn-default btn-success" id="subnetScanSubmit" data-subnetId='<?php print $_POST['subnetId']; ?>' data-csrf-cookie='<?php print $csrf; ?>'><i class="fa fa-gears"></i> <?php print _('Scan subnet'); ?></button>
define("REVISION", "031");									//increment on static content changes (js/css) or point releases to avoid caching issues
	var csrf     = $(this).attr('data-csrf-cookie');
	$.post('app/subnets/scan/subnet-scan-execute.php', {subnetId:subnetId, type:type, debug:debug, port:port, csrf_cookie:csrf}, function(data) {
    + XSS in subnet-scan-telnet.php, CSRF in subnet-scan-execute.php (#2327);