Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2021-3827: KEYCLOAK-19177 Disable ECP flow by default for all Saml clients; ecp … · keycloak/keycloak@44000ca

A flaw was found in keycloak, where the default ECP binding flow allows other authentication flows to be bypassed. By exploiting this behavior, an attacker can bypass the MFA authentication by sending a SOAP request with an AuthnRequest and Authorization header with the user’s credentials. The highest threat from this vulnerability is to confidentiality and integrity.

CVE
#vulnerability#java#auth

@@ -17,17 +17,34 @@ package org.keycloak.testsuite.saml;
import org.junit.Test; import org.keycloak.dom.saml.v2.SAML2Object; import org.keycloak.dom.saml.v2.assertion.AuthnStatementType; import org.keycloak.dom.saml.v2.protocol.ResponseType; import org.keycloak.dom.saml.v2.protocol.StatusResponseType; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; import org.keycloak.protocol.saml.SamlConfigAttributes; import org.keycloak.saml.common.constants.JBossSAMLURIConstants; import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder; import org.keycloak.testsuite.updaters.ClientAttributeUpdater; import org.keycloak.testsuite.util.SamlClientBuilder;
import javax.ws.rs.core.Response; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; import static org.hamcrest.Matchers.nullValue; import static org.keycloak.testsuite.util.Matchers.isSamlResponse; import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC; import static org.keycloak.testsuite.util.SamlClient.Binding.POST; import static org.keycloak.testsuite.util.SamlClient.Binding.SOAP;
@@ -214,4 +231,64 @@ public void soapBindingLogoutWithoutSignatureMissingDestinationTest() {
assertThat(response.getSamlObject(), instanceOf(StatusResponseType.class)); }
@Test public void soapBindingIsNotPossibleForClientsWithSamlEcpFlowAttributeFalse() { // Disable ECP_FLOW_ENABLED switch getCleanup().addCleanup(ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_ECP_SP) .setAttribute(SamlConfigAttributes.SAML_ALLOW_ECP_FLOW, “false”) .setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, “false”) .setAttribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, “false”) .update());
new SamlClientBuilder() .authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_ECP_SP, SAML_ASSERTION_CONSUMER_URL_ECP_SP, SOAP) .basicAuthentication(bburkeUser) .build() .execute(response -> { assertThat(response, statusCodeIsHC(Response.Status.INTERNAL_SERVER_ERROR));
try { MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage soapMessage = messageFactory.createMessage(null, response.getEntity().getContent()); String faultDetail = soapMessage.getSOAPBody().getFault().getDetail().getValue(); assertThat(faultDetail, is(equalTo(“Client is not allowed to use ECP profile.”))); } catch (SOAPException | IOException e) { throw new RuntimeException(e); } });
}
@Test public void ecpFlowCreatesTransientSessions() { // Disable ECP_FLOW_ENABLED switch getCleanup().addCleanup(ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_ECP_SP) .setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE, “false”) .setAttribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, “false”) .update());
// Successfully login using ECP flow SAML2Object samlObject = new SamlClientBuilder() .authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_ECP_SP, SAML_ASSERTION_CONSUMER_URL_ECP_SP, SOAP) .basicAuthentication(bburkeUser) .build() .executeAndTransform(SOAP::extractResponse).getSamlObject();
assertThat(samlObject, isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS)); ResponseType loginResp1 = (ResponseType) samlObject; AuthnStatementType sessionId = (AuthnStatementType) loginResp1.getAssertions().get(0).getAssertion().getStatements().iterator().next();
String userSessionId = sessionId.getSessionIndex().split(“::”)[0];
// Test that the user session with the given ID does not exist testingClient.server().run(session -> { RealmModel realmByName = session.realms().getRealmByName(REALM_NAME); UserSessionModel userSession = session.sessions().getUserSession(realmByName, userSessionId);
assertThat(userSession, nullValue()); });

} }

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda