CVE-2022-39387 (Java, published 2022-11-04T19:15Z)
Description: value: XWiki OIDC has various tools to manipulate OpenID Connect protocol in XWiki. Prior to version 1.29.1, even if a wiki has an OpenID provider configured through its xwiki.properties, it is possible to provide a third party provider its details through request parameters. One can then bypass the XWiki authentication altogether by specifying its own provider through the oidc.endpoint.* request parameters (or by using an XWiki-based OpenID provider with oidc.xwikiprovider. With the same approach, one could also provide a specific group mapping through oidc.groups.mapping that would make his user automatically part of the XWikiAdminGroup. This issue has been patched, please upgrade to 1.29.1. There is no workaround, an upgrade of the authenticator is required.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-287 \u2014 Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
Repository: https://github.com/xwiki-contrib/oidc
Files changed:
oidc-authenticator/src/main/java/org/xwiki/contrib/oidc/auth/internal/OIDCClientConfiguration.java
oidc-authenticator/src/test/java/org/xwiki/contrib/oidc/auth/internal/OIDCClientConfigurationTest.java
Commit message: OIDC-118: Fix bad handling of request parameters


Vulnerable code:
import org.xwiki.configuration.ConfigurationSource;
    @Inject
    // TODO: store configuration in custom objects
    private ConfigurationSource configuration;

        // Get property from request
        String requestValue = getRequestParameter(key);
        if (requestValue != null) {
            return this.converter.convert(valueClass, requestValue);
        // Get property from request
        String requestValue = getRequestParameter(key);
        if (requestValue != null) {
            return this.converter.convert(def.getClass(), requestValue);
        // If we still don't have any endpoint URI, return null
            return null;

Fixed code:
import org.apache.commons.collections4.SetUtils;
    private static final Set<String> SAFE_PROPERTIES = SetUtils.hashSet(PROP_SKIPPED);

        if (SAFE_PROPERTIES.contains(key)) {
            // Get property from request
            String requestValue = getRequestParameter(key);
            if (requestValue != null) {
                return this.converter.convert(valueClass, requestValue);
            }
        if (SAFE_PROPERTIES.contains(key)) {
            // Get property from request
            String requestValue = getRequestParameter(key);
            if (requestValue != null) {
                return this.converter.convert(def.getClass(), requestValue);
            }
        // If we still don't have any endpoint URI, try the request
            uriString = getRequestParameter(PROPPREFIX_ENDPOINT + hint);
            if (uriString == null) {
                String provider = getRequestParameter(PROP_XWIKIPROVIDER);
                if (provider == null) {
                    return null;
                }

                uri = this.manager.createEndPointURI(provider, hint);
            } else {
                uri = new URI(uriString);
            }
import java.net.MalformedURLException;
import java.net.URL;
import org.xwiki.container.Container;
import org.xwiki.container.servlet.ServletRequest;
import org.xwiki.contrib.oidc.provider.internal.OIDCManager;
import org.xwiki.contrib.oidc.provider.internal.endpoint.TokenOIDCEndpoint;
import org.xwiki.properties.ConverterManager;
import com.xpn.xwiki.web.XWikiServletRequestStub;

import static org.junit.jupiter.api.Assertions.assertFalse;
    @MockComponent
    private Container container;

    @MockComponent
    private OIDCManager manager;

    @MockComponent
    private ConverterManager converterManager;

    }

    @Test
    void getPropertyOrder() throws MalformedURLException, URISyntaxException
    {
        String provider = "http://urlprovider";
        URI urlauthorization = new URI("http://urlauthorization");

        XWikiServletRequestStub requestStub = new XWikiServletRequestStub(new URL("http://url"), null);

        when(this.container.getRequest()).thenReturn(new ServletRequest(requestStub));
        when(this.sourceConfiguration.getProperty(OIDCClientConfiguration.PROP_SKIPPED, false)).thenReturn(false);

        assertFalse(this.configuration.isSkipped());
        assertNull(this.configuration.getXWikiProvider());
        assertNull(this.configuration.getAuthorizationOIDCEndpoint());
        assertNull(this.configuration.getAuthorizationOIDCEndpoint());
        assertNull(this.configuration.getTokenOIDCEndpoint());

        requestStub.put(OIDCClientConfiguration.PROP_SKIPPED, "true");
        when(this.converterManager.convert(Boolean.class, "true")).thenReturn(true);

        assertTrue(this.configuration.isSkipped());

        requestStub.put(OIDCClientConfiguration.PROP_GROUPS_ALLOWED, "true");

        assertNull(this.configuration.getAllowedGroups());

        requestStub.put(OIDCClientConfiguration.PROP_XWIKIPROVIDER, provider.toString());
        requestStub.put(OIDCClientConfiguration.PROP_ENDPOINT_AUTHORIZATION, urlauthorization.toString());
        when(this.manager.createEndPointURI(provider, TokenOIDCEndpoint.HINT)).thenReturn(new URI(provider));
        assertEquals(urlauthorization, this.configuration.getAuthorizationOIDCEndpoint().getURI());
        assertEquals(provider, this.configuration.getTokenOIDCEndpoint().getURI().toString());