Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-35953

Use of atlassian-whitelist plugin allows CORS access to origins which it should not

    XMLWordPrintable

Details

    Description

      The ApplicationLinkMatcher class and the SelfUrlMatcher class
      atlassian-whitelist-api-plugin considers a uri that starts with an application link's 'rpcurl' or starts with the current application's URI as a match respectively. When an application or an application link's 'rpcurl' does not contain a trailing '/' (e.g. https://foobar.com) and it does not explicitly specify a port then a uri of a domain that starts with either the current application or a application link's domain (and scheme) is considered valid. For example, if https://foobar.com is a configured application link then https://foobar.com.attacker.domain is matched and allowed.

      The atlassian-whitelist-api-plugin includes a CorsFilter which adds CORS headers to whitelisted origin responses that are under its configured url path (/rest/*). The CORS headers the CorsFilter adds allow CORS requests to be sent with credentials and set a custom content-type header.

      Impact
      Where a context path or a port is not specified for the current application or a application link, an attacker can setup a site such that they can make CORS requests in a victim's browser to confluence's rest api (read and write from confluence's rest api). As the CORS response headers will permit a CORS request with a custom content-type header XSRF/CSRF protection depending upon the content-type header of an incoming request can be bypassed.

      How to fix:
      The in addition to the URI path the scheme, domain and port should be used to check if a uri matches an application link. e.g.
      For ApplicationLinkMatcher

      
          @Override
          public boolean apply(final URI uri)
          {
              try
              {
                  final URI normalizedUri = MatcherUtils.normalizeUri(uri);
                 return (applinkRpcUrl.getHost().equals(normalizedUri.getHost()) && 
      applinkRpcUrl.getScheme().equals(normalizedUri.getScheme()) && 
      applinkRpcUrl.getPort() == normalizedUri.getPort() &&  
      applinkRpcUrl.getPath().equals(uri.getPath()))
      
              }
              catch (URISyntaxException e)
              {
                  return false;
              }
      

      For SelfUrlMatcher:

          @Override
          public boolean apply(final URI uri)
          {
              try
              {
                  final URI normalizedUri = MatcherUtils.normalizeUri(uri);
                  final String baseUrl = Strings.nullToEmpty(applicationProperties.getBaseUrl(UrlMode.CANONICAL));
                 return (baseUrl.getHost().equals(normalizedUri.getHost()) && 
      baseUrl.getScheme().equals(normalizedUri.getScheme()) && 
      baseUrl.getPort() == normalizedUri.getPort() &&  
      baseUrl.getPath().equals(uri.getPath()))
              }
              catch (URISyntaxException e)
              {
                  return false;
              }
          }
      

      Also the URI path comparison check is not overly useful when used in the CorsFilter because "The Origin header includes only the information required to identify the principal that initiated the request (typically the scheme, host, and port of initiating origin). In particular, the Origin header does not contain the path or query portions of the URI included in the Referer header that invade privacy without providing additional security." (http://tools.ietf.org/id/draft-abarth-origin-03.html)

      Note: confluence implicitly trusts itself and so if confluence is configured with an empty context path, e.g. http://confluence.domain.com, then this issue can be exploited without any configured application links.

      Attachments

        Issue Links

          Activity

            People

              mreis Mitermayer Reis
              dblack David Black
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: