From: Joshua Rüsweg Date: Fri, 6 Nov 2020 16:00:10 +0000 (+0100) Subject: Use constant time encoding / decoding of security critical code (#3699) X-Git-Tag: 5.4.0_Alpha_1~627 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c5fc8e591ee7d4c79e9cf55dce10bfa88e94ba49;p=GitHub%2FWoltLab%2FWCF.git Use constant time encoding / decoding of security critical code (#3699) * Use `Hex::decode` to convert hex2bin Previously we used the internal PHP function `hex2bin` which has the problem with cache-timing leaks. The Hex class converts the given string without cache-timing leaks. * Use `Hex::encode` to convert bin2hex Previously we used the internal PHP function `bin2hex` which has the problem with cache-timing leaks. The Hex class converts the given string without cache-timing leaks. --- diff --git a/wcfsetup/install/files/lib/action/FacebookAuthAction.class.php b/wcfsetup/install/files/lib/action/FacebookAuthAction.class.php index f2133ef562..38b6da7cde 100644 --- a/wcfsetup/install/files/lib/action/FacebookAuthAction.class.php +++ b/wcfsetup/install/files/lib/action/FacebookAuthAction.class.php @@ -1,5 +1,6 @@ register('__facebookInit', $token); HeaderUtil::redirect("https://www.facebook.com/dialog/oauth?client_id=".StringUtil::trim(FACEBOOK_PUBLIC_KEY). "&redirect_uri=".rawurlencode($callbackURL)."&state=".$token."&scope=email"); $this->executed(); diff --git a/wcfsetup/install/files/lib/action/GithubAuthAction.class.php b/wcfsetup/install/files/lib/action/GithubAuthAction.class.php index a7d850b551..873f3b839a 100644 --- a/wcfsetup/install/files/lib/action/GithubAuthAction.class.php +++ b/wcfsetup/install/files/lib/action/GithubAuthAction.class.php @@ -1,5 +1,6 @@ register('__githubInit', $token); HeaderUtil::redirect("https://github.com/login/oauth/authorize?client_id=".rawurlencode(StringUtil::trim(GITHUB_PUBLIC_KEY))."&scope=".rawurlencode('user:email')."&state=".$token); $this->executed(); diff --git a/wcfsetup/install/files/lib/action/GoogleAuthAction.class.php b/wcfsetup/install/files/lib/action/GoogleAuthAction.class.php index 396dfa70bb..57159330f8 100644 --- a/wcfsetup/install/files/lib/action/GoogleAuthAction.class.php +++ b/wcfsetup/install/files/lib/action/GoogleAuthAction.class.php @@ -1,5 +1,6 @@ register('__googleInit', $token); HeaderUtil::redirect("https://accounts.google.com/o/oauth2/auth?client_id=".rawurlencode(StringUtil::trim(GOOGLE_PUBLIC_KEY)). "&redirect_uri=".rawurlencode($callbackURL)."&state=".$token."&scope=profile+openid+email&response_type=code"); $this->executed(); diff --git a/wcfsetup/install/files/lib/action/TwitterAuthAction.class.php b/wcfsetup/install/files/lib/action/TwitterAuthAction.class.php index e0d0e3e68a..59c84735a6 100644 --- a/wcfsetup/install/files/lib/action/TwitterAuthAction.class.php +++ b/wcfsetup/install/files/lib/action/TwitterAuthAction.class.php @@ -1,5 +1,6 @@ StringUtil::trim(TWITTER_PUBLIC_KEY), - 'oauth_nonce' => bin2hex(\random_bytes(20)), + 'oauth_nonce' => Hex::encode(\random_bytes(20)), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0', @@ -114,7 +115,7 @@ class TwitterAuthAction extends AbstractAction { try { $oauthHeader = [ 'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), - 'oauth_nonce' => bin2hex(\random_bytes(20)), + 'oauth_nonce' => Hex::encode(\random_bytes(20)), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0', @@ -167,7 +168,7 @@ class TwitterAuthAction extends AbstractAction { $oauthHeader = [ 'oauth_callback' => $callbackURL, 'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), - 'oauth_nonce' => bin2hex(\random_bytes(20)), + 'oauth_nonce' => Hex::encode(\random_bytes(20)), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0' diff --git a/wcfsetup/install/files/lib/data/style/StyleAction.class.php b/wcfsetup/install/files/lib/data/style/StyleAction.class.php index 4bf7800b3a..bbf2b5b975 100644 --- a/wcfsetup/install/files/lib/data/style/StyleAction.class.php +++ b/wcfsetup/install/files/lib/data/style/StyleAction.class.php @@ -1,5 +1,6 @@ getLocation(); $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION); - $newName = $type.'-'.\bin2hex(\random_bytes(4)).'.'.$extension; + $newName = $type.'-'.Hex::encode(\random_bytes(4)).'.'.$extension; $newLocation = $style->getAssetPath().$newName; rename($fileLocation, $newLocation); $this->parameters['variables'][$type] = $newName; diff --git a/wcfsetup/install/files/lib/data/user/UserAction.class.php b/wcfsetup/install/files/lib/data/user/UserAction.class.php index 772e2b3e9a..c13eb933cb 100644 --- a/wcfsetup/install/files/lib/data/user/UserAction.class.php +++ b/wcfsetup/install/files/lib/data/user/UserAction.class.php @@ -1,5 +1,6 @@ objects as $object) { (new UserAction([$object], 'update', [ 'data' => [ - 'emailConfirmed' => bin2hex(\random_bytes(20)) + 'emailConfirmed' => Hex::encode(\random_bytes(20)) ] ]))->executeAction(); } @@ -743,7 +744,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio $action = new UserAction($this->objects, 'update', [ 'data' => [ 'activationCode' => UserRegistrationUtil::getActivationCode(), - 'emailConfirmed' => bin2hex(\random_bytes(20)), + 'emailConfirmed' => Hex::encode(\random_bytes(20)), ], 'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::USERS]) ]); @@ -1113,7 +1114,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio foreach ($this->objects as $object) { $action = new UserAction([$object], 'update', [ 'data' => [ - 'emailConfirmed' => bin2hex(\random_bytes(20)) + 'emailConfirmed' => Hex::encode(\random_bytes(20)) ] ]); $action->executeAction(); diff --git a/wcfsetup/install/files/lib/data/user/UserEditor.class.php b/wcfsetup/install/files/lib/data/user/UserEditor.class.php index f9d7642be4..8000688446 100644 --- a/wcfsetup/install/files/lib/data/user/UserEditor.class.php +++ b/wcfsetup/install/files/lib/data/user/UserEditor.class.php @@ -1,5 +1,6 @@ accessToken = $parameters['accessToken']; diff --git a/wcfsetup/install/files/lib/form/LostPasswordForm.class.php b/wcfsetup/install/files/lib/form/LostPasswordForm.class.php index 56120d5a00..6364a8454d 100644 --- a/wcfsetup/install/files/lib/form/LostPasswordForm.class.php +++ b/wcfsetup/install/files/lib/form/LostPasswordForm.class.php @@ -1,5 +1,6 @@ objectAction = new UserAction([$this->user], 'update', [ diff --git a/wcfsetup/install/files/lib/form/RegisterForm.class.php b/wcfsetup/install/files/lib/form/RegisterForm.class.php index 1c02be1c0b..11d0454b07 100644 --- a/wcfsetup/install/files/lib/form/RegisterForm.class.php +++ b/wcfsetup/install/files/lib/form/RegisterForm.class.php @@ -1,5 +1,6 @@ password = bin2hex(\random_bytes(20)); + $this->password = Hex::encode(\random_bytes(20)); } $eventParameters = [ @@ -453,7 +454,7 @@ class RegisterForm extends UserAddForm { $addDefaultGroups = true; if (!empty($this->blacklistMatches) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$registerVia3rdParty) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN)) { $activationCode = UserRegistrationUtil::getActivationCode(); - $emailConfirmCode = bin2hex(\random_bytes(20)); + $emailConfirmCode = Hex::encode(\random_bytes(20)); $this->additionalFields['activationCode'] = $activationCode; $this->additionalFields['emailConfirmed'] = $emailConfirmCode; $addDefaultGroups = false; diff --git a/wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php b/wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php index 89040ef1cc..ec6be23f0d 100644 --- a/wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php +++ b/wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php @@ -1,5 +1,6 @@ notificationMailToken) { - $token = bin2hex(\random_bytes(10)); + $token = Hex::encode(\random_bytes(10)); $editor = new UserEditor($user); $editor->update(['notificationMailToken' => $token]); diff --git a/wcfsetup/install/files/lib/system/email/Email.class.php b/wcfsetup/install/files/lib/system/email/Email.class.php index 18919c5be3..15af59d45a 100644 --- a/wcfsetup/install/files/lib/system/email/Email.class.php +++ b/wcfsetup/install/files/lib/system/email/Email.class.php @@ -1,5 +1,6 @@ messageID === null) { - $this->messageID = bin2hex(\random_bytes(20)); + $this->messageID = Hex::encode(\random_bytes(20)); } return '<'.$this->messageID.'@'.self::getHost().'>'; @@ -533,7 +534,7 @@ class Email { */ public function getHeaderString() { return implode("\r\n", array_map(function ($item) { - list($name, $value) = $item; + [$name, $value] = $item; switch ($name) { case 'message-id': diff --git a/wcfsetup/install/files/lib/system/email/mime/AbstractMultipartMimePart.class.php b/wcfsetup/install/files/lib/system/email/mime/AbstractMultipartMimePart.class.php index 0653c78576..fcb373c54a 100644 --- a/wcfsetup/install/files/lib/system/email/mime/AbstractMultipartMimePart.class.php +++ b/wcfsetup/install/files/lib/system/email/mime/AbstractMultipartMimePart.class.php @@ -1,5 +1,6 @@ boundary = "WoltLab_Suite=_".bin2hex(\random_bytes(20)); + $this->boundary = "WoltLab_Suite=_".Hex::encode(\random_bytes(20)); $this->parts = new \SplObjectStorage(); } diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php index ba709ea7ff..ae209f262e 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php @@ -232,12 +232,16 @@ class PackageInstallationDispatcher { ]); $statement->execute([ + // We do not use the cache-timing safe class Hex, because we run the + // function during the setup. $signatureSecret = \bin2hex(\random_bytes(20)), 'signature_secret' ]); \define('SIGNATURE_SECRET', $signatureSecret); HeaderUtil::setCookie( 'acp_session', + // We do not use the cache-timing safe class Hex, because we run the + // function during the setup. CryptoUtil::createSignedString(\hex2bin(WCF::getSession()->sessionID)) ); diff --git a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php index 66cf6e8273..64e6269dfd 100644 --- a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php +++ b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php @@ -1,5 +1,6 @@ sessionID = \bin2hex(\random_bytes(20)); + $this->sessionID = Hex::encode(\random_bytes(20)); // Create new session. $sql = "INSERT INTO wcf".WCF_N."_".($this->isACP ? 'acp' : 'user')."_session diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/CryptMD5.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/CryptMD5.class.php index fea77e8cf1..04ccc4ba45 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/CryptMD5.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/CryptMD5.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt); } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb2.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb2.class.php index 0e0c5ac9aa..11acd3f52d 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb2.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb2.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb3.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb3.class.php index ddd8fb3ec5..da46cdc7d8 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb3.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Ipb3.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla1.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla1.class.php index 6be64299bd..e924b88de2 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla1.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla1.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla2.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla2.class.php index 1a5bf50487..da73f714d2 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla2.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla2.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla3.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla3.class.php index 4c24b74ce8..670535a106 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla3.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Joomla3.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Mybb1.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Mybb1.class.php index df4a579d8c..cf59295d77 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Mybb1.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Mybb1.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Phpfox3.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Phpfox3.class.php index cd00be386e..05faa8c719 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Phpfox3.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Phpfox3.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf1.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf1.class.php index 2603994af7..97a3be0b5a 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf1.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf1.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf2.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf2.class.php index c18c15c565..605553295c 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf2.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Smf2.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/TPhpass.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/TPhpass.class.php index 9a71d0ceda..d3363f10d8 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/TPhpass.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/TPhpass.class.php @@ -1,5 +1,6 @@ hashPhpass($password, $settings).':'; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb3.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb3.class.php index 24546c4fe1..2848e14264 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb3.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb3.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb4.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb4.class.php index 0aa3375082..94b66dded1 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb4.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb4.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb5.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb5.class.php index f911776c90..b7968df6ab 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb5.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Vb5.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1.class.php index c2ea2fb302..802a794179 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1e.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1e.class.php index b449f6cd7e..b7ca07e794 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1e.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Wcf1e.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Xf1.class.php b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Xf1.class.php index d170488b9b..c3fbd00353 100644 --- a/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Xf1.class.php +++ b/wcfsetup/install/files/lib/system/user/authentication/password/algorithm/Xf1.class.php @@ -1,5 +1,6 @@ hashWithSalt($password, $salt).':'.$salt; } diff --git a/wcfsetup/install/files/lib/system/user/notification/TestableUserNotificationEventHandler.class.php b/wcfsetup/install/files/lib/system/user/notification/TestableUserNotificationEventHandler.class.php index 0d8c526ab8..fc3c6ddcf2 100644 --- a/wcfsetup/install/files/lib/system/user/notification/TestableUserNotificationEventHandler.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/TestableUserNotificationEventHandler.class.php @@ -1,5 +1,6 @@ [ 'email' => $username . '@example.com', 'languageID' => $languages[array_rand($languages)]->languageID, - 'password' => \bin2hex(\random_bytes(16)), + 'password' => Hex::encode(\random_bytes(16)), 'registrationDate' => TIME_NOW - 24 * 3600 * random_int(10, 1000), 'username' => $username ] diff --git a/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php b/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php index 577efecbfd..f8e8a49d0f 100644 --- a/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php +++ b/wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php @@ -1,5 +1,6 @@ notificationMailToken) { - $token = bin2hex(\random_bytes(10)); + $token = Hex::encode(\random_bytes(10)); $editor = new UserEditor($user); $editor->update(['notificationMailToken' => $token]); diff --git a/wcfsetup/install/files/lib/system/worker/SendNewPasswordWorker.class.php b/wcfsetup/install/files/lib/system/worker/SendNewPasswordWorker.class.php index 87c93fb92e..dbbba5b21a 100644 --- a/wcfsetup/install/files/lib/system/worker/SendNewPasswordWorker.class.php +++ b/wcfsetup/install/files/lib/system/worker/SendNewPasswordWorker.class.php @@ -1,5 +1,6 @@ [ diff --git a/wcfsetup/install/files/lib/util/FileUtil.class.php b/wcfsetup/install/files/lib/util/FileUtil.class.php index cbb148e0a0..95b998227b 100644 --- a/wcfsetup/install/files/lib/util/FileUtil.class.php +++ b/wcfsetup/install/files/lib/util/FileUtil.class.php @@ -1,5 +1,6 @@ addHeader('content-type', 'application/x-www-form-urlencoded'); } else { - $boundary = bin2hex(\random_bytes(20)); + $boundary = Hex::encode(\random_bytes(20)); $this->addHeader('content-type', 'multipart/form-data; boundary='.$boundary); // source of the iterators: http://stackoverflow.com/a/7623716/782822 diff --git a/wcfsetup/install/files/lib/util/StringUtil.class.php b/wcfsetup/install/files/lib/util/StringUtil.class.php index ecdc830113..c47c347fc4 100644 --- a/wcfsetup/install/files/lib/util/StringUtil.class.php +++ b/wcfsetup/install/files/lib/util/StringUtil.class.php @@ -1,5 +1,6 @@