diff --git a/src/main/java/alfio/util/MustacheCustomTag.java b/src/main/java/alfio/util/MustacheCustomTag.java index fecf3c5711..f99d9d977d 100644 --- a/src/main/java/alfio/util/MustacheCustomTag.java +++ b/src/main/java/alfio/util/MustacheCustomTag.java @@ -168,7 +168,15 @@ public void setAttributes(Node node, String tagName, Map attribu if (node instanceof Link) { Link l = (Link) node; String destination = StringUtils.trimToEmpty(l.getDestination()); + var scheme = getScheme(destination); + scheme.ifPresent(resolvedScheme -> { + if (!Set.of("http", "https").contains(resolvedScheme)) { + log.info("User tried to set an url with scheme {}, only http/https are accepted, href has been removed", resolvedScheme); + attributes.remove("href"); + } + }); if (UrlUtils.isAbsoluteUrl(destination)) { + // accept only http or https protocols if we have an absolute link, else we override with an empty string attributes.put("target", "_blank"); attributes.put("rel", "nofollow noopener noreferrer"); var newTabLabel = A11Y_NEW_TAB_LABEL.get(); @@ -183,6 +191,14 @@ public static String renderToHtmlCommonmarkEscaped(String input) { return renderToHtmlCommonmarkEscaped(input, null); } + /** + * return lowercase scheme if present + */ + private static Optional getScheme(String uri) { + var s = StringUtils.trimToEmpty(uri).toLowerCase(Locale.ROOT); + return s.indexOf(':') >= 0 ? Optional.of(StringUtils.substringBefore(s, ':')) : Optional.empty(); + } + public static String renderToHtmlCommonmarkEscaped(String input, String localizedNewWindowLabel) { try { A11Y_NEW_TAB_LABEL.set(localizedNewWindowLabel); diff --git a/src/test/java/alfio/util/MustacheCustomTagTest.java b/src/test/java/alfio/util/MustacheCustomTagTest.java index c2c0c19bb5..17ef9701e4 100644 --- a/src/test/java/alfio/util/MustacheCustomTagTest.java +++ b/src/test/java/alfio/util/MustacheCustomTagTest.java @@ -87,4 +87,13 @@ public void testHtmlMarkDown() { //for absolute link we add target="_blank" assertEquals("

link bla link

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("link [bla](http://test) link")); } + + @Test + public void acceptOnlyHttpOrHttpsProtocols() { + assertEquals("

google

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("[google](http://google.com)")); + assertEquals("

google

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("[google](https://google.com)")); + assertEquals("

google

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("[google](any:google.com)")); + assertEquals("

google

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("[google](other:google.com)")); + assertEquals("

google

\n", MustacheCustomTag.renderToHtmlCommonmarkEscaped("[google](protocols:/google.com)")); + } } \ No newline at end of file