!3 fix CVE-2021-28091
From: @tong_1001 Reviewed-by: @xiezhipeng1 Signed-off-by: @xiezhipeng1
This commit is contained in:
commit
51ad1fc37e
179
backport-CVE-2021-28091.patch
Normal file
179
backport-CVE-2021-28091.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From ea7e5efe9741e1b1787a58af16cb15b40c23be5a Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Dauvergne <bdauvergne@entrouvert.com>
|
||||
Date: Mon, 8 Mar 2021 11:33:26 +0100
|
||||
Subject: Fix signature checking on unsigned response with multiple assertions
|
||||
|
||||
CVE-2021-28091 : when AuthnResponse messages are not signed (which is
|
||||
permitted by the specifiation), all assertion's signatures should be
|
||||
checked, but currently after the first signed assertion is checked all
|
||||
following assertions are accepted without checking their signature, and
|
||||
the last one is considered the main assertion.
|
||||
|
||||
This patch :
|
||||
* check signatures from all assertions if the message is not signed,
|
||||
* refuse messages with assertion from different issuers than the one on
|
||||
the message, to prevent assertion bundling event if they are signed.
|
||||
|
||||
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
|
||||
index 0d4bb1d..cf62c1c 100644
|
||||
--- a/lasso/saml-2.0/login.c
|
||||
+++ b/lasso/saml-2.0/login.c
|
||||
@@ -1257,7 +1257,11 @@ lasso_saml20_login_check_assertion_signature(LassoLogin *login,
|
||||
original_node = lasso_node_get_original_xmlnode(LASSO_NODE(assertion));
|
||||
goto_cleanup_if_fail_with_rc(original_node, LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE);
|
||||
|
||||
- rc = profile->signature_status = lasso_provider_verify_saml_signature(remote_provider, original_node, NULL);
|
||||
+ /* Shouldn't set the profile->signature_status here as we're only
|
||||
+ * checking the assertion signature.
|
||||
+ * Instead, we'll set the status after all the assertions are iterated.
|
||||
+ */
|
||||
+ rc = lasso_provider_verify_saml_signature(remote_provider, original_node, NULL);
|
||||
|
||||
#define log_verify_assertion_signature_error(msg) \
|
||||
message(G_LOG_LEVEL_WARNING, "Could not verify signature of assertion" \
|
||||
@@ -1282,18 +1286,6 @@ cleanup:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static gboolean
|
||||
-_lasso_check_assertion_issuer(LassoSaml2Assertion *assertion, const gchar *provider_id)
|
||||
-{
|
||||
- if (! LASSO_SAML2_ASSERTION(assertion) || ! provider_id)
|
||||
- return FALSE;
|
||||
-
|
||||
- if (! assertion->Issuer || ! assertion->Issuer->content)
|
||||
- return FALSE;
|
||||
-
|
||||
- return lasso_strisequal(assertion->Issuer->content,provider_id);
|
||||
-}
|
||||
-
|
||||
static gint
|
||||
_lasso_saml20_login_decrypt_assertion(LassoLogin *login, LassoSamlp2Response *samlp2_response)
|
||||
{
|
||||
@@ -1358,11 +1350,23 @@ _lasso_saml20_login_decrypt_assertion(LassoLogin *login, LassoSamlp2Response *sa
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Verify that an assertion comes from a designated Issuer */
|
||||
+static gboolean
|
||||
+_lasso_check_assertion_issuer(LassoSaml2Assertion *assertion, const gchar *provider_id)
|
||||
+{
|
||||
+ if (! LASSO_SAML2_ASSERTION(assertion) || ! provider_id)
|
||||
+ return FALSE;
|
||||
+ if (! assertion->Issuer || ! assertion->Issuer->content)
|
||||
+ return FALSE;
|
||||
+ return lasso_strisequal(assertion->Issuer->content,provider_id);
|
||||
+}
|
||||
+
|
||||
static gint
|
||||
lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
|
||||
{
|
||||
LassoSamlp2StatusResponse *response;
|
||||
LassoSamlp2Response *samlp2_response = NULL;
|
||||
+ LassoSaml2Assertion *last_assertion = NULL;
|
||||
LassoProfile *profile;
|
||||
char *status_value;
|
||||
lasso_error_t rc = 0;
|
||||
@@ -1404,34 +1408,62 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
|
||||
|
||||
/* Decrypt all EncryptedAssertions */
|
||||
_lasso_saml20_login_decrypt_assertion(login, samlp2_response);
|
||||
- /* traverse all assertions */
|
||||
- goto_cleanup_if_fail_with_rc (samlp2_response->Assertion != NULL,
|
||||
- LASSO_PROFILE_ERROR_MISSING_ASSERTION);
|
||||
|
||||
+ /* Check there is at least one assertion */
|
||||
+ goto_cleanup_if_fail_with_rc (samlp2_response->Assertion != NULL, LASSO_PROFILE_ERROR_MISSING_ASSERTION);
|
||||
+
|
||||
+ /* In case of verify_hint as 'FORCE', if there's no response signature,
|
||||
+ * we reject.
|
||||
+ * In case of 'MAYBE', if response signature is present and valid, or
|
||||
+ * not present, then we proceed with checking assertion signature(s).
|
||||
+ * In any case, if there's a response signature and it's not valid,
|
||||
+ * we reject.
|
||||
+ */
|
||||
verify_hint = lasso_profile_get_signature_verify_hint(profile);
|
||||
+ if (profile->signature_status == LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
|
||||
+ if (verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE) {
|
||||
+ goto_cleanup_with_rc(profile->signature_status);
|
||||
+ }
|
||||
+ } else if (profile->signature_status != 0) {
|
||||
+ goto_cleanup_with_rc(profile->signature_status);
|
||||
+ }
|
||||
|
||||
lasso_foreach_full_begin(LassoSaml2Assertion*, assertion, it, samlp2_response->Assertion);
|
||||
LassoSaml2Subject *subject = NULL;
|
||||
|
||||
- lasso_assign_gobject (login->private_data->saml2_assertion, assertion);
|
||||
+ /* All Assertions MUST come from the same issuer as the Response. */
|
||||
+ if (! _lasso_check_assertion_issuer(assertion, profile->remote_providerID)) {
|
||||
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_ISSUER);
|
||||
+ }
|
||||
|
||||
- /* If signature has already been verified on the message, and assertion has the same
|
||||
- * issuer as the message, the assertion is covered. So no need to verify a second
|
||||
- * time */
|
||||
- if (profile->signature_status != 0
|
||||
- || ! _lasso_check_assertion_issuer(assertion,
|
||||
- profile->remote_providerID)
|
||||
- || verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE) {
|
||||
+ if (profile->signature_status != 0) {
|
||||
+ /* When response signature is not present */
|
||||
+ if (verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE) {
|
||||
+ assertion_signature_status =
|
||||
+ lasso_saml20_login_check_assertion_signature(login, assertion);
|
||||
+ if (assertion_signature_status) {
|
||||
+ goto_cleanup_with_rc(assertion_signature_status);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* response signature is present and valid */
|
||||
assertion_signature_status = lasso_saml20_login_check_assertion_signature(login,
|
||||
- assertion);
|
||||
- /* If signature validation fails, it is the return code for this function */
|
||||
+ assertion);
|
||||
if (assertion_signature_status) {
|
||||
- rc = LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE;
|
||||
+ /* assertion signature is not valid or not present */
|
||||
+ if (verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE) {
|
||||
+ /* In case of FORCE, we reject right away */
|
||||
+ goto_cleanup_with_rc(assertion_signature_status);
|
||||
+ } else if (verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE) {
|
||||
+ /* In case of MAYBE, if assertion signature is present and invalid, then we reject */
|
||||
+ if (assertion_signature_status != LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
|
||||
+ goto_cleanup_with_rc(assertion_signature_status);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
-
|
||||
lasso_extract_node_or_fail(subject, assertion->Subject, SAML2_SUBJECT,
|
||||
- LASSO_PROFILE_ERROR_MISSING_SUBJECT);
|
||||
+ LASSO_PROFILE_ERROR_MISSING_SUBJECT);
|
||||
|
||||
/* Verify Subject->SubjectConfirmationData->InResponseTo */
|
||||
if (login->private_data->request_id) {
|
||||
@@ -1446,8 +1478,20 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
|
||||
/** Handle nameid */
|
||||
lasso_check_good_rc(lasso_saml20_profile_process_name_identifier_decryption(profile,
|
||||
&subject->NameID, &subject->EncryptedID));
|
||||
+
|
||||
+ last_assertion = assertion;
|
||||
lasso_foreach_full_end();
|
||||
|
||||
+ /* set the profile signature status only after all the signatures are
|
||||
+ * verified.
|
||||
+ */
|
||||
+ profile->signature_status = rc;
|
||||
+
|
||||
+ /* set the default assertion to the last one */
|
||||
+ if (last_assertion) {
|
||||
+ lasso_assign_gobject (login->private_data->saml2_assertion, last_assertion);
|
||||
+ }
|
||||
+
|
||||
switch (verify_hint) {
|
||||
case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE:
|
||||
case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE:
|
||||
--
|
||||
cgit v0.10.2
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: lasso
|
||||
Version: 2.6.0
|
||||
Release: 12
|
||||
Release: 13
|
||||
Summary: Liberty Alliance Single Sign On
|
||||
License: GPLv2+
|
||||
URL: http://lasso.entrouvert.org/
|
||||
@ -11,6 +11,8 @@ Patch2: build-scripts-py3-compatible.patch
|
||||
Patch3: duplicate-python-LogoutTestCase.patch
|
||||
patch4: versioned-python-configure.patch
|
||||
Patch5: 0005-tests-Remove-the-use-of-an-expired-cert-in-tests-as-.patch
|
||||
Patch6000: backport-CVE-2021-28091.patch
|
||||
|
||||
BuildRequires: autoconf automake check-devel glib2-devel gtk-doc libtool
|
||||
BuildRequires: libxml2-devel openssl-devel swig xmlsec1-devel >= 1.2.25-4
|
||||
BuildRequires: xmlsec1-openssl-devel >= 1.2.25-4 zlib-devel jpackage-utils
|
||||
@ -113,6 +115,9 @@ fi
|
||||
%doc AUTHORS NEWS README
|
||||
|
||||
%changelog
|
||||
* Sat Jul 10 2021 shixuantong <shixuantong@huawei.com> - 2.6.0-13
|
||||
- fix CVE-2021-28091
|
||||
|
||||
* Wed Oct 21 2020 Ge Wang <wangge20@huawei.com> - 2.6.0-12
|
||||
- remove python2
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user