CVE-2019-6777: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: An issue was discovered in ZoneMinder v1.32.3. Reflected XSS exists in web/skins/classic/views/plugin.php via the zm/index.php?view=plugin pl parameter.
CWE description: 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.
CVSS v3 base score: 6.1
Published: 2019-01-24T15:29Z
Repository: https://github.com/mnoorenberghe/ZoneMinder
Language: PHP
Files changed: web/skins/classic/views/plugin.php
Commit date: 2019-01-23 19:41:38 -0800
Commit message: plugin.php: Fix XSS and directory traversal bugs. Fixes #2436

This view seems like dead code so maybe it should be removed instead.

Diff: diff --git a/web/skins/classic/views/plugin.php b/web/skins/classic/views/plugin.php
index 7b4cf85ca..814416058 100644
--- a/web/skins/classic/views/plugin.php
+++ b/web/skins/classic/views/plugin.php
@@ -34,11 +34,12 @@ if ( $zid > 0 ) {
 } else {
    $view = "error";
    return;
 }
 $monitor = dbFetchMonitor ( $mid );
-$plugin = $_REQUEST['pl'];
+// Only allow certain filename characters (not including a period) to prevent directory traversal.
+$plugin = preg_replace('/[^-a-zA-Z0-9]/', '', $_REQUEST['pl']);
 
 $plugin_path = dirname(ZM_PLUGINS_CONFIG_PATH)."/".$plugin;
 
 $focusWindow = true;
 
@@ -101,19 +102,19 @@ function pLang($name)
 
 ?>
 <body>
   <div id="page">
     <div id="header">
-      <h2><?php echo translate('Monitor') ?> <?php echo $monitor['Name'] ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo $plugin ?></h2>
+      <h2><?php echo translate('Monitor') ?> <?php echo $monitor['Name'] ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo validHtmlStr($plugin) ?></h2>
     </div>
     <div id="content">
       <form name="pluginForm" id="pluginForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
         <input type="hidden" name="view" value="<?php echo $view ?>"/>
         <input type="hidden" name="action" value="plugin"/>
         <input type="hidden" name="mid" value="<?php echo $mid ?>"/>
         <input type="hidden" name="zid" value="<?php echo $zid ?>"/>
-        <input type="hidden" name="pl" value="<?php echo $plugin ?>"/>
+        <input type="hidden" name="pl" value="<?php echo validHtmlStr($plugin) ?>"/>
 
         <div id="settingsPanel">
           <table id="pluginSettings" cellspacing="0">
             <tbody>
 <?php

Vulnerable code: $plugin = $_REQUEST['pl'];
      <h2><?php echo translate('Monitor') ?> <?php echo $monitor['Name'] ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo $plugin ?></h2>
        <input type="hidden" name="pl" value="<?php echo $plugin ?>"/>
Fixed code: // Only allow certain filename characters (not including a period) to prevent directory traversal.
$plugin = preg_replace('/[^-a-zA-Z0-9]/', '', $_REQUEST['pl']);
      <h2><?php echo translate('Monitor') ?> <?php echo $monitor['Name'] ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo validHtmlStr($plugin) ?></h2>
        <input type="hidden" name="pl" value="<?php echo validHtmlStr($plugin) ?>"/>