Issue 14220: Sanitize profile data

This commit is contained in:
Michael 2024-06-14 20:19:31 +00:00
parent 11f305de68
commit 8dd8ca23f7

View file

@ -26,13 +26,13 @@ use Friendica\Content\Feature;
use Friendica\Content\GroupManager; use Friendica\Content\GroupManager;
use Friendica\Content\Nav; use Friendica\Content\Nav;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Contact; use Friendica\Model\Contact;
@ -43,12 +43,14 @@ use Friendica\Module\BaseProfile;
use Friendica\Module\Response; use Friendica\Module\Response;
use Friendica\Module\Security\Login; use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Profile\ProfileField\Repository\ProfileField; use Friendica\Profile\ProfileField\Repository\ProfileField;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Strings;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use GuzzleHttp\Psr7\Uri;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
class Profile extends BaseProfile class Profile extends BaseProfile
@ -164,7 +166,7 @@ class Profile extends BaseProfile
$basic_fields = []; $basic_fields = [];
$basic_fields += self::buildField('fullname', $this->t('Full Name:'), $profile['name']); $basic_fields += self::buildField('fullname', $this->t('Full Name:'), $this->cleanInput($profile['uri-id'], $profile['name']));
if (Feature::isEnabled($profile['uid'], Feature::MEMBER_SINCE)) { if (Feature::isEnabled($profile['uid'], Feature::MEMBER_SINCE)) {
$basic_fields += self::buildField( $basic_fields += self::buildField(
@ -196,18 +198,18 @@ class Profile extends BaseProfile
} }
if ($profile['xmpp']) { if ($profile['xmpp']) {
$basic_fields += self::buildField('xmpp', $this->t('XMPP:'), $profile['xmpp']); $basic_fields += self::buildField('xmpp', $this->t('XMPP:'), $this->cleanInput($profile['uri-id'], $profile['xmpp']));
} }
if ($profile['matrix']) { if ($profile['matrix']) {
$basic_fields += self::buildField('matrix', $this->t('Matrix:'), $profile['matrix']); $basic_fields += self::buildField('matrix', $this->t('Matrix:'), $this->cleanInput($profile['uri-id'], $profile['matrix']));
} }
if ($profile['homepage']) { if ($profile['homepage']) {
$basic_fields += self::buildField( $basic_fields += self::buildField(
'homepage', 'homepage',
$this->t('Homepage:'), $this->t('Homepage:'),
$this->tryRelMe($profile['homepage']) ?: $profile['homepage'] $this->tryRelMe($profile['homepage']) ?: $this->cleanInput($profile['uri-id'], $profile['homepage'])
); );
} }
@ -218,7 +220,7 @@ class Profile extends BaseProfile
|| $profile['region'] || $profile['region']
|| $profile['country-name'] || $profile['country-name']
) { ) {
$basic_fields += self::buildField('location', $this->t('Location:'), ProfileModel::formatLocation($profile)); $basic_fields += self::buildField('location', $this->t('Location:'), $this->cleanInput($profile['uri-id'], ProfileModel::formatLocation($profile)));
} }
if ($profile['pub_keywords']) { if ($profile['pub_keywords']) {
@ -372,10 +374,28 @@ class Profile extends BaseProfile
*/ */
private function tryRelMe(string $input): string private function tryRelMe(string $input): string
{ {
if (preg_match(Strings::onlyLinkRegEx(), trim($input))) { $input = trim($input);
return '<a href="' . trim($input) . '" target="_blank" rel="noopener noreferrer me">' . trim($input) . '</a>'; if (Network::isValidHttpUrl($input)) {
try {
$input = (string)Uri::fromParts(parse_url($input));
return '<a href="' . $input . '" target="_blank" rel="noopener noreferrer me">' . $input . '</a>';
} catch (\Throwable $th) {
return '';
}
} }
return ''; return '';
} }
/**
* Clean the provided input to prevent XSS problems
* @param int $uri_id
* @param string $input
* @return string
* @throws InternalServerErrorException
*/
private function cleanInput(int $uri_id, string $input): string
{
return BBCode::convertForUriId($uri_id, HTML::toBBCode($input));
}
} }