import lasso-2.6.0-12.el8
This commit is contained in:
parent
c64a9babf0
commit
9e2c4c2d1a
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
||||
Summary: Liberty Alliance Single Sign On
|
||||
Name: lasso
|
||||
Version: 2.6.0
|
||||
Release: 8%{?dist}
|
||||
Release: 12%{?dist}
|
||||
License: GPLv2+
|
||||
Group: System Environment/Libraries
|
||||
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
|
||||
Patch6: 0006-Fix-ECP-signature-not-found-error-when-only-assertio.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
|
||||
|
||||
@ -205,6 +207,8 @@ library.
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
|
||||
# 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' \
|
||||
@ -322,6 +326,24 @@ rm -fr %{buildroot}%{_defaultdocdir}/%{name}
|
||||
%endif
|
||||
|
||||
%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
|
||||
- Resolves: rhbz#1730018 - lasso includes "Destination" attribute in SAML
|
||||
AuthnRequest populated with SP
|
||||
|
Loading…
Reference in New Issue
Block a user