From 86ceea054f5f85157b04473bac5bfb6ff86ca31f Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Thu, 25 May 2017 14:52:42 +0200
Subject: Add a whitelist of protocols for URLs

 - for Shaare
 - for markdown description links and images

Not whitelisted protocols will be replaced by `http://`
---
 tests/Url/WhitelistProtocolsTest.php  | 63 +++++++++++++++++++++++++++++++++++
 tests/plugins/PluginMarkdownTest.php  | 11 ++++--
 tests/plugins/resources/markdown.html | 11 +++++-
 tests/plugins/resources/markdown.md   | 12 ++++++-
 4 files changed, 92 insertions(+), 5 deletions(-)
 create mode 100644 tests/Url/WhitelistProtocolsTest.php

(limited to 'tests')

diff --git a/tests/Url/WhitelistProtocolsTest.php b/tests/Url/WhitelistProtocolsTest.php
new file mode 100644
index 00000000..a3156804
--- /dev/null
+++ b/tests/Url/WhitelistProtocolsTest.php
@@ -0,0 +1,63 @@
+<?php
+
+require_once 'application/Url.php';
+
+use Shaarli\Config\ConfigManager;
+
+/**
+ * Class WhitelistProtocolsTest
+ *
+ * Test whitelist_protocols() function of Url.
+ */
+class WhitelistProtocolsTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test whitelist_protocols() on a note (relative URL).
+     */
+    public function testWhitelistProtocolsRelative()
+    {
+        $whitelist = ['ftp', 'magnet'];
+        $url = '?12443564';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+        $url = '/path.jpg';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+    }
+
+    /**
+     * Test whitelist_protocols() on a note (relative URL).
+     */
+    public function testWhitelistProtocolMissing()
+    {
+        $whitelist = ['ftp', 'magnet'];
+        $url = 'test.tld/path/?query=value#hash';
+        $this->assertEquals('http://'. $url, whitelist_protocols($url, $whitelist));
+    }
+
+    /**
+     * Test whitelist_protocols() with allowed protocols.
+     */
+    public function testWhitelistAllowedProtocol()
+    {
+        $whitelist = ['ftp', 'magnet'];
+        $url = 'http://test.tld/path/?query=value#hash';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+        $url = 'https://test.tld/path/?query=value#hash';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+        $url = 'ftp://test.tld/path/?query=value#hash';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+        $url = 'magnet:test.tld/path/?query=value#hash';
+        $this->assertEquals($url, whitelist_protocols($url, $whitelist));
+    }
+
+    /**
+     * Test whitelist_protocols() with allowed protocols.
+     */
+    public function testWhitelistDisallowedProtocol()
+    {
+        $whitelist = ['ftp', 'magnet'];
+        $url = 'javascript:alert("xss");';
+        $this->assertEquals('http://alert("xss");', whitelist_protocols($url, $whitelist));
+        $url = 'other://test.tld/path/?query=value#hash';
+        $this->assertEquals('http://test.tld/path/?query=value#hash', whitelist_protocols($url, $whitelist));
+    }
+}
diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php
index d8180ad6..96891f1f 100644
--- a/tests/plugins/PluginMarkdownTest.php
+++ b/tests/plugins/PluginMarkdownTest.php
@@ -26,6 +26,7 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
     {
         PluginManager::$PLUGINS_PATH = 'plugins';
         $this->conf = new ConfigManager('tests/utils/config/configJson');
+        $this->conf->set('security.allowed_protocols', ['ftp', 'magnet']);
     }
 
     /**
@@ -183,15 +184,19 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test hashtag links processed with markdown.
+     * Make sure that the generated HTML match the reference HTML file.
      */
-    public function testMarkdownHashtagLinks()
+    public function testMarkdownGlobalProcessDescription()
     {
         $md = file_get_contents('tests/plugins/resources/markdown.md');
         $md = format_description($md);
         $html = file_get_contents('tests/plugins/resources/markdown.html');
 
-        $data = process_markdown($md);
+        $data = process_markdown(
+            $md,
+            $this->conf->get('security.markdown_escape', true),
+            $this->conf->get('security.allowed_protocols')
+        );
         $this->assertEquals($html, $data);
     }
 
diff --git a/tests/plugins/resources/markdown.html b/tests/plugins/resources/markdown.html
index 07a5a32e..844a6f31 100644
--- a/tests/plugins/resources/markdown.html
+++ b/tests/plugins/resources/markdown.html
@@ -21,4 +21,13 @@
 next #foo</code></pre>
 <p>Block:</p>
 <pre><code>lorem ipsum #foobar http://link.tld
-#foobar http://link.tld</code></pre></div>
\ No newline at end of file
+#foobar http://link.tld</code></pre>
+<p><a href="?123456">link</a><br />
+<img src="/img/train.png" alt="link" /><br />
+<a href="http://test.tld/path/?query=value#hash">link</a><br />
+<a href="http://test.tld/path/?query=value#hash">link</a><br />
+<a href="https://test.tld/path/?query=value#hash">link</a><br />
+<a href="ftp://test.tld/path/?query=value#hash">link</a><br />
+<a href="magnet:test.tld/path/?query=value#hash">link</a><br />
+<a href="http://alert('xss')">link</a><br />
+<a href="http://test.tld/path/?query=value#hash">link</a></p></div>
\ No newline at end of file
diff --git a/tests/plugins/resources/markdown.md b/tests/plugins/resources/markdown.md
index 0b8be7c5..b8ebd934 100644
--- a/tests/plugins/resources/markdown.md
+++ b/tests/plugins/resources/markdown.md
@@ -21,4 +21,14 @@ Block:
 ```
 lorem ipsum #foobar http://link.tld
 #foobar http://link.tld
-```
\ No newline at end of file
+```
+
+[link](?123456)
+![link](/img/train.png)
+[link](test.tld/path/?query=value#hash)
+[link](http://test.tld/path/?query=value#hash)
+[link](https://test.tld/path/?query=value#hash)
+[link](ftp://test.tld/path/?query=value#hash)
+[link](magnet:test.tld/path/?query=value#hash)
+[link](javascript:alert('xss'))
+[link](other://test.tld/path/?query=value#hash)
\ No newline at end of file
-- 
cgit v1.2.3