content insight servlet

Avatar

Avatar

kartheekd203042

Avatar

kartheekd203042

kartheekd203042

12-07-2018

Hi Experts,

Can anyone help me understand the purpose of the below servlet and what it is used for?

http://localhost:4502/libs/cq/contentinsight/proxy/reportingservices.json.GET.servlet.a.23.css

Our team reported a vulnerability that using this servlet they can perform SSRF attacks and reach to the publisher bypassing the dispatcher.

While restricting it is an immediate measure we have taken but would like to understand the impact of restricting at the dispatcher.

Any inputs or links referring to the original documentation would be of great help

Regards

Kartheek

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

lmha

Employee

Avatar

lmha

Employee

lmha
Employee

03-08-2018

Hi Kartheek,

Apologies for the delay, I was confirming if the information is fine to release to public.

The workaround instead of installing the patch is to:

Change the “Whitelist” value from .*/api[0-9]*.omniture.com/.*  to https?:\/\/api(\d+)?\.omniture\.com(:\d+)?\/rs\/0\.5\/.* within /system/console/configMgr/com.adobe.cq.contentinsight.impl.servlets.ReportingServicesProxyServlet configuration.

Please make sure to upgrade to latest official patch when possible.

Regards,

Lisa

Answers (8)

Answers (8)

Avatar

Avatar

kartheekd203042

Avatar

kartheekd203042

kartheekd203042

03-08-2018

HI Lisa,

Please let us know  if there is any workaround without SP2 upgrade?

Avatar

Avatar

kartheekd203042

Avatar

kartheekd203042

kartheekd203042

01-08-2018

Hi Lisa,

Unfortunately we are not on SP2 and we cannot upgrade to SP2 within the next few days.

Is there a way to mitigate the upgrade and provide us with a specific patch for our version so we can fix the security vulnerability faster?

Avatar

Avatar

lmha

Employee

Avatar

lmha

Employee

lmha
Employee

01-08-2018

Hi kartheekd20304289

The appropriate hotfix/patch package for AEM Version 6.3.1.2 is:

https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani...

Please note that the pre-requisite for this hotfix is SP2.

Regards,

Lisa

Avatar

Avatar

kartheekd203042

Avatar

kartheekd203042

kartheekd203042

01-08-2018

Thanks.

Can you please share the appropriate hotfix/patch package for AEM Version 6.3.1.2

Avatar

Avatar

lmha

Employee

Avatar

lmha

Employee

lmha
Employee

16-07-2018

kartheekd20304289​ , yes , http://localhost:4502/libs/cq/contentinsight/proxy/reportingservices.json.GET.servlet.a.23 .css is the same as ReportingServicesProxyServlet.java servlet .

Here is better description regarding the functionality of this servlet:

The servlet is proxying requests for browsers (older IE) that do not properly support CORS XMLHttpRequests. The servlet is not used if Content-Insight is used with modern browsers.

Applying a Dispatcher filter would indeed interfere with the Content-Insight feature as other functionality is also exposed at /libs/cq/contentinsight/content/*.  However, we suggest to go with the official patch / hotfix to resolve the issue.

Avatar

Avatar

Himanshu_Singhal

MVP

Avatar

Himanshu_Singhal

MVP

Himanshu_Singhal
MVP

14-07-2018

kartheekd20304289​ The servlet which invoked in backend of mentioned URL (http://localhost:4502/libs/cq/contentinsight/proxy/reportingservices.json.GET.servlet.a.23.css ) is ReportingServicesProxyServlet.java.

For more info, you can have a look at the code.

package com.adobe.cq.contentinsight.impl.servlets;

import org.slf4j.LoggerFactory;

import org.apache.felix.scr.annotations.Activate;

import org.apache.sling.commons.osgi.PropertiesUtil;

import org.osgi.service.component.ComponentContext;

import java.util.regex.Pattern;

import java.io.IOException;

import javax.servlet.ServletException;

import org.apache.http.HttpResponse;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.client.HttpClient;

import java.net.URISyntaxException;

import org.apache.http.client.utils.HttpClientUtils;

import java.io.OutputStream;

import org.apache.commons.io.IOUtils;

import org.apache.http.client.methods.HttpUriRequest;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.utils.URIBuilder;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.SlingHttpServletRequest;

import org.slf4j.Logger;

import org.apache.felix.scr.annotations.Reference;

import org.apache.http.osgi.services.HttpClientBuilderFactory;

import org.apache.felix.scr.annotations.Property;

import org.apache.felix.scr.annotations.sling.SlingServlet;

import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

@SlingServlet(generateComponent = true, metatype = true, resourceTypes = { "cq/contentinsight/proxy" }, extensions = { "json" }, selectors = { "reportingservices" }, methods = { "GET" }, label = "Reporting Services API proxy servlet", description = "Proxy servlet for Reporting Services API")

public class ReportingServicesProxyServlet extends SlingSafeMethodsServlet

{

    private static final String DEFAULT_API_OMNITURE_URL = ".*/api[0-9]*.omniture.com/.*";

    @Property(name = "reportingservices.proxy.whitelist", label = "Whitelist", description = "Allowed destinations for the reporting services proxy servlet", cardinality = Integer.MAX_VALUE, value = { ".*/api[0-9]*.omniture.com/.*" })

    private String[] whiteList;

    @Reference

    private HttpClientBuilderFactory clientBuilderFactory;

    private static final long serialVersionUID = 7044811756109092040L;

    private static final Logger LOG;

   

    public ReportingServicesProxyServlet() {

        this.whiteList = new String[] { ".*/api[0-9]*.omniture.com/.*" };

    }

   

    protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException {

        final String url = request.getParameter("url");

        final String query = request.getParameter("q");

        if (url == null || query == null) {

            response.setStatus(400);

            return;

        }

        if (!this.isUrlAllowed(url)) {

            ReportingServicesProxyServlet.LOG.warn("Received url " + url + " not whitelisted!");

            return;

        }

        final CloseableHttpClient httpClient = this.clientBuilderFactory.newBuilder().build();

        try {

            final URIBuilder uriBuilder = new URIBuilder(url);

            uriBuilder.addParameter("q", query);

            final HttpGet get = new HttpGet(uriBuilder.build());

            get.setHeader("x-adobe-rs-auth", request.getHeader("x-adobe-rs-auth"));

            HttpResponse getResponse = null;

            try {

                getResponse = (HttpResponse)httpClient.execute((HttpUriRequest)get);

                final int status = getResponse.getStatusLine().getStatusCode();

                IOUtils.copy(getResponse.getEntity().getContent(), (OutputStream)response.getOutputStream());

                response.setStatus(status);

            }

            finally {

                HttpClientUtils.closeQuietly(getResponse);

            }

        }

        catch (URISyntaxException e) {

            ReportingServicesProxyServlet.LOG.error("Invalid URL: " + url, (Throwable)e);

        }

        finally {

            HttpClientUtils.closeQuietly((HttpClient)httpClient);

        }

    }

   

    private boolean isUrlAllowed(final String url) {

        boolean isAllowed = false;

        for (final String whitelistedRegex : this.whiteList) {

            final Pattern pattern = Pattern.compile(whitelistedRegex);

            isAllowed = pattern.matcher((CharSequence)url).matches();

            if (isAllowed) {

                break;

            }

        }

        return isAllowed;

    }

   

    @Activate

    protected void activate(final ComponentContext ctx) {

        this.whiteList = PropertiesUtil.toStringArray(ctx.getProperties().get("reportingservices.proxy.whitelist"), new String[] { ".*/api[0-9]*.omniture.com/.*" });

    }

   

    static {

        LOG = LoggerFactory.getLogger((Class)ReportingServicesProxyServlet.class);

    }

   

    protected void bindClientBuilderFactory(final HttpClientBuilderFactory clientBuilderFactory) {

        this.clientBuilderFactory = clientBuilderFactory;

    }

   

    protected void unbindClientBuilderFactory(final HttpClientBuilderFactory httpClientBuilderFactory) {

        if (this.clientBuilderFactory == httpClientBuilderFactory) {

            this.clientBuilderFactory = null;

        }

    }

}

Avatar

Avatar

kartheekd203042

Avatar

kartheekd203042

kartheekd203042

13-07-2018

Thanks.IS the ReportingServicesProxyServlet.java servlet same as the http://localhost:4502/libs/cq/contentinsight/proxy/reportingservices.json.GET.servlet.a.23 .css

Avatar

Avatar

lmha

Employee

Avatar

lmha

Employee

lmha
Employee

13-07-2018

Hi Kartheek,

The purpose of the ReportingServicesProxyServlet.java servlet (found in the notes directly in the source code):

/**
* A servlet that proxies requests to Reporting Services's API for browsers
* not supporting real CORS, i.e. IE 9 with XDomainRequest.
* <p>
* The API's response code and body are copied to the servlet response.
*/

This SSRF vulnerability is related to Adobe Security Bulletin

Please note that the immediate fix would be to install the corresponding hotfix for your AEM version (if the official patch has not been released yet).

Proactive HF for 6.0 - https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani... 

Proactive HF for 6.1 - https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani...

Pro-active HF for 6.2 - https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani...

Pro-active HF for 6.3 - https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani...

Pro-active HF for 6.4 - https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/compani...

Regards,

Lisa