SLING-8966 escape all dynamic input
diff --git a/src/main/java/org/apache/sling/installer/core/impl/console/AbstractWebConsolePlugin.java b/src/main/java/org/apache/sling/installer/core/impl/console/AbstractWebConsolePlugin.java
new file mode 100644
index 0000000..a9e8895
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/core/impl/console/AbstractWebConsolePlugin.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.core.impl.console;
+
+import java.net.URL;
+
+import javax.servlet.GenericServlet;
+
+@SuppressWarnings("serial")
+abstract class AbstractWebConsolePlugin extends GenericServlet {
+
+ /**
+ *
+ * @return the prefix under which resources are requested (must not start with "/", must end with "/")
+ */
+ abstract String getRelativeResourcePrefix();
+
+ /**
+ * Method to retrieve static resources from this bundle.
+ */
+ @SuppressWarnings("unused")
+ private URL getResource(final String path) {
+ if (path.startsWith("/" + getRelativeResourcePrefix())) {
+ // strip label
+ int index = path.indexOf('/', 1);
+ if (index <= 0) {
+ throw new IllegalStateException("The relativeResourcePrefix must contain at least one '/'");
+ }
+ return this.getClass().getResource(path.substring(index));
+ }
+ return null;
+ }
+
+ /**
+ * Copied from org.apache.sling.api.request.ResponseUtil
+ * Escape XML text
+ * @param input The input text
+ * @return The escaped text
+ */
+ protected String escapeXml(final String input) {
+ if (input == null) {
+ return null;
+ }
+
+ final StringBuilder b = new StringBuilder(input.length());
+ for(int i = 0;i < input.length(); i++) {
+ final char c = input.charAt(i);
+ if(c == '&') {
+ b.append("&");
+ } else if(c == '<') {
+ b.append("<");
+ } else if(c == '>') {
+ b.append(">");
+ } else if(c == '"') {
+ b.append(""");
+ } else if(c == '\'') {
+ b.append("'");
+ } else {
+ b.append(c);
+ }
+ }
+ return b.toString();
+ }
+}
diff --git a/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java b/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java
index d6d065f..b90e1cb 100644
--- a/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java
+++ b/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java
@@ -21,7 +21,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Dictionary;
import java.util.Enumeration;
@@ -29,7 +28,6 @@
import java.util.Hashtable;
import java.util.Set;
-import javax.servlet.GenericServlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -52,10 +50,10 @@
"felix.webconsole.category=OSGi"
})
@SuppressWarnings("serial")
-public class ConfigurationSerializerWebConsolePlugin extends GenericServlet {
+public class ConfigurationSerializerWebConsolePlugin extends AbstractWebConsolePlugin {
public static final String LABEL = "osgi-installer-config-printer";
- private static final String RES_LOC = LABEL + "/res/ui";
+ private static final String RES_LOC = LABEL + "/res/ui/";
private static final String PARAMETER_PID = "pid";
private static final String PARAMETER_FORMAT = "format";
@@ -87,17 +85,6 @@
@Reference
ConfigurationAdmin configurationAdmin;
- /**
- * Method to retrieve static resources from this bundle.
- */
- @SuppressWarnings("unused")
- private URL getResource(final String path) {
- if (path.startsWith("/" + RES_LOC)) {
- return this.getClass().getResource(path.substring(LABEL.length()+1));
- }
- return null;
- }
-
@Override
public void service(final ServletRequest request, final ServletResponse response)
throws IOException {
@@ -114,7 +101,7 @@
}
final PrintWriter pw = response.getWriter();
- pw.println("<script type=\"text/javascript\" src=\"" + RES_LOC + "/clipboard.js\"></script>");
+ pw.println("<script type=\"text/javascript\" src=\"" + RES_LOC + "clipboard.js\"></script>");
pw.print("<form method='get'>");
pw.println("<table class='content' cellpadding='0' cellspacing='0' width='100%'>");
@@ -191,37 +178,6 @@
pw.print("</form>");
}
- /**
- * Copied from org.apache.sling.api.request.ResponseUtil
- * Escape XML text
- * @param input The input text
- * @return The escaped text
- */
- private String escapeXml(final String input) {
- if (input == null) {
- return null;
- }
-
- final StringBuilder b = new StringBuilder(input.length());
- for(int i = 0;i < input.length(); i++) {
- final char c = input.charAt(i);
- if(c == '&') {
- b.append("&");
- } else if(c == '<') {
- b.append("<");
- } else if(c == '>') {
- b.append(">");
- } else if(c == '"') {
- b.append(""");
- } else if(c == '\'') {
- b.append("'");
- } else {
- b.append(c);
- }
- }
- return b.toString();
- }
-
// copied from org.apache.sling.installer.factories.configuration.impl.ConfigUtil
/**
* Remove all ignored properties
@@ -289,4 +245,9 @@
}
}
+ @Override
+ String getRelativeResourcePrefix() {
+ return RES_LOC;
+ }
+
}
diff --git a/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java b/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java
index 2f4b17a..97bc12d 100644
--- a/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java
+++ b/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java
@@ -21,14 +21,12 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
-import javax.servlet.GenericServlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -55,13 +53,13 @@
"felix.webconsole.category=OSGi",
"felix.webconsole.configprinter.modes=zip",
"felix.webconsole.configprinter.modes=txt",
- "felix.webconsole.css=" + OsgiInstallerWebConsolePlugin.RES_LOC + "/list.css"
+ "felix.webconsole.css=" + OsgiInstallerWebConsolePlugin.RES_LOC + "list.css"
})
@SuppressWarnings("serial")
-public class OsgiInstallerWebConsolePlugin extends GenericServlet {
+public class OsgiInstallerWebConsolePlugin extends AbstractWebConsolePlugin {
public static final String LABEL = "osgi-installer";
- protected static final String RES_LOC = LABEL + "/res/ui";
+ protected static final String RES_LOC = LABEL + "/res/ui/";
@Reference(policyOption=ReferencePolicyOption.GREEDY)
@@ -159,8 +157,8 @@
if ( rt != null ) {
bufferedPw.println("</tbody></table>");
}
- String anchor = "active-" + getType(toActivate);
- pw.println("<li><a href='#" + anchor + "'>" + getType(toActivate) + "</a></li>");
+ String anchor = "active-" + escapeXml(getType(toActivate));
+ pw.println("<li><a href='#" + anchor + "'>" + escapeXml(getType(toActivate)) + "</a></li>");
bufferedPw.println("<div id='" + anchor + "' class='ui-widget-header ui-corner-top buttonGroup' style='height: 15px;'>");
bufferedPw.printf("<span style='float: left; margin-left: 1em;'>Active Resources - %s</span>", getType(toActivate));
bufferedPw.println("</div>");
@@ -169,11 +167,11 @@
rt = toActivate.getType();
}
bufferedPw.printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
- getEntityId(toActivate, group.getAlias()),
- getInfo(toActivate),
- getURL(toActivate),
- toActivate.getState(),
- getError(toActivate));
+ escapeXml(getEntityId(toActivate, group.getAlias())),
+ escapeXml(getInfo(toActivate)),
+ escapeXml(getURL(toActivate)),
+ escapeXml(toActivate.getState().toString()),
+ escapeXml(getError(toActivate)));
}
if ( rt != null ) {
bufferedPw.println("</tbody></table>");
@@ -195,8 +193,8 @@
if ( rt != null ) {
bufferedPw.println("</tbody></table>");
}
- String anchor = "processed-" + getType(first);
- pw.println("<li><a href='#" + anchor + "'>" + getType(first) + "</a></li>");
+ String anchor = "processed-" + escapeXml(getType(first));
+ pw.println("<li><a href='#" + anchor + "'>" + escapeXml(getType(first)) + "</a></li>");
bufferedPw.println("<div id='" + anchor + "' class='ui-widget-header ui-corner-top buttonGroup' style='height: 15px;'>");
bufferedPw.printf("<span style='float: left; margin-left: 1em;'>Processed Resources - %s</span>", getType(first));
@@ -206,13 +204,13 @@
rt = first.getType();
}
bufferedPw.print("<tr><td>");
- bufferedPw.print(getEntityId(first, group.getAlias()));
+ bufferedPw.print(escapeXml(getEntityId(first, group.getAlias())));
bufferedPw.print("</td><td>");
- bufferedPw.print(getInfo(first));
+ bufferedPw.print(escapeXml(getInfo(first)));
bufferedPw.print("</td><td>");
- bufferedPw.print(getURL(first));
+ bufferedPw.print(escapeXml(getURL(first)));
bufferedPw.print("</td><td>");
- bufferedPw.print(getState(first));
+ bufferedPw.print(escapeXml(getState(first)));
if ( first.getState() == ResourceState.INSTALLED ) {
final long lastChange = first.getLastChange();
if ( lastChange > 0 ) {
@@ -221,24 +219,24 @@
}
}
bufferedPw.print("</td><td>");
- bufferedPw.print(getError(first));
+ bufferedPw.print(escapeXml(getError(first)));
bufferedPw.print("</td></tr>");
if ( first.getAttribute(TaskResource.ATTR_INSTALL_EXCLUDED) != null ) {
bufferedPw.printf("<tr><td></td><td colspan='2'>%s</td><td></td><td></td></tr>",
- first.getAttribute(TaskResource.ATTR_INSTALL_EXCLUDED));
+ escapeXml(first.getAttribute(TaskResource.ATTR_INSTALL_EXCLUDED).toString()));
}
if ( first.getAttribute(TaskResource.ATTR_INSTALL_INFO) != null ) {
bufferedPw.printf("<tr><td></td><td colspan='2'>%s</td><td></td><td></td></tr>",
- first.getAttribute(TaskResource.ATTR_INSTALL_INFO));
+ escapeXml(first.getAttribute(TaskResource.ATTR_INSTALL_INFO).toString()));
}
while ( iter.hasNext() ) {
final Resource resource = iter.next();
bufferedPw.printf("<tr><td></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
- getInfo(resource),
- getURL(resource),
- resource.getState(),
- getError(resource));
+ escapeXml(getInfo(resource)),
+ escapeXml(getURL(resource)),
+ escapeXml(resource.getState().toString()),
+ escapeXml(getError(resource)));
}
}
}
@@ -258,8 +256,8 @@
if ( rt != null ) {
bufferedPw.println("</tbody></table>");
}
- String anchor = "untransformed-" + getType(registeredResource);
- pw.println("<li><a href='#" + anchor + "'>" + getType(registeredResource) + "</a></li>");
+ String anchor = "untransformed-" + escapeXml(getType(registeredResource));
+ pw.println("<li><a href='#" + anchor + "'>" + escapeXml(getType(registeredResource)) + "</a></li>");
bufferedPw.println("<div id='" + anchor + "' class='ui-widget-header ui-corner-top buttonGroup' style='height: 15px;'>");
bufferedPw.printf("<span style='float: left; margin-left: 1em;'>Untransformed Resources - %s</span>", getType(registeredResource));
@@ -270,8 +268,8 @@
rt = registeredResource.getType();
}
bufferedPw.printf("<tr><td>%s</td><td>%s</td></tr>",
- getInfo(registeredResource),
- registeredResource.getURL());
+ escapeXml(getInfo(registeredResource)),
+ escapeXml(registeredResource.getURL()));
}
if ( rt != null ) {
bufferedPw.println("</tbody></table>");
@@ -364,15 +362,11 @@
registeredResource.getURL());
}
}
-
- /**
- * Method to retrieve static resources from this bundle.
- */
- @SuppressWarnings("unused")
- private URL getResource(final String path) {
- if (path.startsWith("/" + RES_LOC)) {
- return this.getClass().getResource(path.substring(LABEL.length()+1));
- }
- return null;
+
+ @Override
+ String getRelativeResourcePrefix() {
+ return RES_LOC;
}
+
+
}