From 25c401c6532a2930cc568b45d2a8b6e2a319fa39 Mon Sep 17 00:00:00 2001 From: Jonathan Perret Date: Mon, 22 Jul 2024 20:28:08 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F(saml)=20check=20the=20sco?= =?UTF-8?q?pe=20of=20the=20eduPersonPrincipalName=20attribute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The metadata obtained from the federation server contains a list of allowed scopes for each of the registered identity providers. By checking the value of the eduPersonPrincipalName attribute returned by an IdP against the allowed scopes for that IdP, we protect the downstream services against identity theft by a compromised IdP. --- CHANGELOG.md | 1 + src/satosa/internal_attributes.yaml | 2 +- .../microservices/attribute_authorization.yaml | 7 +++++++ .../plugins/microservices/filter_attributes.yaml | 12 ++++++++++++ .../plugins/microservices/primary_identifier.yaml | 2 +- src/satosa/proxy_conf.yaml | 1 + src/satosa/tests/test_e2e.py | 2 +- 7 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/satosa/plugins/microservices/filter_attributes.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e47641..bc2534c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- check the scope of returned eduPersonPrincipalNames - require "employee" value in eduPersonAffiliation ## [1.0.1] - 2024-06-04 diff --git a/src/satosa/internal_attributes.yaml b/src/satosa/internal_attributes.yaml index 94653d9..6a76b29 100644 --- a/src/satosa/internal_attributes.yaml +++ b/src/satosa/internal_attributes.yaml @@ -22,7 +22,7 @@ attributes: acr: openid: - acr - eppn: + eduPersonPrincipalName: saml: - eduPersonPrincipalName eduPersonAffiliation: diff --git a/src/satosa/plugins/microservices/attribute_authorization.yaml b/src/satosa/plugins/microservices/attribute_authorization.yaml index 30484f1..cf1a67b 100644 --- a/src/satosa/plugins/microservices/attribute_authorization.yaml +++ b/src/satosa/plugins/microservices/attribute_authorization.yaml @@ -5,5 +5,12 @@ config: attribute_allow: default: # any requester (SP/RP) default: # any issuer (IdP/OP) + eduPersonPrincipalName: + # The eduPersonPrincipalName value may have been filtered by the + # AttributeFilter processor, if it did not match an expected scope + # for the IdP. + # We require it to be non-empty here, to avoid an unhandled error + # later in the PrimaryIdentifier processor. + - ".+" eduPersonAffiliation: - "^employee$" diff --git a/src/satosa/plugins/microservices/filter_attributes.yaml b/src/satosa/plugins/microservices/filter_attributes.yaml new file mode 100644 index 0000000..fd25047 --- /dev/null +++ b/src/satosa/plugins/microservices/filter_attributes.yaml @@ -0,0 +1,12 @@ +module: satosa.micro_services.attribute_modifications.FilterAttributeValues +name: AttributeFilter +config: + attribute_filters: + # default rules for any IdentityProvider + "": + # default rules for any requester + "": + eduPersonPrincipalName: + # enforce correct scope (the part after '@' must match one + # of the scopes declared in the metadata) + shibmdscope_match_scope: diff --git a/src/satosa/plugins/microservices/primary_identifier.yaml b/src/satosa/plugins/microservices/primary_identifier.yaml index 6616798..d9127c0 100644 --- a/src/satosa/plugins/microservices/primary_identifier.yaml +++ b/src/satosa/plugins/microservices/primary_identifier.yaml @@ -7,7 +7,7 @@ config: # names are the internal SATOSA names for the attributes as # defined in internal_attributes.yaml. ordered_identifier_candidates: - - attribute_names: [eppn] + - attribute_names: [eduPersonPrincipalName] # The internal SATOSA attribute into which to place the primary # identifier value once found from the above configured ordered diff --git a/src/satosa/proxy_conf.yaml b/src/satosa/proxy_conf.yaml index 1c401da..c6bcca1 100644 --- a/src/satosa/proxy_conf.yaml +++ b/src/satosa/proxy_conf.yaml @@ -12,6 +12,7 @@ FRONTEND_MODULES: - plugins/frontends/openid_connect_frontend.yaml - plugins/frontends/ping_frontend.yaml MICRO_SERVICES: + - plugins/microservices/filter_attributes.yaml - plugins/microservices/attribute_authorization.yaml - plugins/microservices/primary_identifier.yaml - plugins/microservices/static_attributes.yaml diff --git a/src/satosa/tests/test_e2e.py b/src/satosa/tests/test_e2e.py index 1da92a6..a591790 100644 --- a/src/satosa/tests/test_e2e.py +++ b/src/satosa/tests/test_e2e.py @@ -125,4 +125,4 @@ def test_agent_connect_to_renater_student_not_allowed(page: Page): renater_wayf(page) renater_test_idp(page, login="etudiant1") - expect(page.locator("body")).to_contain_text("access_denied") + expect(page.locator("body")).to_contain_text("Une erreur technique est survenue.")