Skip to content

Commit fb3c14d

Browse files
committed
Security patch.
Changelog excerpt: - Added a method to check whether a name is reserved, and applied it as a guard at the point where signature files are read in. Attempting to perform file operations on reserved names under Windows and some other operating systems could cause the underlying file system to attempt to communicate with a serial port instead of the intended file. PHP is likely to then wait indefinitely for a response it's unlikely to ever receive, thus locking up the process and preventing further requests unless the process is restarted. Although it's infinitesimally unlikely that a user would actually want to use a reserved name for one of their signature files, as the solution is exceedingly simple, with no particular performance impact, I've implemented it accordingly.
1 parent 61597b4 commit fb3c14d

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,5 @@ __*Why "v3.0.0" instead of "v1.0.0?"*__ Prior to phpMussel v3, the "phpMussel Co
143143
### v3.5.0
144144

145145
[2023.12.01; Maikuolan]: Improved escaping. Added support for specifying a Redis database number to the supplementary cache options.
146+
147+
[2023.12.12; Security; Maikuolan]: Added a method to check whether a name is reserved, and applied it as a guard at the point where signature files are read in. Attempting to perform file operations on reserved names under Windows and some other operating systems could cause the underlying file system to attempt to communicate with a serial port instead of the intended file. PHP is likely to then wait indefinitely for a response it's unlikely to ever receive, thus locking up the process and preventing further requests unless the process is restarted. Although it's infinitesimally unlikely that a user would actually want to use a reserved name for one of their signature files, as the solution is exceedingly simple, with no particular performance impact, I've implemented it accordingly.

src/Loader.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* License: GNU/GPLv2
99
* @see LICENSE.txt
1010
*
11-
* This file: The loader (last modified: 2023.12.01).
11+
* This file: The loader (last modified: 2023.12.12).
1212
*/
1313

1414
namespace phpMussel\Core;
@@ -1180,7 +1180,7 @@ public function updateConfiguration(): bool
11801180
/** Multiline support. */
11811181
$DirValue = preg_replace('~[^\x00-\xFF]~', '', str_replace(
11821182
['\\', "\0", "\7", "\8", "\t", "\n", "\x0B", "\x0C", "\r", "\x1B"],
1183-
["\\\\", '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\e'],
1183+
['\\\\', '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\e'],
11841184
$DirValue
11851185
));
11861186

@@ -1221,6 +1221,19 @@ public function loadShorthandData(): bool
12211221
return true;
12221222
}
12231223

1224+
/**
1225+
* Check whether a name is reserved. Important, because attempting to read
1226+
* from, write to, or otherwise work with names reserved at the file system
1227+
* can result in unexpected behaviour and potential security risks.
1228+
*
1229+
* @param string $Name The name to check.
1230+
* @return bool True if reserved; False if not.
1231+
*/
1232+
public function isReserved(string $Name): bool
1233+
{
1234+
return preg_match('~(?:^|\\\\|/)(?:\.{1,3}|aux|com(?:\d+|¹|²|³)|con|lpt(?:\d+|¹|²|³)|nul|prn)(?:(?:\..*)?$|\\\\|/)|[ .]$~i', $Name);
1235+
}
1236+
12241237
/**
12251238
* Decodes for multiline support (needed when using INI configuration files).
12261239
*
@@ -1240,7 +1253,7 @@ private function decodeForMultilineSupport(): void
12401253
continue;
12411254
}
12421255
$DirVal = str_replace(
1243-
["\\\\", '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\e'],
1256+
['\\\\', '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\e'],
12441257
['\\', "\0", "\7", "\8", "\t", "\n", "\x0B", "\x0C", "\r", "\x1B"],
12451258
$DirVal
12461259
);

src/Scanner.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* License: GNU/GPLv2
99
* @see LICENSE.txt
1010
*
11-
* This file: The scanner (last modified: 2023.12.01).
11+
* This file: The scanner (last modified: 2023.12.12).
1212
*/
1313

1414
namespace phpMussel\Core;
@@ -1833,7 +1833,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
18331833

18341834
$SigFiles = isset($this->Loader->InstanceCache[$ThisConf[0]]) ? explode(',', $this->Loader->InstanceCache[$ThisConf[0]]) : [];
18351835
foreach ($SigFiles as $SigFile) {
1836-
if (!$SigFile) {
1836+
if ($SigFile === '' || $this->Loader->isReserved($SigFile)) {
18371837
continue;
18381838
}
18391839
if (!isset($this->Loader->InstanceCache[$SigFile])) {

0 commit comments

Comments
 (0)