aboutsummaryrefslogtreecommitdiffhomepage
path: root/plugins
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2017-02-27 19:45:55 +0100
committerArthurHoaro <arthur@hoa.ro>2017-02-28 19:16:54 +0100
commite03761011521929a375ebb56f21adacb226a3a8d (patch)
tree6cc318939e74a35d74a037f18bca912b73e5c81e /plugins
parent5978588578ca103152598ccfbe41019b12e00a4f (diff)
downloadShaarli-e03761011521929a375ebb56f21adacb226a3a8d.tar.gz
Shaarli-e03761011521929a375ebb56f21adacb226a3a8d.tar.zst
Shaarli-e03761011521929a375ebb56f21adacb226a3a8d.zip
Add markdown_escape setting
This setting allows to escape HTML in markdown rendering or not. The goal behind it is to avoid XSS issue in shared instances. More info: * the setting is set to true by default * it is set to false for anyone who already have the plugin enabled (avoid breaking existing entries) * improve the HTML sanitization when the setting is set to false - but don't consider it XSS proof * mention the setting in the plugin README
Diffstat (limited to 'plugins')
-rw-r--r--plugins/markdown/README.md27
-rw-r--r--plugins/markdown/markdown.php29
2 files changed, 38 insertions, 18 deletions
diff --git a/plugins/markdown/README.md b/plugins/markdown/README.md
index aafcf066..bc9427e2 100644
--- a/plugins/markdown/README.md
+++ b/plugins/markdown/README.md
@@ -50,9 +50,20 @@ If the tag `nomarkdown` is set for a shaare, it won't be converted to Markdown s
50 50
51> Note: this is a special tag, so it won't be displayed in link list. 51> Note: this is a special tag, so it won't be displayed in link list.
52 52
53### HTML rendering 53### HTML escape
54 54
55Markdown support HTML tags. For example: 55By default, HTML tags are escaped. You can enable HTML tags rendering
56by setting `security.markdwon_escape` to `false` in `data/config.json.php`:
57
58```json
59{
60 "security": {
61 "markdown_escape": false
62 }
63}
64```
65
66With this setting, Markdown support HTML tags. For example:
56 67
57 > <strong>strong</strong><strike>strike</strike> 68 > <strong>strong</strong><strike>strike</strike>
58 69
@@ -60,12 +71,14 @@ Will render as:
60 71
61> <strong>strong</strong><strike>strike</strike> 72> <strong>strong</strong><strike>strike</strike>
62 73
63If you want to shaare HTML code, it is necessary to use inline code or code blocks.
64
65**If your shaared descriptions containing HTML tags before enabling the markdown plugin,
66enabling it might break your page.**
67 74
68> Note: HTML tags such as script, iframe, etc. are disabled for security reasons. 75**Warning:**
76
77 * This setting might present **security risks** (XSS) on shared instances, even though tags
78 such as script, iframe, etc should be disabled.
79 * If you want to shaare HTML code, it is necessary to use inline code or code blocks.
80 * If your shaared descriptions contained HTML tags before enabling the markdown plugin,
81enabling it might break your page.
69 82
70### Known issue 83### Known issue
71 84
diff --git a/plugins/markdown/markdown.php b/plugins/markdown/markdown.php
index 0cf6e6e2..de7c823d 100644
--- a/plugins/markdown/markdown.php
+++ b/plugins/markdown/markdown.php
@@ -14,18 +14,19 @@ define('NO_MD_TAG', 'nomarkdown');
14/** 14/**
15 * Parse linklist descriptions. 15 * Parse linklist descriptions.
16 * 16 *
17 * @param array $data linklist data. 17 * @param array $data linklist data.
18 * @param ConfigManager $conf instance.
18 * 19 *
19 * @return mixed linklist data parsed in markdown (and converted to HTML). 20 * @return mixed linklist data parsed in markdown (and converted to HTML).
20 */ 21 */
21function hook_markdown_render_linklist($data) 22function hook_markdown_render_linklist($data, $conf)
22{ 23{
23 foreach ($data['links'] as &$value) { 24 foreach ($data['links'] as &$value) {
24 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) { 25 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
25 $value = stripNoMarkdownTag($value); 26 $value = stripNoMarkdownTag($value);
26 continue; 27 continue;
27 } 28 }
28 $value['description'] = process_markdown($value['description']); 29 $value['description'] = process_markdown($value['description'], $conf->get('security.markdown_escape', true));
29 } 30 }
30 return $data; 31 return $data;
31} 32}
@@ -34,17 +35,18 @@ function hook_markdown_render_linklist($data)
34 * Parse feed linklist descriptions. 35 * Parse feed linklist descriptions.
35 * 36 *
36 * @param array $data linklist data. 37 * @param array $data linklist data.
38 * @param ConfigManager $conf instance.
37 * 39 *
38 * @return mixed linklist data parsed in markdown (and converted to HTML). 40 * @return mixed linklist data parsed in markdown (and converted to HTML).
39 */ 41 */
40function hook_markdown_render_feed($data) 42function hook_markdown_render_feed($data, $conf)
41{ 43{
42 foreach ($data['links'] as &$value) { 44 foreach ($data['links'] as &$value) {
43 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) { 45 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
44 $value = stripNoMarkdownTag($value); 46 $value = stripNoMarkdownTag($value);
45 continue; 47 continue;
46 } 48 }
47 $value['description'] = process_markdown($value['description']); 49 $value['description'] = process_markdown($value['description'], $conf->get('security.markdown_escape', true));
48 } 50 }
49 51
50 return $data; 52 return $data;
@@ -53,11 +55,12 @@ function hook_markdown_render_feed($data)
53/** 55/**
54 * Parse daily descriptions. 56 * Parse daily descriptions.
55 * 57 *
56 * @param array $data daily data. 58 * @param array $data daily data.
59 * @param ConfigManager $conf instance.
57 * 60 *
58 * @return mixed daily data parsed in markdown (and converted to HTML). 61 * @return mixed daily data parsed in markdown (and converted to HTML).
59 */ 62 */
60function hook_markdown_render_daily($data) 63function hook_markdown_render_daily($data, $conf)
61{ 64{
62 // Manipulate columns data 65 // Manipulate columns data
63 foreach ($data['cols'] as &$value) { 66 foreach ($data['cols'] as &$value) {
@@ -66,7 +69,10 @@ function hook_markdown_render_daily($data)
66 $value2 = stripNoMarkdownTag($value2); 69 $value2 = stripNoMarkdownTag($value2);
67 continue; 70 continue;
68 } 71 }
69 $value2['formatedDescription'] = process_markdown($value2['formatedDescription']); 72 $value2['formatedDescription'] = process_markdown(
73 $value2['formatedDescription'],
74 $conf->get('security.markdown_escape', true)
75 );
70 } 76 }
71 } 77 }
72 78
@@ -250,7 +256,7 @@ function sanitize_html($description)
250 $description); 256 $description);
251 } 257 }
252 $description = preg_replace( 258 $description = preg_replace(
253 '#(<[^>]+)on[a-z]*="[^"]*"#is', 259 '#(<[^>]+)on[a-z]*="?[^ "]*"?#is',
254 '$1', 260 '$1',
255 $description); 261 $description);
256 return $description; 262 return $description;
@@ -265,10 +271,11 @@ function sanitize_html($description)
265 * 5. Wrap description in 'markdown' CSS class. 271 * 5. Wrap description in 'markdown' CSS class.
266 * 272 *
267 * @param string $description input description text. 273 * @param string $description input description text.
274 * @param bool $escape escape HTML entities
268 * 275 *
269 * @return string HTML processed $description. 276 * @return string HTML processed $description.
270 */ 277 */
271function process_markdown($description) 278function process_markdown($description, $escape = true)
272{ 279{
273 $parsedown = new Parsedown(); 280 $parsedown = new Parsedown();
274 281
@@ -278,7 +285,7 @@ function process_markdown($description)
278 $processedDescription = reverse_text2clickable($processedDescription); 285 $processedDescription = reverse_text2clickable($processedDescription);
279 $processedDescription = unescape($processedDescription); 286 $processedDescription = unescape($processedDescription);
280 $processedDescription = $parsedown 287 $processedDescription = $parsedown
281 ->setMarkupEscaped(false) 288 ->setMarkupEscaped($escape)
282 ->setBreaksEnabled(true) 289 ->setBreaksEnabled(true)
283 ->text($processedDescription); 290 ->text($processedDescription);
284 $processedDescription = sanitize_html($processedDescription); 291 $processedDescription = sanitize_html($processedDescription);