Issue 13884: Sanitation of links in BBCode parser
This commit is contained in:
parent
2cc8fcc4aa
commit
96ede22abb
1 changed files with 49 additions and 0 deletions
|
@ -434,6 +434,8 @@ class BBCode
|
|||
return $text;
|
||||
}
|
||||
|
||||
$data['url'] = self::sanitizedLink($data['url']);
|
||||
|
||||
if (isset($data['title'])) {
|
||||
$data['title'] = strip_tags($data['title']);
|
||||
$data['title'] = str_replace(['http://', 'https://'], '', $data['title']);
|
||||
|
@ -485,6 +487,7 @@ class BBCode
|
|||
}
|
||||
|
||||
if (!empty($data['provider_url']) && !empty($data['provider_name'])) {
|
||||
$data['provider_url'] = self::sanitizedLink($data['provider_url']);
|
||||
if (!empty($data['author_name'])) {
|
||||
$return .= sprintf('<sup><a href="%s" target="_blank" rel="noopener noreferrer">%s (%s)</a></sup>', $data['provider_url'], $data['author_name'], $data['provider_name']);
|
||||
} else {
|
||||
|
@ -1064,6 +1067,44 @@ class BBCode
|
|||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove invalid parts from an URL
|
||||
*
|
||||
* @param string $url
|
||||
* @return string sanitized URL
|
||||
*/
|
||||
private static function sanitizedLink(string $url): string
|
||||
{
|
||||
$sanitzed = $url = trim($url);
|
||||
|
||||
foreach (['"', ' '] as $character) {
|
||||
$pos = strpos($sanitzed, $character);
|
||||
if ($pos !== false) {
|
||||
$sanitzed = trim(substr($sanitzed, 0, $pos));
|
||||
}
|
||||
}
|
||||
|
||||
if ($sanitzed != $url) {
|
||||
Logger::debug('Link got sanitized', ['url' => $url, 'sanitzed' => $sanitzed]);
|
||||
}
|
||||
return $sanitzed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback: Sanitize links from given $match array
|
||||
*
|
||||
* @param array $match Array with link match
|
||||
* @return string BBCode
|
||||
*/
|
||||
private static function sanitizeLinksCallback(array $match): string
|
||||
{
|
||||
if (count($match) == 3) {
|
||||
return '[' . $match[1] . ']' . self::sanitizedLink($match[2]) . '[/' . $match[1] . ']';
|
||||
} else {
|
||||
return '[' . $match[1] . '=' . self::sanitizedLink($match[2]) . ']' . $match[3] . '[/' . $match[1] . ']';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback: Expands links from given $match array
|
||||
*
|
||||
|
@ -1717,6 +1758,9 @@ class BBCode
|
|||
// Simplify "video" element
|
||||
$text = preg_replace('(\[video[^\]]*?\ssrc\s?=\s?([^\s\]]+)[^\]]*?\].*?\[/video\])ism', '[video]$1[/video]', $text);
|
||||
|
||||
$text = preg_replace_callback("/\[(video)\](.*?)\[\/video\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
$text = preg_replace_callback("/\[(audio)\](.*?)\[\/audio\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
|
||||
if ($simple_html == self::NPF) {
|
||||
$text = preg_replace(
|
||||
"/\[video\](.*?)\[\/video\]/ism",
|
||||
|
@ -1759,6 +1803,7 @@ class BBCode
|
|||
}
|
||||
|
||||
// Backward compatibility, [iframe] support has been removed in version 2020.12
|
||||
$text = preg_replace_callback("/\[(iframe)\](.*?)\[\/iframe\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
$text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $text);
|
||||
|
||||
$text = self::normalizeVideoLinks($text);
|
||||
|
@ -1811,6 +1856,9 @@ class BBCode
|
|||
$text = '<span style="font-size: xx-large; line-height: normal;">' . $text . '</span>';
|
||||
}
|
||||
|
||||
$text = preg_replace_callback("/\[(url)\](.*?)\[\/url\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
$text = preg_replace_callback("/\[(url)\=(.*?)\](.*?)\[\/url\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
|
||||
// Handle mentions and hashtag links
|
||||
if ($simple_html == self::DIASPORA) {
|
||||
// The ! is converted to @ since Diaspora only understands the @
|
||||
|
@ -1944,6 +1992,7 @@ class BBCode
|
|||
$text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', '<a href="' . DI::baseUrl() . '/acctlink?addr=$1@$2" target="extlink">acct:$1@$2</a>', $text);
|
||||
|
||||
// Perform MAIL Search
|
||||
$text = preg_replace_callback("/\[(mail)\](.*?)\[\/mail\]/ism", [self::class, 'sanitizeLinksCallback'], $text);
|
||||
$text = preg_replace("/\[mail\](.*?)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $text);
|
||||
$text = preg_replace("/\[mail\=(.*?)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $text);
|
||||
|
||||
|
|
Loading…
Reference in a new issue