mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
6678d59be4 | |||
c999a4b61b | |||
e938ab4ffe | |||
e69374af0d | |||
1196ed9512 | |||
1244122b84 | |||
d98d60aaf3 | |||
296ebf0e60 | |||
a60ba300b1 | |||
089789dfff | |||
fbe3fe878f | |||
09827f542c | |||
70ef6f5521 | |||
691e36b1f2 | |||
af6affdc2c | |||
9cf41f27ab | |||
16aadff2ed | |||
07c937583d | |||
67c3efbea0 | |||
bbb7687f31 | |||
b1e5aebaf6 | |||
c63b690a79 | |||
226f636360 | |||
2e4afde68d | |||
dc30cb441c | |||
054ba3c487 | |||
4bae1c9834 | |||
aee3963e6b | |||
4dc98b635d | |||
e4bb12329e | |||
6d0156d707 | |||
131ba75851 | |||
af04ac92e2 | |||
6bb66db00f | |||
b3d45c4bb9 | |||
1d4296f34d | |||
bf5105cb1a | |||
1140613fc7 | |||
1a44cbd62c |
29
.travis.yml
29
.travis.yml
@ -1,18 +1,27 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
dist: trusty
|
||||||
- 7.1
|
sudo: false
|
||||||
- 7.0
|
|
||||||
- 5.6
|
|
||||||
- 5.5
|
|
||||||
- 5.4
|
|
||||||
- 5.3
|
|
||||||
- hhvm
|
|
||||||
- nightly
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
include:
|
||||||
|
- php: 5.3
|
||||||
|
dist: precise
|
||||||
|
- php: 5.4
|
||||||
|
- php: 5.5
|
||||||
|
- php: 5.6
|
||||||
|
- php: 7.0
|
||||||
|
- php: 7.1
|
||||||
|
- php: nightly
|
||||||
|
- php: hhvm
|
||||||
|
- php: hhvm-nightly
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: nightly
|
- php: nightly
|
||||||
|
- php: hhvm-nightly
|
||||||
|
|
||||||
sudo: false
|
before_script:
|
||||||
|
- composer install --prefer-dist --no-interaction --no-progress
|
||||||
|
|
||||||
|
script:
|
||||||
|
- vendor/bin/phpunit
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 Emanuil Rusev, erusev.com
|
Copyright (c) 2013-2018 Emanuil Rusev, erusev.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
133
Parsedown.php
133
Parsedown.php
@ -75,6 +75,32 @@ class Parsedown
|
|||||||
|
|
||||||
protected $urlsLinked = true;
|
protected $urlsLinked = true;
|
||||||
|
|
||||||
|
function setSafeMode($safeMode)
|
||||||
|
{
|
||||||
|
$this->safeMode = (bool) $safeMode;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $safeMode;
|
||||||
|
|
||||||
|
protected $safeLinksWhitelist = array(
|
||||||
|
'http://',
|
||||||
|
'https://',
|
||||||
|
'ftp://',
|
||||||
|
'ftps://',
|
||||||
|
'mailto:',
|
||||||
|
'data:image/png;base64,',
|
||||||
|
'data:image/gif;base64,',
|
||||||
|
'data:image/jpeg;base64,',
|
||||||
|
'irc:',
|
||||||
|
'ircs:',
|
||||||
|
'git:',
|
||||||
|
'ssh:',
|
||||||
|
'news:',
|
||||||
|
'steam:',
|
||||||
|
);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Lines
|
# Lines
|
||||||
#
|
#
|
||||||
@ -342,8 +368,6 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$text = $Block['element']['text']['text'];
|
$text = $Block['element']['text']['text'];
|
||||||
|
|
||||||
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
|
|
||||||
|
|
||||||
$Block['element']['text']['text'] = $text;
|
$Block['element']['text']['text'] = $text;
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
@ -354,7 +378,7 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockComment($Line)
|
protected function blockComment($Line)
|
||||||
{
|
{
|
||||||
if ($this->markupEscaped)
|
if ($this->markupEscaped or $this->safeMode)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -457,8 +481,6 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$text = $Block['element']['text']['text'];
|
$text = $Block['element']['text']['text'];
|
||||||
|
|
||||||
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
|
|
||||||
|
|
||||||
$Block['element']['text']['text'] = $text;
|
$Block['element']['text']['text'] = $text;
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
@ -515,10 +537,10 @@ class Parsedown
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if($name === 'ol')
|
if($name === 'ol')
|
||||||
{
|
{
|
||||||
$listStart = stristr($matches[0], '.', true);
|
$listStart = stristr($matches[0], '.', true);
|
||||||
|
|
||||||
if($listStart !== '1')
|
if($listStart !== '1')
|
||||||
{
|
{
|
||||||
$Block['element']['attributes'] = array('start' => $listStart);
|
$Block['element']['attributes'] = array('start' => $listStart);
|
||||||
@ -678,12 +700,12 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockMarkup($Line)
|
protected function blockMarkup($Line)
|
||||||
{
|
{
|
||||||
if ($this->markupEscaped)
|
if ($this->markupEscaped or $this->safeMode)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
|
if (preg_match('/^<(\w[\w-]*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
|
||||||
{
|
{
|
||||||
$element = strtolower($matches[1]);
|
$element = strtolower($matches[1]);
|
||||||
|
|
||||||
@ -1074,7 +1096,6 @@ class Parsedown
|
|||||||
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
|
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
$text = $matches[2];
|
$text = $matches[2];
|
||||||
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
|
|
||||||
$text = preg_replace("/[ ]*\n/", ' ', $text);
|
$text = preg_replace("/[ ]*\n/", ' ', $text);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
@ -1253,8 +1274,6 @@ class Parsedown
|
|||||||
$Element['attributes']['title'] = $Definition['title'];
|
$Element['attributes']['title'] = $Definition['title'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']);
|
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'extent' => $extent,
|
'extent' => $extent,
|
||||||
'element' => $Element,
|
'element' => $Element,
|
||||||
@ -1263,12 +1282,12 @@ class Parsedown
|
|||||||
|
|
||||||
protected function inlineMarkup($Excerpt)
|
protected function inlineMarkup($Excerpt)
|
||||||
{
|
{
|
||||||
if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
|
if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'markup' => $matches[0],
|
'markup' => $matches[0],
|
||||||
@ -1284,7 +1303,7 @@ class Parsedown
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'markup' => $matches[0],
|
'markup' => $matches[0],
|
||||||
@ -1343,14 +1362,16 @@ class Parsedown
|
|||||||
|
|
||||||
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
|
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
|
||||||
{
|
{
|
||||||
|
$url = $matches[0][0];
|
||||||
|
|
||||||
$Inline = array(
|
$Inline = array(
|
||||||
'extent' => strlen($matches[0][0]),
|
'extent' => strlen($matches[0][0]),
|
||||||
'position' => $matches[0][1],
|
'position' => $matches[0][1],
|
||||||
'element' => array(
|
'element' => array(
|
||||||
'name' => 'a',
|
'name' => 'a',
|
||||||
'text' => $matches[0][0],
|
'text' => $url,
|
||||||
'attributes' => array(
|
'attributes' => array(
|
||||||
'href' => $matches[0][0],
|
'href' => $url,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -1363,7 +1384,7 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
|
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
$url = str_replace(array('&', '<'), array('&', '<'), $matches[1]);
|
$url = $matches[1];
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'extent' => strlen($matches[0]),
|
'extent' => strlen($matches[0]),
|
||||||
@ -1401,6 +1422,11 @@ class Parsedown
|
|||||||
|
|
||||||
protected function element(array $Element)
|
protected function element(array $Element)
|
||||||
{
|
{
|
||||||
|
if ($this->safeMode)
|
||||||
|
{
|
||||||
|
$Element = $this->sanitiseElement($Element);
|
||||||
|
}
|
||||||
|
|
||||||
$markup = '<'.$Element['name'];
|
$markup = '<'.$Element['name'];
|
||||||
|
|
||||||
if (isset($Element['attributes']))
|
if (isset($Element['attributes']))
|
||||||
@ -1412,7 +1438,7 @@ class Parsedown
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$markup .= ' '.$name.'="'.$value.'"';
|
$markup .= ' '.$name.'="'.self::escape($value).'"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1426,7 +1452,7 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$markup .= $Element['text'];
|
$markup .= self::escape($Element['text'], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$markup .= '</'.$Element['name'].'>';
|
$markup .= '</'.$Element['name'].'>';
|
||||||
@ -1485,10 +1511,77 @@ class Parsedown
|
|||||||
return $markup;
|
return $markup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function sanitiseElement(array $Element)
|
||||||
|
{
|
||||||
|
static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/';
|
||||||
|
static $safeUrlNameToAtt = array(
|
||||||
|
'a' => 'href',
|
||||||
|
'img' => 'src',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($safeUrlNameToAtt[$Element['name']]))
|
||||||
|
{
|
||||||
|
$Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty($Element['attributes']))
|
||||||
|
{
|
||||||
|
foreach ($Element['attributes'] as $att => $val)
|
||||||
|
{
|
||||||
|
# filter out badly parsed attribute
|
||||||
|
if ( ! preg_match($goodAttribute, $att))
|
||||||
|
{
|
||||||
|
unset($Element['attributes'][$att]);
|
||||||
|
}
|
||||||
|
# dump onevent attribute
|
||||||
|
elseif (self::striAtStart($att, 'on'))
|
||||||
|
{
|
||||||
|
unset($Element['attributes'][$att]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterUnsafeUrlInAttribute(array $Element, $attribute)
|
||||||
|
{
|
||||||
|
foreach ($this->safeLinksWhitelist as $scheme)
|
||||||
|
{
|
||||||
|
if (self::striAtStart($Element['attributes'][$attribute], $scheme))
|
||||||
|
{
|
||||||
|
return $Element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]);
|
||||||
|
|
||||||
|
return $Element;
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Static Methods
|
# Static Methods
|
||||||
#
|
#
|
||||||
|
|
||||||
|
protected static function escape($text, $allowQuotes = false)
|
||||||
|
{
|
||||||
|
return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function striAtStart($string, $needle)
|
||||||
|
{
|
||||||
|
$len = strlen($needle);
|
||||||
|
|
||||||
|
if ($len > strlen($string))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return strtolower(substr($string, 0, $len)) === strtolower($needle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static function instance($name = 'default')
|
static function instance($name = 'default')
|
||||||
{
|
{
|
||||||
if (isset(self::$instances[$name]))
|
if (isset(self::$instances[$name]))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
> You might also like [Caret](https://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux.
|
> I also make [Caret](https://caret.io?ref=parsedown) - a Markdown editor for Mac and PC.
|
||||||
|
|
||||||
## Parsedown
|
## Parsedown
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ Better Markdown Parser in PHP
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* One File
|
* One File
|
||||||
|
* No Dependencies
|
||||||
* Super Fast
|
* Super Fast
|
||||||
* Extensible
|
* Extensible
|
||||||
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
||||||
@ -35,6 +36,10 @@ echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</e
|
|||||||
|
|
||||||
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
|
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
Parsedown does not sanitize the HTML that it generates. When you deal with untrusted content (ex: user comments) you should also use a HTML sanitizer like [HTML Purifier](http://htmlpurifier.org/).
|
||||||
|
|
||||||
### Questions
|
### Questions
|
||||||
|
|
||||||
**How does Parsedown work?**
|
**How does Parsedown work?**
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"php": ">=5.3.0"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.35"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {"Parsedown": ""}
|
"psr-0": {"Parsedown": ""}
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,4 @@
|
|||||||
<file>test/ParsedownTest.php</file>
|
<file>test/ParsedownTest.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
@ -8,7 +8,10 @@
|
|||||||
* @link http://commonmark.org/ CommonMark
|
* @link http://commonmark.org/ CommonMark
|
||||||
* @link http://git.io/8WtRvQ JavaScript test runner
|
* @link http://git.io/8WtRvQ JavaScript test runner
|
||||||
*/
|
*/
|
||||||
class CommonMarkTest extends PHPUnit_Framework_TestCase
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class CommonMarkTest extends TestCase
|
||||||
{
|
{
|
||||||
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/stmd/master/spec.txt';
|
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/stmd/master/spec.txt';
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class ParsedownTest extends PHPUnit_Framework_TestCase
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ParsedownTest extends TestCase
|
||||||
{
|
{
|
||||||
final function __construct($name = null, array $data = array(), $dataName = '')
|
final function __construct($name = null, array $data = array(), $dataName = '')
|
||||||
{
|
{
|
||||||
@ -46,6 +48,8 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
|||||||
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
|
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
|
||||||
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
|
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
|
||||||
|
|
||||||
|
$this->Parsedown->setSafeMode(substr($test, 0, 3) === 'xss');
|
||||||
|
|
||||||
$actualMarkup = $this->Parsedown->text($markdown);
|
$actualMarkup = $this->Parsedown->text($markdown);
|
||||||
|
|
||||||
$this->assertEquals($expectedMarkup, $actualMarkup);
|
$this->assertEquals($expectedMarkup, $actualMarkup);
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
include 'Parsedown.php';
|
include 'Parsedown.php';
|
||||||
|
|
||||||
if ( ! class_exists('\PHPUnit_Framework_TestCase')) {
|
|
||||||
class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
|
|
||||||
}
|
|
||||||
|
6
test/data/xss_attribute_encoding.html
Normal file
6
test/data/xss_attribute_encoding.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<p><a href="https://www.example.com"">xss</a></p>
|
||||||
|
<p><img src="https://www.example.com"" alt="xss" /></p>
|
||||||
|
<p><a href="https://www.example.com'">xss</a></p>
|
||||||
|
<p><img src="https://www.example.com'" alt="xss" /></p>
|
||||||
|
<p><img src="https://www.example.com" alt="xss"" /></p>
|
||||||
|
<p><img src="https://www.example.com" alt="xss'" /></p>
|
11
test/data/xss_attribute_encoding.md
Normal file
11
test/data/xss_attribute_encoding.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[xss](https://www.example.com")
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
[xss](https://www.example.com')
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
16
test/data/xss_bad_url.html
Normal file
16
test/data/xss_bad_url.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<p><a href="javascript%3Aalert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript%3Aalert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript%3A//alert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript&colon;alert(1)">xss</a></p>
|
||||||
|
<p><img src="javascript%3Aalert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript%3Aalert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript%3A//alert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript&colon;alert(1)" alt="xss" /></p>
|
||||||
|
<p><a href="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data%3A//text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><img src="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data%3A//text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
31
test/data/xss_bad_url.md
Normal file
31
test/data/xss_bad_url.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[xss](javascript:alert(1))
|
||||||
|
|
||||||
|
[xss]( javascript:alert(1))
|
||||||
|
|
||||||
|
[xss](javascript://alert(1))
|
||||||
|
|
||||||
|
[xss](javascript:alert(1))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
[xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss]( data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss](data://text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
7
test/data/xss_text_encoding.html
Normal file
7
test/data/xss_text_encoding.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<p><script>alert(1)</script></p>
|
||||||
|
<p><script></p>
|
||||||
|
<p>alert(1)</p>
|
||||||
|
<p></script></p>
|
||||||
|
<p><script>
|
||||||
|
alert(1)
|
||||||
|
</script></p>
|
12
test/data/xss_text_encoding.md
Normal file
12
test/data/xss_text_encoding.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>alert(1)</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
alert(1)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
alert(1)
|
||||||
|
</script>
|
Reference in New Issue
Block a user