Four-part audit (OIDC/JWT/crypto, user sync, admin UI, login bypasses)
with dynamic PoCs against a real WordPress install; every fix is covered
by a regression test. Report: docs/security-audit.md, section 6.
Critical/High
- Multisite: settings, AJAX actions and certificate download require
manage_network_options (site admins could sign in as super admin).
- Privileged accounts are only linked (sync and first sign-in) via a
matching UPN of a member account, never via the settable mail
attribute; the sync never changes their e-mail address; e-mail change
notifications stay on.
- Button-only mode exempts by credential (application passwords, WP-CLI)
instead of request context, closing bypasses through xmlrpc.php and
REST login handlers; API requests never receive login cookies.
- Multi-tenant mode refuses guest/external identities.
Medium/Low
- Same message for right and wrong passwords; button-only no longer
switches off when the connection breaks; server-side fallback cookie
expiry; correct fallback key beats IP lockouts; right-most proxy hop;
higher start limit; one object ID per account.
- Deactivation sets a random password, revokes application passwords and
removes the role (restored on reactivation); disabled people are
deactivated even when their mail vanished; duplicate bindings handled.
- Sync: abort on empty directory answer, no deprovisioning right after a
tenant change, atomic run lock, strict photo path validation.
- Certificates: key bundles refused, clean re-exported certificate.
- Array-safe sanitising, encoded redirect_to, per-action nonces, escaped
role lists, no Graph sleeps during sign-in, warnings for public groups,
multi-tenant group rules and missing salts, uninstall clears the token.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds a WordPress plugin that places a customisable "Sign in with
Microsoft" button on wp-login.php and signs existing users in via the
OpenID Connect authorization code flow with PKCE. Users are matched by
e-mail address only; no accounts are created.
Security: single-use state/nonce bound to an HttpOnly cookie, ID token
signature verification against Microsoft's JWKS (RS256 only) with
issuer/audience/tenant/expiry/nonce checks, optional tenant pinning,
account binding to the Microsoft object ID, e-mail domain allow-list,
client secret encrypted at rest (AES-256-GCM).
Admin: settings screen with connection, button and security tabs, live
button preview, colour presets, media-library icon picker, redirect URI
copy button and tenant connectivity test.
Packaging for WordPress.org: readme.txt with External services section,
GPL-2.0 license, uninstall.php, POT + German translations, .distignore,
build script, PHPCS config and CI running Plugin Check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2