import lasso-2.6.0-12.el8

This commit is contained in:
CentOS Sources 2021-10-05 19:51:09 -04:00 committed by Stepan Oksanichenko
parent c64a9babf0
commit 9e2c4c2d1a
3 changed files with 244 additions and 1 deletions

View File

@ -0,0 +1,183 @@
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: [PATCH] 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.
---
lasso/saml-2.0/login.c | 102 +++++++++++++++++++++++++++++------------
1 file changed, 73 insertions(+), 29 deletions(-)
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 0d4bb1da1..cf62c1cc9 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:
--
2.26.3

View File

@ -0,0 +1,38 @@
diff -up lasso-2.5.1/lasso/saml-2.0/login.c.coverity lasso-2.5.1/lasso/saml-2.0/login.c
--- lasso-2.5.1/lasso/saml-2.0/login.c.coverity 2021-07-27 10:23:31.976845852 +0200
+++ lasso-2.5.1/lasso/saml-2.0/login.c 2021-07-27 10:23:55.358913123 +0200
@@ -1371,7 +1371,7 @@ lasso_saml20_login_process_response_stat
char *status_value;
lasso_error_t rc = 0;
lasso_error_t assertion_signature_status = 0;
- LassoProfileSignatureVerifyHint verify_hint;
+ LassoProfileSignatureVerifyHint verify_hint = LASSO_PROFILE_SIGNATURE_VERIFY_HINT_LAST;
profile = &login->parent;
lasso_extract_node_or_fail(response, profile->response, SAMLP2_STATUS_RESPONSE,
@@ -1492,20 +1492,12 @@ lasso_saml20_login_process_response_stat
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:
- break;
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE:
- /* ignore signature errors */
- if (rc == LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE) {
- rc = 0;
- }
- break;
- default:
- g_assert(0);
- }
cleanup:
+ if (verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE &&
+ rc == LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE) {
+ profile->signature_status = rc;
+ rc = 0;
+ }
return rc;
}

View File

@ -58,7 +58,7 @@
Summary: Liberty Alliance Single Sign On Summary: Liberty Alliance Single Sign On
Name: lasso Name: lasso
Version: 2.6.0 Version: 2.6.0
Release: 8%{?dist} Release: 12%{?dist}
License: GPLv2+ License: GPLv2+
Group: System Environment/Libraries Group: System Environment/Libraries
Source: http://dev.entrouvert.org/lasso/lasso-%{version}.tar.gz Source: http://dev.entrouvert.org/lasso/lasso-%{version}.tar.gz
@ -70,6 +70,8 @@ Patch4: versioned-python-configure.patch
Patch5: 0005-tests-use-self-generated-certificate-to-sign-federat.patch Patch5: 0005-tests-use-self-generated-certificate-to-sign-federat.patch
Patch6: 0006-Fix-ECP-signature-not-found-error-when-only-assertio.patch Patch6: 0006-Fix-ECP-signature-not-found-error-when-only-assertio.patch
Patch7: 0007-PAOS-Do-not-populate-Destination-attribute.patch Patch7: 0007-PAOS-Do-not-populate-Destination-attribute.patch
Patch8: 0008-Fix-signature-checking-on-unsigned-response-with-mul.patch
Patch9: 0009-lasso_saml20_login_process_response_status_and_asser.patch
BuildRequires: libtool autoconf automake BuildRequires: libtool autoconf automake
@ -205,6 +207,8 @@ library.
%patch5 -p1 %patch5 -p1
%patch6 -p1 %patch6 -p1
%patch7 -p1 %patch7 -p1
%patch8 -p1
%patch9 -p1
# Remove any python script shebang lines (unless they refer to python3) # Remove any python script shebang lines (unless they refer to python3)
sed -i -E -e '/^#![[:blank:]]*(\/usr\/bin\/env[[:blank:]]+python[^3]?\>)|(\/usr\/bin\/python[^3]?\>)/d' \ sed -i -E -e '/^#![[:blank:]]*(\/usr\/bin\/env[[:blank:]]+python[^3]?\>)|(\/usr\/bin\/python[^3]?\>)/d' \
@ -322,6 +326,24 @@ rm -fr %{buildroot}%{_defaultdocdir}/%{name}
%endif %endif
%changelog %changelog
* Fri Jul 30 2021 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-12
- Fix a dead code issue in the signature wrapping patch
- Resolves: rhbz#1951653 - CVE-2021-28091 lasso: XML signature wrapping
vulnerability when parsing SAML responses [rhel-8]
* Mon Jun 21 2021 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-11
- Bump release to force the package through OSCI as the previous
build reached CI just in time for an outage
- Related: rhbz#1888195 - [RFE] release (built) python3-lasso pkg (comingfrom lasso)
* Fri Jun 4 2021 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-10
- Resolves: rhbz#1951653 - CVE-2021-28091 lasso: XML signature wrapping
vulnerability when parsing SAML responses [rhel-8]
* Thu May 6 2021 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-9
- Resolves: rhbz#1888195 - [RFE] release (built) python3-lasso pkg (coming
from lasso)
* Fri Oct 18 2019 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-8 * Fri Oct 18 2019 Jakub Hrozek <jhrozek@redhat.com> - 2.6.0-8
- Resolves: rhbz#1730018 - lasso includes "Destination" attribute in SAML - Resolves: rhbz#1730018 - lasso includes "Destination" attribute in SAML
AuthnRequest populated with SP AuthnRequest populated with SP