CVE-2022-23621: Files or Directories Accessible to External Parties (CWE-552)
value: XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. In affected versions any user with SCRIPT right can read any file located in the XWiki WAR (for example xwiki.cfg and xwiki.properties) through XWiki#invokeServletAndReturnAsString as `$xwiki.invokeServletAndReturnAsString("/WEB-INF/xwiki.cfg")`. This issue has been patched in XWiki versions 12.10.9, 13.4.3 and 13.7-rc-1. Users are advised to update. The only workaround is to limit SCRIPT right.
CWE description: The product makes files or directories accessible to unauthorized actors, even though they should not be.
CVSS v3 base score: 4.9
Published: 2022-02-09T22:15Z
Repository: https://github.com/xwiki/xwiki-platform
Language: Other
Files changed: xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj, xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/api/XWikiCompatibilityAspect.aj, xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java, xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
Commit date: 2021-07-29 15:12:59 +0200
Commit message: XWIKI-18870: Unexpected behavior of XWiki#invokeServletAndReturnAsString

Diff: diff --git a/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj b/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj
index e29da138857f..6091b01a62a5 100644
--- a/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj
+++ b/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/XWikiCompatibilityAspect.aj
@@ -33,10 +33,13 @@ import java.util.Map;
 import java.net.InetAddress;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 import java.io.IOException;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.net.smtp.SMTPClient;
 import org.apache.commons.net.smtp.SMTPReply;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.MethodUtils;
 import org.apache.velocity.VelocityContext;
@@ -76,10 +79,11 @@ import com.xpn.xwiki.plugin.query.XWikiCriteria;
 import com.xpn.xwiki.plugin.query.XWikiQuery;
 import com.xpn.xwiki.util.Util;
 import com.xpn.xwiki.web.Utils;
 import com.xpn.xwiki.web.XWikiMessageTool;
 import com.xpn.xwiki.web.XWikiRequest;
+import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
 
 /**
  * Add a backward compatibility layer to the {@link com.xpn.xwiki.XWiki} class.
  * 
  * @version $Id$
@@ -1386,6 +1390,26 @@ public privileged aspect XWikiCompatibilityAspect
                 extendedRenderingConfiguration.getDefaultContentSyntax().toIdString());
             this.configuredSyntaxes = Arrays.asList(StringUtils.split(syntaxes, " ,"));
         }
         return this.configuredSyntaxes;
     }
+
+    /**
+     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
+     * RequestDispatcher, buffering the output, then returning it as a string.
+     * 
+     * @deprecated since 12.10.9, 13.4.3, 13.7RC1
+     */
+    @Deprecated
+    public String XWiki.invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
+    {
+        HttpServletRequest servletRequest = xwikiContext.getRequest();
+        HttpServletResponse servletResponse = xwikiContext.getResponse();
+
+        try {
+            return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
+        } catch (Exception e) {
+            LOGGER.warn("Exception including url: " + url, e);
+            return "Exception including \"" + url + "\", see logs for details.";
+        }
+    }
 }
diff --git a/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/api/XWikiCompatibilityAspect.aj b/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/api/XWikiCompatibilityAspect.aj
index bd48aa8b564c..263fef293bbf 100644
--- a/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/api/XWikiCompatibilityAspect.aj
+++ b/xwiki-platform-core/xwiki-platform-legacy/xwiki-platform-legacy-oldcore/src/main/aspect/com/xpn/xwiki/api/XWikiCompatibilityAspect.aj
@@ -1196,6 +1196,20 @@ public privileged aspect XWikiCompatibilityAspect
     @Deprecated
     public List<String> XWiki.getConfiguredSyntaxes()
     {
         return this.xwiki.getConfiguredSyntaxes();
     }
+
+    /**
+     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
+     * RequestDispatcher, buffering the output, then returning it as a string.
+     *
+     * @param url URL of the servlet
+     * @return text result of the servlet
+     * @deprecated since 12.10.9, 13.4.3, 13.7RC1
+     */
+    @Deprecated
+    public String XWiki.invokeServletAndReturnAsString(String url)
+    {
+        return hasProgrammingRights() ? this.xwiki.invokeServletAndReturnAsString(url, getXWikiContext()) : null;
+    }
 }
\ No newline at end of file
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
index b8389e4b0e3f..c2a920a3232d 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java
@@ -64,12 +64,10 @@
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.naming.NamingException;
 import javax.script.ScriptContext;
 import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.httpclient.Credentials;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.URIException;
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
@@ -263,11 +261,10 @@
 import com.xpn.xwiki.web.XWikiRequest;
 import com.xpn.xwiki.web.XWikiServletRequestStub;
 import com.xpn.xwiki.web.XWikiURLFactory;
 import com.xpn.xwiki.web.XWikiURLFactoryService;
 import com.xpn.xwiki.web.XWikiURLFactoryServiceImpl;
-import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
 
 @Serializable(false)
 public class XWiki implements EventListener
 {
     /** Name of the default wiki. */
@@ -2576,29 +2573,10 @@ public String renderTemplate(String template, XWikiContext context)
             LOGGER.error("Failed to render template [" + template + "]", ex);
             return parseTemplate(template, context);
         }
     }
 
-    /**
-     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
-     * RequestDispatcher, buffering the output, then returning it as a string.
-     */
-    public String invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
-    {
-
-        HttpServletRequest servletRequest = xwikiContext.getRequest();
-        HttpServletResponse servletResponse = xwikiContext.getResponse();
-
-        try {
-            return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
-        } catch (Exception e) {
-            LOGGER.warn("Exception including url: " + url, e);
-            return "Exception including \"" + url + "\", see logs for details.";
-        }
-
-    }
-
     /**
      * @param iconName the standard name of an icon (it's not the name of the file on the filesystem, it's a generic
      *            name, for example "success" for a success icon
      * @param context see {@link XWikiContext}
      * @return the URL to the icon resource
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
index 48da7d8fc5bc..d89c31df87cc 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/api/XWiki.java
@@ -1008,22 +1008,10 @@ public String parseTemplate(String template)
     public String renderTemplate(String template)
     {
         return this.xwiki.renderTemplate(template, getXWikiContext());
     }
 
-    /**
-     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
-     * RequestDispatcher, buffering the output, then returning it as a string.
-     *
-     * @param url URL of the servlet
-     * @return text result of the servlet
-     */
-    public String invokeServletAndReturnAsString(String url)
-    {
-        return this.xwiki.invokeServletAndReturnAsString(url, getXWikiContext());
-    }
-
     /**
      * Return the URL of the static file provided by the current skin The file is first looked in the skin active for
      * the user, the space or the wiki. If the file does not exist in that skin, the file is looked up in the "parent
      * skin" of the skin. The file can be a CSS file, an image file, a javascript file, etc.
      *

Vulnerable code: import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
    /**
     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
     * RequestDispatcher, buffering the output, then returning it as a string.
     */
    public String invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
    {

        HttpServletRequest servletRequest = xwikiContext.getRequest();
        HttpServletResponse servletResponse = xwikiContext.getResponse();

        try {
            return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
        } catch (Exception e) {
            LOGGER.warn("Exception including url: " + url, e);
            return "Exception including \"" + url + "\", see logs for details.";
        }

    }

    /**
     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
     * RequestDispatcher, buffering the output, then returning it as a string.
     *
     * @param url URL of the servlet
     * @return text result of the servlet
     */
    public String invokeServletAndReturnAsString(String url)
    {
        return this.xwiki.invokeServletAndReturnAsString(url, getXWikiContext());
    }

Fixed code: import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;

    /**
     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
     * RequestDispatcher, buffering the output, then returning it as a string.
     * 
     * @deprecated since 12.10.9, 13.4.3, 13.7RC1
     */
    @Deprecated
    public String XWiki.invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
    {
        HttpServletRequest servletRequest = xwikiContext.getRequest();
        HttpServletResponse servletResponse = xwikiContext.getResponse();

        try {
            return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
        } catch (Exception e) {
            LOGGER.warn("Exception including url: " + url, e);
            return "Exception including \"" + url + "\", see logs for details.";
        }
    }

    /**
     * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
     * RequestDispatcher, buffering the output, then returning it as a string.
     *
     * @param url URL of the servlet
     * @return text result of the servlet
     * @deprecated since 12.10.9, 13.4.3, 13.7RC1
     */
    @Deprecated
    public String XWiki.invokeServletAndReturnAsString(String url)
    {
        return hasProgrammingRights() ? this.xwiki.invokeServletAndReturnAsString(url, getXWikiContext()) : null;
    }