Remove IPAddress::remote and all implicit resolving of the request remote address.

This commit is contained in:
flash 2023-01-05 18:33:03 +00:00
parent f7fcd3230a
commit 2394492bf8
26 changed files with 65 additions and 69 deletions

View file

@ -187,7 +187,7 @@ if($authToken->isValid()) {
if(!$userInfo->isDeleted()) {
$sessionInfo->setCurrent();
$userInfo->setCurrent();
$sessionInfo->bump();
$sessionInfo->bump($_SERVER['REMOTE_ADDR']);
if($sessionInfo->shouldBumpExpire())
setcookie('msz_auth', $authToken->pack(), $sessionInfo->getExpiresTime(), '/', msz_cookie_domain(), !empty($_SERVER['HTTPS']), true);
@ -202,7 +202,7 @@ if($authToken->isValid()) {
}
if(UserSession::hasCurrent()) {
$userInfo->bumpActivity();
$userInfo->bumpActivity($_SERVER['REMOTE_ADDR']);
} else {
setcookie('msz_auth', '', -9001, '/', msz_cookie_domain(), !empty($_SERVER['HTTPS']), true);
setcookie('msz_auth', '', -9001, '/', '', !empty($_SERVER['HTTPS']), true);
@ -210,7 +210,11 @@ if($authToken->isValid()) {
}
CSRF::setGlobalSecretKey($cfg->getValue('csrf.secret', CfgType::T_STR, 'soup'));
CSRF::setGlobalIdentity(UserSession::hasCurrent() ? UserSession::getCurrent()->getToken() : IPAddress::remote());
CSRF::setGlobalIdentity(
UserSession::hasCurrent()
? UserSession::getCurrent()->getToken()
: ($_SERVER['REMOTE_ADDR'] ?? '::1')
);
function mszLockdown(): void {
global $misuzuBypassLockdown, $cfg;

View file

@ -41,10 +41,11 @@ if(!empty($_GET['resolve'])) {
}
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$siteIsPrivate = $cfg->getValue('private.enable', CfgType::T_BOOL);
$loginPermCat = $siteIsPrivate ? $cfg->getValue('private.perm.cat', CfgType::T_STR) : '';
$loginPermVal = $siteIsPrivate ? $cfg->getValue('private.perm.val', CfgType::T_INT) : 0;
$remainingAttempts = UserLoginAttempt::remaining();
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
while(!empty($_POST['login']) && is_array($_POST['login'])) {
if(!CSRF::validateRequest()) {
@ -75,7 +76,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
try {
$userInfo = User::byUsernameOrEMailAddress($_POST['login']['username']);
} catch(UserNotFoundException $ex) {
UserLoginAttempt::create(false);
UserLoginAttempt::create($ipAddress, false);
$notices[] = $loginFailedError;
break;
}
@ -86,7 +87,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
}
if($userInfo->isDeleted() || !$userInfo->checkPassword($_POST['login']['password'])) {
UserLoginAttempt::create(false, $userInfo);
UserLoginAttempt::create($ipAddress, false, $userInfo);
$notices[] = $loginFailedError;
break;
}
@ -96,7 +97,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
if(!empty($loginPermCat) && $loginPermVal > 0 && !perms_check_user($loginPermCat, $userInfo->getId(), $loginPermVal)) {
$notices[] = "Login succeeded, but you're not allowed to browse the site right now.";
UserLoginAttempt::create(true, $userInfo);
UserLoginAttempt::create($ipAddress, true, $userInfo);
break;
}
@ -107,10 +108,10 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
return;
}
UserLoginAttempt::create(true, $userInfo);
UserLoginAttempt::create($ipAddress, true, $userInfo);
try {
$sessionInfo = UserSession::create($userInfo);
$sessionInfo = UserSession::create($userInfo, $ipAddress);
$sessionInfo->setCurrent();
} catch(UserSessionCreationFailedException $ex) {
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";

View file

@ -33,9 +33,10 @@ if($userId > 0)
}
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$siteIsPrivate = $cfg->getValue('private.enable', CfgType::T_BOOL);
$canResetPassword = $siteIsPrivate ? $cfg->getValue('private.allow_password_reset', CfgType::T_BOOL, true) : true;
$remainingAttempts = UserLoginAttempt::remaining();
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
while($canResetPassword) {
if(!empty($reset) && $userId > 0) {
@ -78,7 +79,7 @@ while($canResetPassword) {
->removeTOTPKey()
->save();
AuditLog::create(AuditLog::PASSWORD_RESET, [], $userInfo);
AuditLog::create($ipAddress, AuditLog::PASSWORD_RESET, [], $userInfo);
$tokenInfo->invalidate();
@ -114,9 +115,9 @@ while($canResetPassword) {
}
try {
$tokenInfo = UserRecoveryToken::byUserAndRemoteAddress($forgotUser);
$tokenInfo = UserRecoveryToken::byUserAndRemoteAddress($forgotUser, $ipAddress);
} catch(UserRecoveryTokenNotFoundException $ex) {
$tokenInfo = UserRecoveryToken::create($forgotUser);
$tokenInfo = UserRecoveryToken::create($forgotUser, $ipAddress);
$recoveryMessage = Mailer::template('password-recovery', [
'username' => $forgotUser->getUsername(),

View file

@ -1,7 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Net\IPAddress;
use Misuzu\Users\User;
use Misuzu\Users\UserCreationFailedException;
use Misuzu\Users\UserLoginAttempt;
@ -18,9 +17,9 @@ if(UserSession::hasCurrent()) {
$register = !empty($_POST['register']) && is_array($_POST['register']) ? $_POST['register'] : [];
$notices = [];
$ipAddress = IPAddress::remote();
$remainingAttempts = UserLoginAttempt::remaining();
$restricted = UserWarning::countByRemoteAddress() > 0 ? 'ban' : '';
$ipAddress = $_SERVER['REMOTE_ADDR'];
$remainingAttempts = UserLoginAttempt::remaining($_SERVER['REMOTE_ADDR']);
$restricted = UserWarning::countByRemoteAddress($ipAddress) > 0 ? 'ban' : '';
while(!$restricted && !empty($register)) {
if(!CSRF::validateRequest()) {

View file

@ -15,9 +15,10 @@ if(UserSession::hasCurrent()) {
return;
}
$ipAddress = $_SERVER['REMOTE_ADDR'];
$twofactor = !empty($_POST['twofactor']) && is_array($_POST['twofactor']) ? $_POST['twofactor'] : [];
$notices = [];
$remainingAttempts = UserLoginAttempt::remaining();
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
try {
$tokenInfo = UserAuthSession::byToken(
@ -66,11 +67,11 @@ while(!empty($twofactor)) {
$remainingAttempts - 1,
$remainingAttempts === 2 ? '' : 's'
);
UserLoginAttempt::create(false, $userInfo);
UserLoginAttempt::create($ipAddress, false, $userInfo);
break;
}
UserLoginAttempt::create(true, $userInfo);
UserLoginAttempt::create($ipAddress, true, $userInfo);
$tokenInfo->delete();
try {

View file

@ -138,13 +138,13 @@ switch($commentMode) {
$commentInfo2->save();
if($isModAction) {
AuditLog::create(AuditLog::COMMENT_ENTRY_DELETE_MOD, [
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_DELETE_MOD, [
$commentInfo2->getId(),
$commentUserId = $commentInfo2->getUserId(),
($commentUserId < 1 ? '(Deleted User)' : $commentInfo2->getUser()->getUsername()),
]);
} else {
AuditLog::create(AuditLog::COMMENT_ENTRY_DELETE, [$commentInfo2->getId()]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_DELETE, [$commentInfo2->getId()]);
}
redirect($redirect);
@ -164,7 +164,7 @@ switch($commentMode) {
$commentInfo2->setDeleted(false);
$commentInfo2->save();
AuditLog::create(AuditLog::COMMENT_ENTRY_RESTORE, [
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_RESTORE, [
$commentInfo2->getId(),
$commentUserId = $commentInfo2->getUserId(),
($commentUserId < 1 ? '(Deleted User)' : $commentInfo2->getUser()->getUsername()),

View file

@ -104,7 +104,7 @@ switch($postMode) {
$deletePost = forum_post_delete($postInfo['post_id']);
if($deletePost) {
AuditLog::create(AuditLog::FORUM_POST_DELETE, [$postInfo['post_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_DELETE, [$postInfo['post_id']]);
}
if(!$deletePost) {
@ -147,7 +147,7 @@ switch($postMode) {
break;
}
AuditLog::create(AuditLog::FORUM_POST_NUKE, [$postInfo['post_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_NUKE, [$postInfo['post_id']]);
url_redirect('forum-topic', ['topic' => $postInfo['topic_id']]);
break;
@ -184,7 +184,7 @@ switch($postMode) {
break;
}
AuditLog::create(AuditLog::FORUM_POST_RESTORE, [$postInfo['post_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_RESTORE, [$postInfo['post_id']]);
url_redirect('forum-topic', ['topic' => $postInfo['topic_id']]);
break;

View file

@ -1,7 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Net\IPAddress;
use Misuzu\Parsers\Parser;
use Misuzu\Users\User;
@ -210,7 +209,7 @@ if(!empty($_POST)) {
$topicId,
$forum['forum_id'],
$currentUserId,
IPAddress::remote(),
$_SERVER['REMOTE_ADDR'],
$postText,
$postParser,
$postSignature
@ -220,7 +219,7 @@ if(!empty($_POST)) {
break;
case 'edit':
if(!forum_post_update($postId, IPAddress::remote(), $postText, $postParser, $postSignature, $postText !== $post['post_text'])) {
if(!forum_post_update($postId, $_SERVER['REMOTE_ADDR'], $postText, $postParser, $postSignature, $postText !== $post['post_text'])) {
$notices[] = 'Post edit failed.';
}

View file

@ -157,7 +157,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
$deleteTopic = forum_topic_delete($topic['topic_id']);
if($deleteTopic)
AuditLog::create(AuditLog::FORUM_TOPIC_DELETE, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_DELETE, [$topic['topic_id']]);
if(!$deleteTopic) {
echo render_error(500);
@ -200,7 +200,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break;
}
AuditLog::create(AuditLog::FORUM_TOPIC_RESTORE, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_RESTORE, [$topic['topic_id']]);
url_redirect('forum-category', [
'forum' => $topic['forum_id'],
@ -238,7 +238,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break;
}
AuditLog::create(AuditLog::FORUM_TOPIC_NUKE, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_NUKE, [$topic['topic_id']]);
url_redirect('forum-category', [
'forum' => $topic['forum_id'],
@ -247,7 +247,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'bump':
if($canBumpTopic && forum_topic_bump($topic['topic_id'])) {
AuditLog::create(AuditLog::FORUM_TOPIC_BUMP, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_BUMP, [$topic['topic_id']]);
}
url_redirect('forum-topic', [
@ -257,7 +257,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'lock':
if($canLockTopic && !$topicIsLocked && forum_topic_lock($topic['topic_id'])) {
AuditLog::create(AuditLog::FORUM_TOPIC_LOCK, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_LOCK, [$topic['topic_id']]);
}
url_redirect('forum-topic', [
@ -267,7 +267,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'unlock':
if($canLockTopic && $topicIsLocked && forum_topic_unlock($topic['topic_id'])) {
AuditLog::create(AuditLog::FORUM_TOPIC_UNLOCK, [$topic['topic_id']]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_UNLOCK, [$topic['topic_id']]);
}
url_redirect('forum-topic', [

View file

@ -60,6 +60,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::CHANGELOG_ENTRY_EDIT
: AuditLog::CHANGELOG_ENTRY_CREATE,

View file

@ -35,6 +35,7 @@ if(!empty($_POST['tag']) && is_array($_POST['tag']) && CSRF::validateRequest())
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::CHANGELOG_TAG_EDIT
: AuditLog::CHANGELOG_TAG_CREATE,

View file

@ -22,7 +22,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(!CSRF::validateRequest())
throw new \Exception("Request verification failed.");
AuditLog::create(AuditLog::CONFIG_DELETE, [$sName]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::CONFIG_DELETE, [$sName]);
$cfg->removeValue($sName);
url_redirect('manage-general-settings');
} else {

View file

@ -95,7 +95,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
$sVar['value'] = $sValue;
AuditLog::create($sLogAction, [$sName]);
AuditLog::create($_SERVER['REMOTE_ADDR'], $sLogAction, [$sName]);
$cfg->setValue($sName, $sValue);
url_redirect('manage-general-settings');
return;

View file

@ -36,6 +36,7 @@ if(!empty($_POST['category']) && CSRF::validateRequest()) {
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::NEWS_CATEGORY_EDIT
: AuditLog::NEWS_CATEGORY_CREATE,

View file

@ -45,6 +45,7 @@ if(!empty($_POST['post']) && CSRF::validateRequest()) {
$postInfo->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::NEWS_POST_EDIT
: AuditLog::NEWS_POST_CREATE,

View file

@ -103,7 +103,7 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
}
} else {
$currentUser->setEMailAddress($_POST['email']['new']);
AuditLog::create(AuditLog::PERSONAL_EMAIL_CHANGE, [
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_EMAIL_CHANGE, [
$_POST['email']['new'],
]);
}
@ -121,7 +121,7 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
$errors[] = 'The given passwords was too weak.';
} else {
$currentUser->setPassword($_POST['password']['new']);
AuditLog::create(AuditLog::PERSONAL_PASSWORD_CHANGE);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_PASSWORD_CHANGE);
}
}
}

View file

@ -36,7 +36,7 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
&& $currentUser->checkPassword($_POST['password'] ?? '')) {
switch($_POST['action']) {
case 'data':
AuditLog::create(AuditLog::PERSONAL_DATA_DOWNLOAD);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_DATA_DOWNLOAD);
$timeStamp = floor(time() / 3600) * 3600;
$fileName = sprintf('msz-user-data-%d-%d.zip', $currentUserId, $timeStamp);

View file

@ -38,12 +38,12 @@ if(!empty($_POST['session']) && CSRF::validateRequest()) {
}
$sessionInfo->delete();
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY, [$sessionInfo->getId()]);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_SESSION_DESTROY, [$sessionInfo->getId()]);
}
} elseif($_POST['session'] === 'all') {
$currentSessionKilled = true;
UserSession::purgeUser($currentUser);
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY_ALL);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_SESSION_DESTROY_ALL);
}
if($currentSessionKilled) {

View file

@ -155,9 +155,8 @@ class AuditLog {
return vsprintf(self::FORMATS[$this->getAction()], $this->getParams());
}
public static function create(string $action, array $params = [], ?User $user = null, ?string $remoteAddr = null): void {
public static function create(string $remoteAddr, string $action, array $params = [], ?User $user = null): void {
$user = $user ?? User::getCurrent();
$remoteAddr = $remoteAddr ?? IPAddress::remote();
$createLog = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`log_action`, `user_id`, `log_params`, `log_ip`, `log_country`)'
. ' VALUES (:action, :user, :params, INET6_ATON(:ip), :country)'

View file

@ -4,10 +4,6 @@ namespace Misuzu\Net;
use GeoIp2\Exception\AddressNotFoundException;
final class IPAddress {
public static function remote(string $fallback = '::1'): string {
return $_SERVER['REMOTE_ADDR'] ?? $fallback;
}
public static function country(string $address, string $fallback = 'XX'): string {
if(!GeoIP::isAvailable())
return $fallback;

View file

@ -228,7 +228,7 @@ final class SharpChatRoutes {
return ['success' => false, 'reason' => 'expired'];
}
$sessionInfo->bump();
$sessionInfo->bump($authInfo->ip);
} else {
return ['success' => false, 'reason' => 'unsupported'];
}

View file

@ -337,9 +337,9 @@ class User implements HasRankInterface, JsonSerializable {
return ProfileField::user($userId, $filterEmpty);
}
public function bumpActivity(?string $lastRemoteAddress = null): void {
public function bumpActivity(string $lastRemoteAddress): void {
$this->user_active = time();
$this->last_ip = $lastRemoteAddress ?? IPAddress::remote();
$this->last_ip = $lastRemoteAddress;
DB::prepare(
'UPDATE `' . DB::PREFIX . self::TABLE . '`'

View file

@ -66,8 +66,7 @@ class UserLoginAttempt {
return $this->uaInfo;
}
public static function remaining(?string $remoteAddr = null): int {
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public static function remaining(string $remoteAddr): int {
return (int)DB::prepare(
'SELECT 5 - COUNT(*)'
. ' FROM `' . DB::PREFIX . self::TABLE . '`'
@ -78,8 +77,7 @@ class UserLoginAttempt {
->fetchColumn();
}
public static function create(bool $success, ?User $user = null, ?string $remoteAddr = null, string $userAgent = null): void {
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public static function create(string $remoteAddr, bool $success, ?User $user = null, string $userAgent = null): void {
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT') ?? '';
$createLog = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `attempt_success`, `attempt_ip`, `attempt_country`, `attempt_user_agent`)'

View file

@ -73,8 +73,7 @@ class UserRecoveryToken {
return bin2hex(random_bytes(self::TOKEN_WIDTH));
}
public static function create(User $user, ?string $remoteAddr = null, bool $return = true): ?self {
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public static function create(User $user, string $remoteAddr, bool $return = true): ?self {
$token = self::generateToken();
$created = DB::prepare('INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `reset_ip`, `verification_code`) VALUES (:user, INET6_ATON(:address), :token)')
@ -110,8 +109,7 @@ class UserRecoveryToken {
return $object;
}
public static function byUserAndRemoteAddress(User $user, ?string $remoteAddr = null): self {
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public static function byUserAndRemoteAddress(User $user, string $remoteAddr): self {
$object = DB::prepare(self::byQueryBase() . ' WHERE `user_id` = :user AND `reset_ip` = INET6_ATON(:address)')
->bind('user', $user->getId())
->bind('address', $remoteAddr)

View file

@ -120,9 +120,9 @@ class UserSession {
return boolval($this->session_expires_bump);
}
public function bump(bool $callUpdate = true, ?int $timestamp = null, ?string $remoteAddr = null): void {
$timestamp = $timestamp ?? time();
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public function bump(string $remoteAddr, int $timestamp = -1): void {
if($timestamp < 0)
$timestamp = time();
$this->setActiveTime($timestamp)
->setLastRemoteAddress($remoteAddr);
@ -130,8 +130,7 @@ class UserSession {
if($this->shouldBumpExpire())
$this->setExpiresTime($timestamp + self::LIFETIME);
if($callUpdate)
$this->update();
$this->update();
}
public function delete(): void {
@ -175,8 +174,7 @@ class UserSession {
->execute();
}
public static function create(User $user, ?string $remoteAddr = null, ?string $userAgent = null, ?string $token = null): self {
$remoteAddr = $remoteAddr ?? IPAddress::remote();
public static function create(User $user, string $remoteAddr, ?string $userAgent = null, ?string $token = null): self {
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT') ?? '';
$token = $token ?? self::generateToken();

View file

@ -4,7 +4,6 @@ namespace Misuzu\Users;
use InvalidArgumentException;
use Misuzu\DB;
use Misuzu\Pagination;
use Misuzu\Net\IPAddress;
class UserWarningException extends UsersException {}
class UserWarningNotFoundException extends UserWarningException {}
@ -199,8 +198,7 @@ class UserWarning {
private static function countQueryBase(): string {
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
}
public static function countByRemoteAddress(?string $address = null, bool $withDuration = true): int {
$address = $address ?? IPAddress::remote();
public static function countByRemoteAddress(string $address, bool $withDuration = true): int {
return (int)DB::prepare(
self::countQueryBase()
. ' WHERE `user_ip` = INET6_ATON(:address)'