WP Manifestindependent plugin directory
manifest / users / pressbooks-saml-sso

Pressbooks SAML2 Single Sign-On WP Registry grade F. Critical findings · 2 findingsWP RegistryCritical findings · 2 findingsOpen the reportF #3 in Users & Membership

SAML2 Single Sign-On integration for Pressbooks (Shibboleth, ADFS, Google Apps, Etc.)

★ 3stars
22krelease downloads
≈560active sites
8composer installs
2.7.0latest · 7mo ago

Install

Download pressbooks-saml-sso-2.6.0.zip From the 2.6.0 release on GitHub, Jan 20, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/pressbooks/pressbooks-saml-sso/releases/download/2.6.0/pressbooks-saml-sso-2.6.0.zip

On Packagist as pressbooks/pressbooks-shibboleth-sso:

composer require pressbooks/pressbooks-shibboleth-sso
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

SAML2 Single Sign-On integration for Pressbooks.

Description

Plugin to integrate Pressbooks with a SAML2 single sign-on service. (Shibboleth, Microsoft ADFS, Google Apps, Etc.)

Users who attempt to login to Pressbooks are redirected to a Shibboleth or SAML2 Identity Provider. After the user’s credentials are verified, they are redirected back to the Pressbooks network. If we match a Pressbooks user by UID ( stored in user_meta table), the user is recognized as valid and allowed access. If no match, then try to match a Pressbooks user by email (and store a successful match in user_meta table for next time). If the user does not have an account in Pressbooks, a new user can be created, or access can be refused, depending on the configuration.

Limitations: This plugin does not enable authentication with multilateral Shibboleth. For use in a non-federated, bilateral configuration, with a single IdP.

Installation

composer require pressbooks/pressbooks-saml-sso

Or, download the latest version from the releases page and unzip it into your WordPress plugin directory: https://github.com/pressbooks/pressbooks-saml-sso/releases

Then, create the necessary certificates:

cd vendor/onelogin/php-saml/certs
openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out sp.crt -keyout sp.key

Then, activate and configure the plugin at the Network level.

Security Considerations

Generating certificates in vendor/onelogin/php-saml/certs, without further changes, will expose them to malicious users (Ie. https://path/to/vendor/onelogin/php-saml/certs/sp.crt). Furthermore, your certificates are at risk of being deleted when updating packages using composer update or similar commands. A competent sysadmin must make sure certificates are not accessible from the internet nor deleted. It is highly recommended that you pass your certificates via configuration variables. Example:

add_filter( 'pb_saml_auth_settings', function( $config ) {
    $config['sp']['x509cert'] = file_get_contents( '/path/to/sp.key' );
    $config['sp']['privateKey'] = file_get_contents( '/path/to/sp.crt' );
    return $config;
} );

Or:

define( 'PHP_SAML_SP_KEY_PATH', '/path/to/sp.key' );
define( 'PHP_SAML_SP_CERT_PATH', '/path/to/sp.crt' );

IdP Setup

Upon activation of the plugin, a submenu item ("SAML2") is added to the Network Admin interface under "Integrations". This leads to the SAML2 settings page. Your metadata XML can be downloaded from this page.

The plugin requires the Assertion elements of the Response to be signed.

The plugin looks for the following Attributes in the Response:

  • Requires: urn:oid:0.9.2342.19200300.100.1.1 (samAccountName or equivalent, ideally with FriendlyName uid)
  • Strongly recommends: urn:oid:0.9.2342.19200300.100.1.3 (email-address or equivalent, ideally with FriendlyName mail). If no value is available we fall back to uid@127.0.0.1
  • Optional: urn:oid:1.3.6.1.4.1.5923.1.1.1.6 (eduPersonPrincipalName or equivalent). Upon the first launch for a given user, if mail cannot match an existing person, and this value is present, we'll try to use it.

The email can be filtered, example: add_filter( 'pb_integrations_multidomain_email', function( $email, $uid, $plugin ) { /* Custom use case, return $email */ }, 10, 3 );

Because this plugin uses the fabulous onelogin/php-saml toolkit, many other configuration variables can be tweaked.

Using a test IdP SAML app

If you want to test the plugin with a test IdP, you can use Auth0. Here are the steps to create a test IdP application:

  1. Create an Auth0 account (or ask the Operation Team for a test account).
  2. Create a new application in the Auth0 dashboard.
  3. Select "Regular Web Applications" as the application type.
  4. Go to the "Settings" tab of your application.
  5. Scroll down to the "Advanced Settings" section and click on "Ednpoints" tab.
  6. Copy the "SAML Metadata URL" and paste it on Pressbooks SAML2 settings page, in the "IdP metadata URL" field and save the changes.
  7. In Auth0, go to the "Addons" tab of your application, and click on "SAML2 Web App".
  8. In the Settings tab, under the Application Callback URL, add: https://<NETWORK_DOMAIN>/wp/wp-login.php?action=pb_shibboleth_acs
  9. In the PB Admin area, go to Integrations > SAML2 and click under the "Metadata XML Configuration" link displayed at the top of the page.
  10. Locate the EntityID value inside the <md:EntityDescriptor> tag in your metadata XML. You’ll use this value as the audience in the next step.
  11. Update your Auth0 Settings JSON to include the following configuration. Be sure to:
  • Replace <URL_ENTITY_ID_FROM_METADATA_XML> with the actual EntityID you copied.
  • Replace <NETWORK_DOMAIN> with the domain of your Pressbooks instance.
    {
        "audience": "<URL_ENTITY_ID_FROM_METADATA_XML>",
        "recipient": "https://<NETWORK_DOMAIN>/wp/wp-login.php?action=pb_shibboleth_acs",
        "mappings": {
            "user_id": "urn:oid:0.9.2342.19200300.100.1.1",
            "email": "urn:oid:0.9.2342.19200300.100.1.3",
            "name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
            "given_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
            "family_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
            "upn": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
            "groups": "http://schemas.xmlsoap.org/claims/Group"
        },
        "createUpnClaim": true,
        "passthroughClaimsWithNoMapping": true,
        "logout": {
            "slo_enabled": true,
            "callback": "https://<NETWORK_DOMAIN>/wp/wp-login.php?action=pb_shibboleth_sls"
        },
        "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    }

    Make sure you are using the correct NETWORK_DOMAIN for your Pressbooks instance.

  1. Save the changes in Auth0.
  2. Create a new user in the "User Management" section of the Auth0 dashboard.
  3. Now you can log in using the new user you created in Auth0. Go to your Pressbooks instance and click on the "Login with SAML" button.

Sending logs

If you use AWS and want to log SAML attempts on your server, you will need define some environment variables on the server which is hosting your Pressbooks instance.

AWS S3

Define the following environment variables:

  LOG_LOGIN_ATTEMPTS (setting this value to true will enable this feature at the infrastructure level)
  AWS_ACCESS_KEY_ID
  AWS_SECRET_ACCESS_KEY
  AWS_S3_OIDC_BUCKET
  AWS_S3_REGION
  AWS_S3_VERSION

After these variables have been properly defined, basic information about SAML login attempts will be logged to your S3 bucket. A new CSV file will be created each month so that the logs remain readable. Log storage will take place in a folder structure that looks like this S3 Bucket > saml_logs > {ENVIRONMENT} > {Network URL hashed though wp_hash function} > {YYYY-MM} > saml_logs.log.

AWS CloudWatch Logs

Define the following envirnoment variables:

  LOG_LOGIN_ATTEMPTS (setting this value to true will enable this feature at the infrastructure level)
  AWS_ACCESS_KEY_ID
  AWS_SECRET_ACCESS_KEY
  AWS_S3_REGION
  AWS_S3_VERSION

After these variables have been properly defined, basic information about SAML login attempts will be logged in your AWS CloudWatch Logs service in JSON format. You will need to create a new Log group called pressbooks-logs.

Screenshots

SAML2 Administration.

Metadata XML.

Changelog

Please see the CHANGELOG file for more information.

Releases

Newest 25 of 31 recorded releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
2.7.0 latest
Mar 16, 2026 7mo ago
tag only
—
Jan 20, 2026 9mo ago
pressbooks-saml-sso-2.6.0.zip
279
May 13, 2025 1 year ago
pressbooks-saml-sso-2.5.3.zip
528
Apr 10, 2025 1 year ago
pressbooks-saml-sso-2.5.2.zip
559
Jun 12, 2024 2 years ago
pressbooks-saml-sso-2.5.1.zip
768
Apr 10, 2024 2 years ago
pressbooks-saml-sso-2.5.0.zip
765
Oct 26, 2023 2 years ago
pressbooks-saml-sso-2.4.1.zip
769
Jun 16, 2023 3 years ago
pressbooks-saml-sso-2.4.0.zip
770
Mar 8, 2023 3 years ago
pressbooks-saml-sso-2.3.0.zip
769
Nov 20, 2022 3 years ago
pressbooks-saml-sso-2.2.0.zip
774
Oct 31, 2022 3 years ago
pressbooks-saml-sso-2.1.0.zip
776
Sep 20, 2022 4 years ago
pressbooks-saml-sso-2.0.0.zip
785
May 3, 2022 4 years ago
pressbooks-saml-sso-1.6.1.zip
782
Oct 12, 2021 5 years ago
pressbooks-saml-sso-1.6.0.zip
769
Jul 7, 2021 5 years ago
pressbooks-saml-sso-1.5.0.zip
769
Jun 22, 2021 5 years ago
pressbooks-saml-sso-1.4.0.zip
769
Apr 27, 2021 5 years ago
pressbooks-saml-sso-1.3.1.zip
770
Mar 24, 2021 5 years ago
pressbooks-saml-sso-1.3.0.zip
777
Feb 16, 2021 5 years ago
pressbooks-saml-sso-1.2.0.zip
769
Nov 11, 2019 6 years ago
pressbooks-saml-sso-1.1.1.zip
770
Nov 5, 2019 6 years ago
pressbooks-saml-sso-1.1.0.zip
767
Aug 19, 2019 7 years ago
pressbooks-saml-sso-1.0.4.zip
770
May 13, 2019 7 years ago
pressbooks-saml-sso-1.0.3.zip
768
Apr 29, 2019 7 years ago
pressbooks-saml-sso-1.0.2.zip
767
Apr 16, 2019 7 years ago
pressbooks-saml-sso-1.0.1.zip
767
All releases on GitHub →

Active-site estimate ≈560 comes from the median of recent superseded releases. Method.

F grade

Security

Pressbooks SAML2 Single Sign-On 2.5.0 · audited by WP Registry

Critical findings.

1 critical 1 medium
Audited release
2.5.0
Findings
2
Worst severity
critical
Content hash
1ca3e7cc012d250979ab9029…

Findings

  • critical SAML ACS accepts Golden SAML Responses via xmlseclibs 3.1.1 void canonicalization (CVE-2025-66475)

    auth_bypass

    The plugin's unauthenticated Assertion Consumer Service (wp-login.php?action=pb_shibboleth_acs) calls OneLogin\Saml2\Auth::processResponse() and treats a passing response as a WordPress login. composer.lock vendors onelogin/php-saml 4.2.0 and robrichards/xmlseclibs 3.1.1. xmlseclibs <= 3.1.3 (CVE-2025-66475 / GHSA-c4cc-x928-vjw9) does not treat a failed C14N() as fatal: canonicalizeData() returns $node->C14N(...) even when libxml2 yields false/empty because of a relative namespace URI (xmlns:ns="1"). php-saml then hashes the empty string (SHA-256 digest 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=) and, with a Signature wrapping a real IdP-signed blob (SP/IdP metadata, a signed SAML error, or public WS-Fed federation XML) plus a fake Assertion carrying that empty digest, the response validates. PortSwigger's "Void Canonicalization" / Golden SAML research names php-saml and xmlseclibs as affected; GHSA-5j8p-438x-rgg5 rates php-saml < 4.3.1 Critical 9.3 (impersonate any user). This plugin never sets rejectUnsolicitedResponsesWithInResponseTo, so request_id may be null. After isAuthenticated(), parseAttributeStatement() trusts attacker uid/mail; handleLoginAttempt() matchUser/associateUser logs in the existing WP user with that email or, when Network Admin set provision=create, wp_create_user + programmatic_login. The 2.6.0 GitHub zip (plugin header still 2.5.0) shipped 20 Jan 2026, after the 8–9 Dec 2025 advisories, without bumping the libraries; upstream 2.7.0 later locked php-saml 4.3.1 / xmlseclibs 3.1.4.

    vendor/robrichards/xmlseclibs/src/XMLSecurityDSig.php:261-297

    Recommendation

    Upgrade the bundled stack to onelogin/php-saml >= 4.3.1 and robrichards/xmlseclibs >= 3.1.4 (Pressbooks SAML SSO 2.7.0 already does this), or replace the vendor copy in this zip. Treat C14N failure/empty output as a hard validation error. Also set security.rejectUnsolicitedResponsesWithInResponseTo=true and keep wantAssertionsSigned=true. Do not ship phpcompatibility/phpcs in the production require set.

  • medium Unsigned SAML RelayState is used as an open redirect after ACS

    unsafe_input

    After a successful (or Golden) SAMLResponse, samlAssertionConsumerService() reads RelayState from POST, runs only FILTER_SANITIZE_URL (no host allowlist; the inline TODO acknowledges this), and if it is not the current URL calls Auth::redirectTo() → Utils::redirect() → Location: $url. Utils::redirect() allows any URL matching @^https?://@i plus FILTER_VALIDATE_URL, so https://attacker.example/phish is accepted. ACS uses HTTP-POST binding, so RelayState is not covered by the SAML signature. An attacker copies the IdP login URL emitted by loginForm() (RelayState is the SP login URL), rewrites RelayState to an external https URL, and sends that link to a victim; after the victim authenticates at the real IdP, the browser is sent to the attacker site. php-saml's own README warns implementers not to trust RelayState on POST without a same-site check. The same plugin already uses wp_validate_redirect() for ?redirect_to= in trackRedirectUrl() but not here.

    inc/class-saml.php:582-587

    Recommendation

    Do not redirect to raw RelayState. Pass it through wp_validate_redirect( $redirect_to, $this->loginUrl ) (same helper already used in trackRedirectUrl), or ignore RelayState and always return to the session SIGN_IN_PAGE / login URL. Reject protocol-relative and off-site http(s) targets.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.