From ada0d779eedf959f714490934d23a395e4560a32 Mon Sep 17 00:00:00 2001 From: Michael Hamann <michael@content-space.de> Date: Sun, 15 Apr 2018 13:20:59 +0200 Subject: [PATCH] Prevent HTML and JS injection in section names Before this change, HTML and some JS code (as far as it was not escaped by json_encode) could be injected into the output as the closing pattern that is checked by the regex is not escaped in JSON (see test case). --- _test/tests/inc/html_secedit_pattern.test.php | 11 +++++++++++ inc/html.php | 3 ++- inc/parser/xhtml.php | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/_test/tests/inc/html_secedit_pattern.test.php b/_test/tests/inc/html_secedit_pattern.test.php index ca1615885..fd703996f 100644 --- a/_test/tests/inc/html_secedit_pattern.test.php +++ b/_test/tests/inc/html_secedit_pattern.test.php @@ -56,4 +56,15 @@ class html_scedit_pattern_test extends DokuWikiTest { } } + public function testSecEditHTMLInjection() { + $ins = p_get_instructions("====== Foo ======\n\n===== } --> <script> =====\n\n===== Bar =====\n"); + $info = array(); + $xhtml = p_render('xhtml', $ins, $info); + + $this->assertNotNull($xhtml); + + $xhtml_without_secedit = html_secedit($xhtml, false); + + $this->assertFalse(strpos($xhtml_without_secedit, '<script>'), 'Plain <script> tag found in output - HTML/JS injection might be possible!'); + } } diff --git a/inc/html.php b/inc/html.php index 11a204eb8..a096102dc 100644 --- a/inc/html.php +++ b/inc/html.php @@ -118,7 +118,8 @@ function html_secedit($text,$show=true){ * @triggers HTML_SECEDIT_BUTTON */ function html_secedit_button($matches){ - $data = json_decode($matches[1], true); + $json = htmlspecialchars_decode($matches[1], ENT_QUOTES); + $data = json_decode($json, true); if ($data == NULL) { return; } diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index df436e0e6..a1ce1fce0 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -103,7 +103,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } $data['range'] = $data['start'].'-'.(is_null($end) ? '' : $end); unset($data['start']); - $this->doc .= '<!-- EDIT'.json_encode ($data).' -->'; + $this->doc .= '<!-- EDIT'.hsc(json_encode ($data)).' -->'; } /** -- GitLab