Skip to content

Commit ad7f3fa

Browse files
committed
Bug-fix.
Changelog excerpt: - Failed to correctly determine the client's IP address under certain circumstances (e.g., multiple choices available via HTTP_X_FORWARDED_FOR); Fixed.
1 parent 6567669 commit ad7f3fa

File tree

3 files changed

+43
-30
lines changed

3 files changed

+43
-30
lines changed

Changelog.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,6 @@ __*Why "v3.0.0" instead of "v1.0.0?"*__ Prior to phpMussel v3, the "phpMussel Co
6464

6565
### v3.3.1
6666

67-
[2021.11.27; Maikuolan]: At the front-end configuration page, configuration directives relying on specific extensions (specifically, at this time, the supplementary cache options) will now include a notice as to whether the extension relied upon is available.
67+
[2021.11.27; Maikuolan]: At the front-end configuration page, configuration directives relying on specific extensions (specifically, at this time, the supplementary cache options) will now include a notice as to whether the extensions relied upon are available.
68+
69+
[2022.02.01; Bug-fix; Maikuolan]: Failed to correctly determine the client's IP address under certain circumstances (e.g., multiple choices available via HTTP_X_FORWARDED_FOR); Fixed.

src/Loader.php

Lines changed: 20 additions & 9 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: 2021.10.31).
11+
* This file: The loader (last modified: 2022.02.01).
1212
*/
1313

1414
namespace phpMussel\Core;
@@ -148,6 +148,11 @@ class Loader
148148
*/
149149
public $MostRecentHttpCode = 0;
150150

151+
/**
152+
* @var string The IP address the instance is working with.
153+
*/
154+
public $IPAddr = '';
155+
151156
/**
152157
* @var string The path to the core asset files.
153158
*/
@@ -171,7 +176,7 @@ class Loader
171176
/**
172177
* @var string Safety mechanism for logging events.
173178
*/
174-
public const SAFETY = "\x3c\x3fphp die; \x3f\x3e";
179+
public const SAFETY = "\x3C\x3Fphp die; \x3F\x3E";
175180

176181
/**
177182
* Construct the loader.
@@ -315,13 +320,19 @@ public function __construct(
315320
$this->$Path = $$Path;
316321
}
317322

318-
/** Failsafe for weird ipaddr configuration and occasional weird server IP handling. */
319-
if (empty($this->Configuration['core']['ipaddr'])) {
320-
$this->Configuration['core']['ipaddr'] = 'REMOTE_ADDR';
321-
}
322-
if (empty($_SERVER[$this->Configuration['core']['ipaddr']])) {
323-
$_SERVER[$this->Configuration['core']['ipaddr']] = '';
323+
/** Failsafe for weird ipaddr configuration. */
324+
$this->IPAddr = (
325+
$this->Configuration['core']['ipaddr'] !== 'REMOTE_ADDR' && empty($_SERVER[$this->Configuration['core']['ipaddr']])
326+
) ? 'REMOTE_ADDR' : $this->Configuration['core']['ipaddr'];
327+
328+
/** Ensure we have an IP address available to work with. */
329+
$this->IPAddr = $_SERVER[$this->IPAddr] ?? '';
330+
331+
/** Ensure the IP address we're working with is a string. */
332+
if (is_array($this->IPAddr)) {
333+
$this->IPAddr = array_shift($this->IPAddr);
324334
}
335+
$this->IPAddr = (string)$this->IPAddr;
325336

326337
/** Set timezone. */
327338
if (!empty($this->Configuration['core']['timezone']) && $this->Configuration['core']['timezone'] !== 'SYSTEM') {
@@ -1222,7 +1233,7 @@ public function atHit(string $Hash, int $Size = -1, string $Name = '', string $T
12221233
}
12231234

12241235
/** Ensure that $Text doesn't break lines and clean it up. */
1225-
$Text = preg_replace('~[\x00-\x1f]~', '', $Text);
1236+
$Text = preg_replace('~[\x00-\x1F]~', '', $Text);
12261237

12271238
/** Generate hash reference and key for various arrays to be populated. */
12281239
$HashReference = sprintf('%s:%d:%s', $Hash, $Size, $Name);

src/Scanner.php

Lines changed: 20 additions & 20 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: 2021.10.30).
11+
* This file: The scanner (last modified: 2022.02.01).
1212
*/
1313

1414
namespace phpMussel\Core;
@@ -85,9 +85,9 @@ public function __construct(\phpMussel\Core\Loader &$Loader)
8585
if ($this->CalledFrom === 'CLI') {
8686
$Origin = 'CLI';
8787
} elseif ($this->Loader->Configuration['legal']['pseudonymise_ip_addresses']) {
88-
$Origin = $this->Loader->pseudonymiseIP($_SERVER[$this->Loader->Configuration['core']['ipaddr']]);
88+
$Origin = $this->Loader->pseudonymiseIP($this->IPAddr);
8989
} else {
90-
$Origin = $_SERVER[$this->Loader->Configuration['core']['ipaddr']];
90+
$Origin = $this->IPAddr;
9191
}
9292

9393
/** Get detections. */
@@ -424,7 +424,7 @@ public function quarantine(string $In, string $Key, string $IP, string $ID): boo
424424
}
425425
$k = strlen($Key);
426426
$FileSize = strlen($In);
427-
$Head = "\xa1phpMussel\x21" . $this->Loader->hexSafe(hash('md5', $In)) . pack('l*', $FileSize) . "\1";
427+
$Head = "\xA1phpMussel\x21" . $this->Loader->hexSafe(hash('md5', $In)) . pack('l*', $FileSize) . "\1";
428428
$In = gzdeflate($In, 9);
429429
$Out = '';
430430
$i = 0;
@@ -439,10 +439,10 @@ public function quarantine(string $In, string $Key, string $IP, string $ID): boo
439439
}
440440
}
441441
$Out =
442-
"\x2f\x3d\x3d phpMussel Quarantined File Upload \x3d\x3d\x5c\n\x7c Time\x2fDate Uploaded\x3a " .
442+
"\x2F\x3D\x3D phpMussel Quarantined File Upload \x3D\x3D\x5C\n\x7C Time\x2FDate Uploaded\x3A " .
443443
str_pad($this->Loader->Time, 18, ' ') .
444-
"\x7c\n\x7c Uploaded From\x3a " . str_pad($IP, 22, ' ') .
445-
" \x7c\n\x5c" . str_repeat("\x3d", 39) . "\x2f\n\n\n" . $Head . $Out;
444+
"\x7C\n\x7C Uploaded From\x3A " . str_pad($IP, 22, ' ') .
445+
" \x7C\n\x5C" . str_repeat("\x3D", 39) . "\x2F\n\n\n" . $Head . $Out;
446446
$UsedMemory = $this->memoryUse($this->Loader->QuarantinePath);
447447
$UsedMemory['Size'] += strlen($Out);
448448
$UsedMemory['Count']++;
@@ -688,7 +688,7 @@ private function recursor($Files = '', int $Depth = -1): void
688688
if (is_dir($Files)) {
689689
if (!is_readable($Files)) {
690690
$this->Loader->InstanceCache['ScanErrors']++;
691-
$this->Loader->atHit('', -1, preg_replace(['~[\x00-\x1f]~', '~^[\\\/]~'], '', $Files), sprintf(
691+
$this->Loader->atHit('', -1, preg_replace(['~[\x00-\x1F]~', '~^[\\\/]~'], '', $Files), sprintf(
692692
$this->Loader->L10N->getString('grammar_exclamation_mark'),
693693
sprintf($this->Loader->L10N->getString('failed_to_access'), $OriginalFilename)
694694
), -5, $Depth);
@@ -715,7 +715,7 @@ private function recursor($Files = '', int $Depth = -1): void
715715
$this->resetHeuristics();
716716

717717
/** Ensure that the original filename doesn't break lines and clean it up. */
718-
$OriginalFilenameClean = preg_replace(['~[\x00-\x1f]~', '~^[\\\/]~'], '', $OriginalFilename);
718+
$OriginalFilenameClean = preg_replace(['~[\x00-\x1F]~', '~^[\\\/]~'], '', $OriginalFilename);
719719

720720
/** Indenting to apply for "checking" . */
721721
$Indent = str_pad('', ($Depth < 1 ? 4 : ($Depth * 3) + 4), '', STR_PAD_LEFT);
@@ -917,7 +917,7 @@ private function recursor($Files = '', int $Depth = -1): void
917917
$this->quarantine(
918918
$In,
919919
$this->Loader->Configuration['quarantine']['quarantine_key'],
920-
$_SERVER[$this->Loader->Configuration['core']['ipaddr']],
920+
$this->IPAddr,
921921
$qfu
922922
);
923923
$this->Loader->HashReference .= sprintf($this->Loader->L10N->getString('quarantined_as'), $qfu) . "\n";
@@ -989,7 +989,7 @@ private function recursor($Files = '', int $Depth = -1): void
989989
$this->quarantine(
990990
$In,
991991
$this->Loader->Configuration['quarantine']['quarantine_key'],
992-
$_SERVER[$this->Loader->Configuration['core']['ipaddr']],
992+
$this->IPAddr,
993993
$qfu
994994
);
995995
$this->Loader->HashReference .= sprintf($this->Loader->L10N->getString('quarantined_as'), $qfu);
@@ -1276,7 +1276,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
12761276
if (strpos($Switch, '=') === false) {
12771277
continue;
12781278
}
1279-
$Switch = explode('=', preg_replace('/[^\x20-\xff]/', '', $Switch));
1279+
$Switch = explode('=', preg_replace('/[^\x20-\xFF]/', '', $Switch));
12801280
if (empty($Switch[0])) {
12811281
continue;
12821282
}
@@ -2233,7 +2233,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
22332233
continue;
22342234
}
22352235
if ($ThisConf[3] === 2) {
2236-
$ThisSig = preg_split('/[\x00-\x1f]+/', $VN[1], -1, PREG_SPLIT_NO_EMPTY);
2236+
$ThisSig = preg_split('/[\x00-\x1F]+/', $VN[1], -1, PREG_SPLIT_NO_EMPTY);
22372237
$ThisSig = ($ThisSig === false) ? '' : implode('', $ThisSig);
22382238
$VN = $this->getShorthand($VN[0]);
22392239
if (
@@ -2247,7 +2247,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
22472247
}
22482248
} elseif ($ThisConf[3] === 0 || $ThisConf[3] === 1) {
22492249
$ThisSig = preg_split((
2250-
$ThisConf[3] === 0 ? '/[^\da-f>]+/i' : '/[\x00-\x1f]+/'
2250+
$ThisConf[3] === 0 ? '/[^\da-f>]+/i' : '/[\x00-\x1F]+/'
22512251
), $VN[1], -1, PREG_SPLIT_NO_EMPTY);
22522252
$ThisSig = ($ThisSig === false ? '' : implode('', $ThisSig));
22532253
$ThisSigLen = strlen($ThisSig);
@@ -2383,7 +2383,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
23832383
/** Chameleon attack bypasses for Mac OS X thumbnails and screenshots. */
23842384
$ThumbnailBypass = (
23852385
substr($OriginalFilename, 0, 2) === '._' &&
2386-
!preg_match('~[^\x00-\x1f]~', substr($str, 0, 8)) &&
2386+
!preg_match('~[^\x00-\x1F]~', substr($str, 0, 8)) &&
23872387
substr($str, 8, 8) === 'Mac OS X'
23882388
);
23892389

@@ -2502,7 +2502,7 @@ private function dataHandler(string $str = '', int $Depth = 0, string $OriginalF
25022502

25032503
/** Control character detection. */
25042504
if ($this->Loader->Configuration['files']['block_control_characters']) {
2505-
if (preg_match('/[\x00-\x08\x0b\x0c\x0e\x1f\x7f]/i', $str)) {
2505+
if (preg_match('/[\x00-\x08\x0B\x0C\x0E\x1F\x7F]/i', $str)) {
25062506
$this->Loader->atHit($sha256, $StringLength, $OriginalFilename, sprintf(
25072507
$this->Loader->L10N->getString('grammar_exclamation_mark'),
25082508
sprintf(
@@ -2921,7 +2921,7 @@ private function archiveRecursor(string $Data, string $File = '', int $ScanDepth
29212921
$Hash = hash('sha256', $Content);
29222922
$DataCRC32 = hash('crc32b', $Content);
29232923
$InternalCRC = $ArchiveObject->EntryCRC();
2924-
$ThisItemRef = $ItemRef . '' . preg_replace(['~[\x00-\x1f]~', '~^[\\\/]~'], '', $Filename);
2924+
$ThisItemRef = $ItemRef . '' . preg_replace(['~[\x00-\x1F]~', '~^[\\\/]~'], '', $Filename);
29252925

29262926
/** Verify filesize, integrity, etc. Exit early in case of problems. */
29272927
if ($Filesize !== strlen($Content) || (
@@ -3279,7 +3279,7 @@ function_exists('gzinflate') &&
32793279
break;
32803280
}
32813281
}
3282-
$str = preg_replace('/[^\x21-\x7e]/', '', strtolower($this->prescanDecode($str . $ostr)));
3282+
$str = preg_replace('/[^\x21-\x7E]/', '', strtolower($this->prescanDecode($str . $ostr)));
32833283
if ($html) {
32843284
$str = preg_replace([
32853285
'@<script[^>]*?>.*?</script>@si',
@@ -3319,7 +3319,7 @@ private function getShorthand(string $VN): string
33193319
$this->Loader->InstanceCache['ignoreme'] = false;
33203320

33213321
/** Byte 0 confirms whether the signature name uses shorthand. */
3322-
if ($VN[0] !== "\x1a") {
3322+
if ($VN[0] !== "\x1A") {
33233323
return $VN;
33243324
}
33253325

@@ -3817,7 +3817,7 @@ private function metaDataScan(string $ItemRef, string $Filename, string &$Data,
38173817
/** Determine whether the file being scanned is a macro. */
38183818
$this->Loader->InstanceCache['file_is_macro'] = (
38193819
strtolower(substr($Filename, -14)) === 'vbaproject.bin' ||
3820-
preg_match('~^\xd0\xcf|\x00Attribut|\x01CompObj|\x05Document~', $Data)
3820+
preg_match('~^\xD0\xCF|\x00Attribut|\x01CompObj|\x05Document~', $Data)
38213821
);
38223822

38233823
/** Handle macro detection and blocking. */

0 commit comments

Comments
 (0)