CVE-2019-25105: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability, which was classified as problematic, was found in dro.pm. This affects an unknown part of the file web/fileman.php. The manipulation of the argument secret/key leads to cross site scripting. It is possible to initiate the attack remotely. This product does not use versioning. This is why information about affected and unaffected releases are unavailable. The patch is named fa73c3a42bc5c246a1b8f815699ea241aef154bb. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-221763.
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: 2023-02-26T08:15Z
Repository: https://github.com/lgommans/dro.pm
Language: PHP
Files changed: web/fileman.php
Commit date: 2019-05-10 21:04:15 +0200
Commit message: Fix reflected XSS in fileman.php (self discovered, no signs of exploitation... not that there would be much to exploit, given that there are no cookies or localstorage (i.e. there is no state you could get at))

Diff: diff --git a/web/fileman.php b/web/fileman.php
index 27bdc0c..ead1ae8 100644
--- a/web/fileman.php
+++ b/web/fileman.php
@@ -15,32 +15,33 @@
 	}
 
 	if (empty($_GET['secret'])) {
 		if ($_SERVER['HTTP_USER_AGENT'] == 'cli' || $_SERVER['HTTP_USER_AGENT'] == 'dro.pm-androidapp') {
 			list($secret, $key) = allocate();
-			$retval = "$secret dro.pm/$key";
+			$retval = htmlspecialchars($secret) . ' dro.pm/' . htmlspecialchars($key);
 		}
 		else {
 			die('Missing required parameter.');
 		}
 	}
 	else {
-		$secret = $db->escape_string($_GET['secret']);
-		
-		$key = $db->query('SELECT `key` FROM `shorts` WHERE `secret` = "' . $secret . '"') or die('Database error 3984');
+		$secret = $_GET['secret'];
+
+		$key = $db->query('SELECT `key` FROM `shorts` WHERE `secret` = "' . $db->escape_string($secret) . '"') or die('Database error 3984');
 		if ($key->num_rows != 1) {
-			die("?secret=$secret not found");
+			die('?secret=' . htmlspecialchars($secret) . ' not found');
 		}
 		$key = $key->fetch_row()[0];
 	}
 
 	$success = move_uploaded_file($_FILES['f']['tmp_name'], 'uploads/' . $key);
 	if (!$success) {
 		die('Error moving file.<script>alert("Error 500 uploading file.");</script>');
 	}
 
-	$data = array('original_filename' => $_FILES['f']['name'], 'filename' => $key);
+	$data = ['original_filename' => $_FILES['f']['name'], 'filename' => $key];
 	$data = $db->escape_string(serialize($data));
-	$db->query('UPDATE `shorts` SET `expires` = ' . (time() + (12*3600)) . ', `type` = 2, `value` = "' . $data . '", expireAfterDownload = ' . $expireAfterDownload . ' WHERE `secret` = "' . $secret . '"') or die('Database error 29348');
+	$db->query('UPDATE `shorts` SET `expires` = ' . (time() + (12*3600)) . ', `type` = 2, `value` = "' . $data . '", expireAfterDownload = ' . $expireAfterDownload
+		. ' WHERE `secret` = "' . $db->escape_string($secret) . '"') or die('Database error 29348');
 
 	die($retval);
 

Vulnerable code: 			$retval = "$secret dro.pm/$key";
		$secret = $db->escape_string($_GET['secret']);
		
		$key = $db->query('SELECT `key` FROM `shorts` WHERE `secret` = "' . $secret . '"') or die('Database error 3984');
			die("?secret=$secret not found");
	$data = array('original_filename' => $_FILES['f']['name'], 'filename' => $key);
	$db->query('UPDATE `shorts` SET `expires` = ' . (time() + (12*3600)) . ', `type` = 2, `value` = "' . $data . '", expireAfterDownload = ' . $expireAfterDownload . ' WHERE `secret` = "' . $secret . '"') or die('Database error 29348');
Fixed code: 			$retval = htmlspecialchars($secret) . ' dro.pm/' . htmlspecialchars($key);
		$secret = $_GET['secret'];

		$key = $db->query('SELECT `key` FROM `shorts` WHERE `secret` = "' . $db->escape_string($secret) . '"') or die('Database error 3984');
			die('?secret=' . htmlspecialchars($secret) . ' not found');
	$data = ['original_filename' => $_FILES['f']['name'], 'filename' => $key];
	$db->query('UPDATE `shorts` SET `expires` = ' . (time() + (12*3600)) . ', `type` = 2, `value` = "' . $data . '", expireAfterDownload = ' . $expireAfterDownload
		. ' WHERE `secret` = "' . $db->escape_string($secret) . '"') or die('Database error 29348');