diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java index e9995c10664..51b0fcbe513 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/HeliumPackage.java @@ -17,10 +17,16 @@ package org.apache.zeppelin.helium; import com.google.gson.Gson; +import org.apache.commons.text.StringEscapeUtils; import org.apache.zeppelin.annotation.Experimental; import org.apache.zeppelin.common.JsonSerializable; +import java.util.Arrays; +import java.util.HashMap; import java.util.Map; +import java.util.Optional; + +import static org.apache.commons.text.StringEscapeUtils.escapeHtml4; /** * Helium package definition @@ -47,7 +53,7 @@ public class HeliumPackage implements JsonSerializable { private SpellPackageInfo spell; private Map config; - public HeliumPackage(HeliumType type, + private HeliumPackage(HeliumType type, String name, String description, String artifact, @@ -140,6 +146,41 @@ public String toJson() { } public static HeliumPackage fromJson(String json) { - return gson.fromJson(json, HeliumPackage.class); + return preventXss(gson.fromJson(json, HeliumPackage.class)); + } + + // This is only for test + public static HeliumPackage newHeliumPackage(HeliumType type, + String name, + String description, + String artifact, + String className, + String[][] resources, + String license, + String icon) { + return preventXss(new HeliumPackage( + type, name, description, artifact, className, resources, license, icon)); + } + + private static HeliumPackage preventXss(HeliumPackage heliumPackage) { + heliumPackage.name = escapeHtml4(heliumPackage.name); + heliumPackage.description = escapeHtml4(heliumPackage.description); + heliumPackage.artifact = escapeHtml4(heliumPackage.artifact); + heliumPackage.className = escapeHtml4(heliumPackage.className); + heliumPackage.resources = + Optional.ofNullable(heliumPackage.getResources()).map(r -> Arrays.stream(r) + .map(resource -> Arrays.stream(resource).map(StringEscapeUtils::escapeHtml4) + .toArray(String[]::new)) + .toArray(String[][]::new)).orElse(null); + heliumPackage.license = escapeHtml4(heliumPackage.license); + heliumPackage.published = escapeHtml4(heliumPackage.published); + heliumPackage.groupId = escapeHtml4(heliumPackage.groupId); + heliumPackage.artifactId = escapeHtml4(heliumPackage.artifactId); + heliumPackage.spell = Optional.ofNullable(heliumPackage.getSpellInfo()) + .map(spellPackageInfo -> new SpellPackageInfo( + escapeHtml4(spellPackageInfo.getMagic()), + escapeHtml4(spellPackageInfo.getUsage()))) + .orElse(null); + return heliumPackage; } } diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/SpellPackageInfo.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/SpellPackageInfo.java index 519d09d70e7..52e17dbd3fd 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/SpellPackageInfo.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/helium/SpellPackageInfo.java @@ -24,6 +24,11 @@ public class SpellPackageInfo { private String magic; private String usage; + public SpellPackageInfo(String magic, String usage) { + this.magic = magic; + this.usage = usage; + } + public String getMagic() { return magic; } diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/ApplicationLoaderTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/ApplicationLoaderTest.java index 21d3d751b8d..52508b48dd2 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/ApplicationLoaderTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/ApplicationLoaderTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -74,7 +75,7 @@ void loadUnloadApplication() throws Exception { } public HeliumPackage createPackageInfo(String className, String artifact) { - HeliumPackage app1 = new HeliumPackage( + HeliumPackage app1 = newHeliumPackage( HeliumType.APPLICATION, "name1", "desc1", diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java index 1d168d1448f..4efeda7dca6 100644 --- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java +++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/helium/HeliumPackageTest.java @@ -17,6 +17,7 @@ package org.apache.zeppelin.helium; +import static org.apache.commons.text.StringEscapeUtils.escapeHtml4; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Map; @@ -42,7 +43,7 @@ void parseSpellPackageInfo() { HeliumPackage p = HeliumPackage.fromJson(examplePackage); assertEquals("%echo", p.getSpellInfo().getMagic()); - assertEquals("%echo ", p.getSpellInfo().getUsage()); + assertEquals(escapeHtml4("%echo "), p.getSpellInfo().getUsage()); } @Test diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java index 87af88507ff..ed74641892c 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/HeliumRestApiTest.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.Set; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -64,7 +65,7 @@ void setUp() throws IOException { HeliumTestRegistry registry = new HeliumTestRegistry("r1", "r1"); helium.clear(); - registry.add(new HeliumPackage( + registry.add(newHeliumPackage( HeliumType.APPLICATION, "name1", "desc1", @@ -74,7 +75,7 @@ void setUp() throws IOException { "", "")); - registry.add(new HeliumPackage( + registry.add(newHeliumPackage( HeliumType.APPLICATION, "name2", "desc2", diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java index 95a3858885c..574b4e22556 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java @@ -16,6 +16,7 @@ */ package org.apache.zeppelin.helium; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; @@ -90,7 +91,7 @@ public void tearDown() throws Exception { public void testLoadRunUnloadApplication() throws IOException, ApplicationException, InterruptedException { // given - HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION, + HeliumPackage pkg1 = newHeliumPackage(HeliumType.APPLICATION, "name1", "desc1", "", @@ -139,7 +140,7 @@ public void testLoadRunUnloadApplication() @Disabled public void testUnloadOnParagraphRemove() throws IOException { // given - HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION, + HeliumPackage pkg1 = newHeliumPackage(HeliumType.APPLICATION, "name1", "desc1", "", @@ -182,7 +183,7 @@ public void testUnloadOnParagraphRemove() throws IOException { @Disabled public void testUnloadOnInterpreterUnbind() throws IOException { // given - HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION, + HeliumPackage pkg1 = newHeliumPackage(HeliumType.APPLICATION, "name1", "desc1", "", @@ -249,7 +250,7 @@ public void testInterpreterUnbindOfNullReplParagraph() throws IOException { @Disabled public void testUnloadOnInterpreterRestart() throws IOException, InterpreterException { // given - HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION, + HeliumPackage pkg1 = newHeliumPackage(HeliumType.APPLICATION, "name1", "desc1", "", diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java index 9c84251ee70..00f5bb0058b 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumBundleFactoryTest.java @@ -17,6 +17,7 @@ package org.apache.zeppelin.helium; import static org.apache.zeppelin.helium.HeliumBundleFactory.HELIUM_LOCAL_REPO; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; @@ -72,7 +73,7 @@ public void testInstallNpm() throws InstallationException { @Test public void downloadPackage() throws TaskRunnerException { HeliumPackage pkg = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "lodash", "lodash", @@ -89,7 +90,7 @@ public void downloadPackage() throws TaskRunnerException { @Test public void bundlePackage() throws IOException, TaskRunnerException { HeliumPackage pkg = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "zeppelin-bubblechart", "zeppelin-bubblechart", @@ -114,7 +115,7 @@ public void bundleLocalPackage() throws IOException, TaskRunnerException { String localPkg = resDir + "/../../../src/test/resources/helium/vis1"; HeliumPackage pkg = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "vis1", "vis1", @@ -135,7 +136,7 @@ public void bundleErrorPropagation() throws IOException, TaskRunnerException { String localPkg = resDir + "/../../../src/test/resources/helium/vis2"; HeliumPackage pkg = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "vis2", "vis2", @@ -161,7 +162,7 @@ public void switchVersion() throws IOException, TaskRunnerException { String resDir = new File(res.getFile()).getParent(); HeliumPackage pkgV1 = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "zeppelin-bubblechart", "zeppelin-bubblechart", @@ -172,7 +173,7 @@ public void switchVersion() throws IOException, TaskRunnerException { "icon"); HeliumPackage pkgV2 = - new HeliumPackage( + newHeliumPackage( HeliumType.VISUALIZATION, "zeppelin-bubblechart", "zeppelin-bubblechart", diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumLocalRegistryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumLocalRegistryTest.java index 972e461ffb8..328656a58de 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumLocalRegistryTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumLocalRegistryTest.java @@ -25,6 +25,7 @@ import java.io.File; import java.io.IOException; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.junit.jupiter.api.Assertions.assertEquals; public class HeliumLocalRegistryTest { @@ -50,7 +51,7 @@ public void testGetAllPackage() throws IOException { // when Gson gson = new Gson(); - HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION, + HeliumPackage pkg1 = newHeliumPackage(HeliumType.APPLICATION, "app1", "desc1", "artifact1", diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumTest.java index 021e6cb786f..384103c2627 100644 --- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumTest.java +++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumTest.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.net.URISyntaxException; +import static org.apache.zeppelin.helium.HeliumPackage.newHeliumPackage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -77,7 +78,7 @@ public void testRestoreRegistryInstances() throws IOException, URISyntaxExceptio helium.addRegistry(registry2); // when - registry1.add(new HeliumPackage( + registry1.add(newHeliumPackage( HeliumType.APPLICATION, "name1", "desc1", @@ -87,7 +88,7 @@ public void testRestoreRegistryInstances() throws IOException, URISyntaxExceptio "", "")); - registry2.add(new HeliumPackage( + registry2.add(newHeliumPackage( HeliumType.APPLICATION, "name2", "desc2", @@ -110,7 +111,7 @@ public void testRefresh() throws IOException, URISyntaxException, TaskRunnerExce helium.addRegistry(registry1); // when - registry1.add(new HeliumPackage( + registry1.add(newHeliumPackage( HeliumType.APPLICATION, "name1", "desc1", @@ -124,7 +125,7 @@ public void testRefresh() throws IOException, URISyntaxException, TaskRunnerExce assertEquals(1, helium.getAllPackageInfo().size()); // when - registry1.add(new HeliumPackage( + registry1.add(newHeliumPackage( HeliumType.APPLICATION, "name2", "desc2",