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