VYPR
High severity8.8NVD Advisory· Published Nov 30, 2017· Updated May 13, 2026

CVE-2017-12631

CVE-2017-12631

Description

Apache CXF Fediz ships with a number of container-specific plugins to enable WS-Federation for applications. A CSRF (Cross Style Request Forgery) style vulnerability has been found in the Spring 2, Spring 3 and Spring 4 plugins in versions before 1.4.3 and 1.3.3. The vulnerability can result in a security context that is set up using a malicious client's roles for the given enduser.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.cxf.fediz:fediz-spring2Maven
< 1.3.31.3.3
org.apache.cxf.fediz:fediz-spring2Maven
>= 1.4.0, < 1.4.31.4.3
org.apache.cxf.fediz:fediz-spring3Maven
< 1.3.31.3.3
org.apache.cxf.fediz:fediz-spring3Maven
>= 1.4.0, < 1.4.31.4.3
org.apache.cxf.fediz:fediz-springMaven
< 1.3.31.3.3
org.apache.cxf.fediz:fediz-springMaven
>= 1.4.0, < 1.4.31.4.3

Affected products

5
  • Apache Software Foundation/Apache CXF Fedizv5
    Range: 1.4.x prior to 1.4.3
  • Apache/Cxf Fediz4 versions
    cpe:2.3:a:apache:cxf_fediz:*:*:*:*:*:*:*:*+ 3 more
    • cpe:2.3:a:apache:cxf_fediz:*:*:*:*:*:*:*:*range: <1.3.3
    • cpe:2.3:a:apache:cxf_fediz:1.4.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:cxf_fediz:1.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:cxf_fediz:1.4.2:*:*:*:*:*:*:*

Patches

2
ccdb12b26ff8

Some improvements to the Spring plugins

https://github.com/apache/cxf-fedizColm O hEigeartaighOct 6, 2017via ghsa
6 files changed · +94 14
  • plugins/spring3/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java+12 7 modified
    @@ -128,14 +128,19 @@ private String getState(ServletRequest request) {
     
         private void verifySavedState(HttpServletRequest request) {
             HttpSession session = request.getSession(false);
    -        if (session != null) {
    -            String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    -            String state = getState(request);
    -            if (savedContext != null && !savedContext.equals(state)) {
    -                logger.warn("The received state does not match the state saved in the context");
    -                throw new BadCredentialsException("The received state does not match the state saved in the context");
    -            }
    +
    +        if (session == null) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
    +        }
    +
    +        String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    +        String state = getState(request);
    +        if (savedContext == null || !savedContext.equals(state)) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
             }
    +        session.removeAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
         }
     
         /**
    
  • plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java+12 7 modified
    @@ -128,14 +128,19 @@ private String getState(ServletRequest request) {
     
         private void verifySavedState(HttpServletRequest request) {
             HttpSession session = request.getSession(false);
    -        if (session != null) {
    -            String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    -            String state = getState(request);
    -            if (savedContext != null && !savedContext.equals(state)) {
    -                logger.warn("The received state does not match the state saved in the context");
    -                throw new BadCredentialsException("The received state does not match the state saved in the context");
    -            }
    +
    +        if (session == null) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
    +        }
    +
    +        String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    +        String state = getState(request);
    +        if (savedContext == null || !savedContext.equals(state)) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
             }
    +        session.removeAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
         }
     
         /**
    
  • systests/spring/src/test/java/org/apache/cxf/fediz/integrationtests/Spring3Test.java+8 0 modified
    @@ -159,4 +159,12 @@ public void testCSRFAttack() throws Exception {
             csrfAttackTest(url);
         }
     
    +    @Override
    +    @org.junit.Test
    +    public void testCSRFAttack2() throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName()
    +            + "/j_spring_fediz_security_check";
    +        csrfAttackTest2(url);
    +    }
    +
     }
    
  • systests/spring/src/test/java/org/apache/cxf/fediz/integrationtests/SpringTest.java+8 0 modified
    @@ -157,4 +157,12 @@ public void testCSRFAttack() throws Exception {
                 + "/j_spring_fediz_security_check";
             csrfAttackTest(url);
         }
    +
    +    @Override
    +    @org.junit.Test
    +    public void testCSRFAttack2() throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName()
    +            + "/j_spring_fediz_security_check";
    +        csrfAttackTest2(url);
    +    }
     }
    
  • systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java+53 0 modified
    @@ -799,4 +799,57 @@ protected void csrfAttackTest(String rpURL) throws Exception {
     
         }
     
    +    @org.junit.Test
    +    public void testCSRFAttack2() throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet";
    +        csrfAttackTest2(url);
    +    }
    +
    +    protected void csrfAttackTest2(String rpURL) throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet";
    +
    +        // 1. Log in as "bob" using another WebClient
    +        WebClient webClient2 = new WebClient();
    +        webClient2.getOptions().setUseInsecureSSL(true);
    +        webClient2.getCredentialsProvider().setCredentials(
    +            new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())),
    +            new UsernamePasswordCredentials("bob", "bob"));
    +
    +        webClient2.getOptions().setJavaScriptEnabled(false);
    +        final HtmlPage idpPage2 = webClient2.getPage(url);
    +        webClient2.getOptions().setJavaScriptEnabled(true);
    +        Assert.assertEquals("IDP SignIn Response Form", idpPage2.getTitleText());
    +
    +        // 2. Now instead of clicking on the form, send the form via alice's WebClient instead
    +
    +        // Send with context...
    +        WebRequest request = new WebRequest(new URL(rpURL), HttpMethod.POST);
    +        request.setRequestParameters(new ArrayList<NameValuePair>());
    +
    +        DomNodeList<DomElement> results = idpPage2.getElementsByTagName("input");
    +
    +        for (DomElement result : results) {
    +            if ("wresult".equals(result.getAttributeNS(null, "name"))
    +                || "wa".equals(result.getAttributeNS(null, "name"))
    +                || "wctx".equals(result.getAttributeNS(null, "name"))) {
    +                String value = result.getAttributeNS(null, "value");
    +                request.getRequestParameters().add(new NameValuePair(result.getAttributeNS(null, "name"), value));
    +            }
    +        }
    +
    +        WebClient webClient = new WebClient();
    +        webClient.getOptions().setUseInsecureSSL(true);
    +
    +        try {
    +            webClient.getPage(request);
    +            Assert.fail("Failure expected on a CSRF attack");
    +        } catch (FailingHttpStatusCodeException ex) {
    +            // expected
    +        }
    +
    +        webClient.close();
    +        webClient2.close();
    +
    +    }
    +
     }
    
  • systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml+1 0 modified
    @@ -37,6 +37,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/sch
             <sec:intercept-url pattern="/index.html" access="permitAll"/>
             <sec:intercept-url pattern="/FederationMetadata/**" access="isAuthenticated()"/>
             <sec:intercept-url pattern="/secure/fedservlet" access="isAuthenticated()"/>
    +        <sec:intercept-url pattern="/secure/test.html" access="isAuthenticated()"/>
             <sec:intercept-url pattern="/secure/manager/**" access="hasRole('ROLE_MANAGER')"/>
             <sec:intercept-url pattern="/secure/admin/**" access="hasRole('ROLE_ADMIN')"/>
             <sec:intercept-url pattern="/secure/user/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_MANAGER')"/>
    
48dd9b68d67c

Some improvements to the Spring plugins

https://github.com/apache/cxf-fedizColm O hEigeartaighOct 6, 2017via ghsa
4 files changed · +73 7
  • plugins/spring/src/main/java/org/apache/cxf/fediz/spring/web/FederationAuthenticationFilter.java+12 7 modified
    @@ -128,14 +128,19 @@ private String getState(ServletRequest request) {
     
         private void verifySavedState(HttpServletRequest request) {
             HttpSession session = request.getSession(false);
    -        if (session != null) {
    -            String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    -            String state = getState(request);
    -            if (savedContext != null && !savedContext.equals(state)) {
    -                logger.warn("The received state does not match the state saved in the context");
    -                throw new BadCredentialsException("The received state does not match the state saved in the context");
    -            }
    +
    +        if (session == null) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
    +        }
    +
    +        String savedContext = (String)session.getAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
    +        String state = getState(request);
    +        if (savedContext == null || !savedContext.equals(state)) {
    +            logger.warn("The received state does not match the state saved in the context");
    +            throw new BadCredentialsException("The received state does not match the state saved in the context");
             }
    +        session.removeAttribute(FederationAuthenticationEntryPoint.SAVED_CONTEXT);
         }
         
         /**
    
  • systests/spring/src/test/java/org/apache/cxf/fediz/integrationtests/SpringTest.java+8 0 modified
    @@ -157,4 +157,12 @@ public void testCSRFAttack() throws Exception {
                 + "/j_spring_fediz_security_check";
             csrfAttackTest(url);
         }
    +
    +    @Override
    +    @org.junit.Test
    +    public void testCSRFAttack2() throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName()
    +            + "/j_spring_fediz_security_check";
    +        csrfAttackTest2(url);
    +    }
     }
    
  • systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java+52 0 modified
    @@ -803,4 +803,56 @@ protected void csrfAttackTest(String rpURL) throws Exception {
             
         }
         
    +    @org.junit.Test
    +    public void testCSRFAttack2() throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet";
    +        csrfAttackTest2(url);
    +    }
    +
    +    protected void csrfAttackTest2(String rpURL) throws Exception {
    +        String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet";
    +
    +        // 1. Log in as "bob" using another WebClient
    +        WebClient webClient2 = new WebClient();
    +        webClient2.getOptions().setUseInsecureSSL(true);
    +        webClient2.getCredentialsProvider().setCredentials(
    +            new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())),
    +            new UsernamePasswordCredentials("bob", "bob"));
    +
    +        webClient2.getOptions().setJavaScriptEnabled(false);
    +        final HtmlPage idpPage2 = webClient2.getPage(url);
    +        webClient2.getOptions().setJavaScriptEnabled(true);
    +        Assert.assertEquals("IDP SignIn Response Form", idpPage2.getTitleText());
    +
    +        // 2. Now instead of clicking on the form, send the form via alice's WebClient instead
    +
    +        // Send with context...
    +        WebRequest request = new WebRequest(new URL(rpURL), HttpMethod.POST);
    +        request.setRequestParameters(new ArrayList<NameValuePair>());
    +
    +        DomNodeList<DomElement> results = idpPage2.getElementsByTagName("input");
    +
    +        for (DomElement result : results) {
    +            if ("wresult".equals(result.getAttributeNS(null, "name"))
    +                || "wa".equals(result.getAttributeNS(null, "name"))
    +                || "wctx".equals(result.getAttributeNS(null, "name"))) {
    +                String value = result.getAttributeNS(null, "value");
    +                request.getRequestParameters().add(new NameValuePair(result.getAttributeNS(null, "name"), value));
    +            }
    +        }
    +
    +        WebClient webClient = new WebClient();
    +        webClient.getOptions().setUseInsecureSSL(true);
    +
    +        try {
    +            webClient.getPage(request);
    +            Assert.fail("Failure expected on a CSRF attack");
    +        } catch (FailingHttpStatusCodeException ex) {
    +            // expected
    +        }
    +
    +        // webClient.close();
    +        // webClient2.close();
    +
    +    }
     }
    
  • systests/webapps/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml+1 0 modified
    @@ -37,6 +37,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/sch
             <sec:intercept-url pattern="/index.html" access="permitAll"/>
             <sec:intercept-url pattern="/FederationMetadata/**" access="isAuthenticated()"/>
             <sec:intercept-url pattern="/secure/fedservlet" access="isAuthenticated()"/>
    +        <sec:intercept-url pattern="/secure/test.html" access="isAuthenticated()"/>
             <sec:intercept-url pattern="/secure/manager/**" access="hasRole('ROLE_MANAGER')"/>
             <sec:intercept-url pattern="/secure/admin/**" access="hasRole('ROLE_ADMIN')"/>
             <sec:intercept-url pattern="/secure/user/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_MANAGER')"/>
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

21

News mentions

0

No linked articles in our index yet.