mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Move url sanitisation out of Element class
This commit is contained in:
parent
a681cf631c
commit
41fb6b0d43
@ -8,6 +8,7 @@ use Erusev\Parsedown\Components\Inline;
|
|||||||
use Erusev\Parsedown\Configurables\SafeMode;
|
use Erusev\Parsedown\Configurables\SafeMode;
|
||||||
use Erusev\Parsedown\Html\Renderables\Element;
|
use Erusev\Parsedown\Html\Renderables\Element;
|
||||||
use Erusev\Parsedown\Html\Renderables\Text;
|
use Erusev\Parsedown\Html\Renderables\Text;
|
||||||
|
use Erusev\Parsedown\Html\Sanitisation\UrlSanitiser;
|
||||||
use Erusev\Parsedown\Parsedown;
|
use Erusev\Parsedown\Parsedown;
|
||||||
use Erusev\Parsedown\Parsing\Excerpt;
|
use Erusev\Parsedown\Parsing\Excerpt;
|
||||||
use Erusev\Parsedown\State;
|
use Erusev\Parsedown\State;
|
||||||
@ -84,7 +85,7 @@ final class Image implements Inline
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($State->get(SafeMode::class)->isEnabled()) {
|
if ($State->get(SafeMode::class)->isEnabled()) {
|
||||||
$attributes['src'] = Element::filterUnsafeUrl($attributes['src']);
|
$attributes['src'] = UrlSanitiser::filter($attributes['src']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Element::selfClosing('img', $attributes);
|
return Element::selfClosing('img', $attributes);
|
||||||
|
@ -10,6 +10,7 @@ use Erusev\Parsedown\Configurables\InlineTypes;
|
|||||||
use Erusev\Parsedown\Configurables\SafeMode;
|
use Erusev\Parsedown\Configurables\SafeMode;
|
||||||
use Erusev\Parsedown\Html\Renderables\Element;
|
use Erusev\Parsedown\Html\Renderables\Element;
|
||||||
use Erusev\Parsedown\Html\Renderables\Text;
|
use Erusev\Parsedown\Html\Renderables\Text;
|
||||||
|
use Erusev\Parsedown\Html\Sanitisation\UrlSanitiser;
|
||||||
use Erusev\Parsedown\Parsedown;
|
use Erusev\Parsedown\Parsedown;
|
||||||
use Erusev\Parsedown\Parsing\Excerpt;
|
use Erusev\Parsedown\Parsing\Excerpt;
|
||||||
use Erusev\Parsedown\State;
|
use Erusev\Parsedown\State;
|
||||||
@ -124,7 +125,7 @@ final class Link implements Inline
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($State->get(SafeMode::class)->isEnabled()) {
|
if ($State->get(SafeMode::class)->isEnabled()) {
|
||||||
$attributes['href'] = Element::filterUnsafeUrl($attributes['href']);
|
$attributes['href'] = UrlSanitiser::filter($attributes['href']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$State = $State->setting(
|
$State = $State->setting(
|
||||||
|
@ -62,25 +62,6 @@ final class Element implements Renderable
|
|||||||
'basefont' => true,
|
'basefont' => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var string[] */
|
|
||||||
public static $COMMON_SCHEMES = [
|
|
||||||
'http://',
|
|
||||||
'https://',
|
|
||||||
'ftp://',
|
|
||||||
'ftps://',
|
|
||||||
'mailto:',
|
|
||||||
'tel:',
|
|
||||||
'data:image/png;base64,',
|
|
||||||
'data:image/gif;base64,',
|
|
||||||
'data:image/jpeg;base64,',
|
|
||||||
'irc:',
|
|
||||||
'ircs:',
|
|
||||||
'git:',
|
|
||||||
'ssh:',
|
|
||||||
'news:',
|
|
||||||
'steam:',
|
|
||||||
];
|
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@ -224,40 +205,4 @@ final class Element implements Renderable
|
|||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $url
|
|
||||||
* @param string[]|null $permittedSchemes
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function filterUnsafeUrl($url, $permittedSchemes = null)
|
|
||||||
{
|
|
||||||
if (! isset($permittedSchemes)) {
|
|
||||||
$permittedSchemes = self::$COMMON_SCHEMES;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($permittedSchemes as $scheme) {
|
|
||||||
if (self::striAtStart($url, $scheme)) {
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return \str_replace(':', '%3A', $url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $string
|
|
||||||
* @param string $needle
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private static function striAtStart($string, $needle)
|
|
||||||
{
|
|
||||||
$len = \strlen($needle);
|
|
||||||
|
|
||||||
if ($len > \strlen($string)) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return \strtolower(\substr($string, 0, $len)) === \strtolower($needle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
63
src/Html/Sanitisation/UrlSanitiser.php
Normal file
63
src/Html/Sanitisation/UrlSanitiser.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Erusev\Parsedown\Html\Sanitisation;
|
||||||
|
|
||||||
|
final class UrlSanitiser
|
||||||
|
{
|
||||||
|
/** @var string[] */
|
||||||
|
private static $COMMON_SCHEMES = [
|
||||||
|
'http://',
|
||||||
|
'https://',
|
||||||
|
'ftp://',
|
||||||
|
'ftps://',
|
||||||
|
'mailto:',
|
||||||
|
'tel:',
|
||||||
|
'data:image/png;base64,',
|
||||||
|
'data:image/gif;base64,',
|
||||||
|
'data:image/jpeg;base64,',
|
||||||
|
'irc:',
|
||||||
|
'ircs:',
|
||||||
|
'git:',
|
||||||
|
'ssh:',
|
||||||
|
'news:',
|
||||||
|
'steam:',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable literal intepretation of unknown scheme in $url. Returns the
|
||||||
|
* filtered version of $url.
|
||||||
|
* @param string $url
|
||||||
|
* @param string[]|null $permittedSchemes
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function filter($url, $permittedSchemes = null)
|
||||||
|
{
|
||||||
|
if (! isset($permittedSchemes)) {
|
||||||
|
$permittedSchemes = self::$COMMON_SCHEMES;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($permittedSchemes as $scheme) {
|
||||||
|
if (self::striAtStart($url, $scheme)) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return \str_replace(':', '%3A', $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $string
|
||||||
|
* @param string $needle
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function striAtStart($string, $needle)
|
||||||
|
{
|
||||||
|
$len = \strlen($needle);
|
||||||
|
|
||||||
|
if ($len > \strlen($string)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return \strtolower(\substr($string, 0, $len)) === \strtolower($needle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user