Last active
January 15, 2024 05:59
-
-
Save wpo365/b0a1c3c8c5612fd0012de2e2f65c09c4 to your computer and use it in GitHub Desktop.
Plugin for WordPress websites that require a user to sign in (e.g. with Microsoft) and that are loaded inside an iframe (e.g. inside a Microsoft Teams App / Tab or similar). The plugin overrides the pluggable WordPress function wp_set_auth_cookie to set SameSite=None to enable third-party usage.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: WPO | SAMESITE | |
* Plugin URI: https://www.wpo365.com/downloads/wordpress-office-365-samesite/ | |
* Description: Plugin for WordPress websites that require a user to sign in (e.g. with Microsoft) and that are loaded inside an iframe (e.g. inside a Microsoft Teams App / Tab or similar). The plugin overrides the pluggable WordPress function wp_set_auth_cookie to set SameSite=None to enable third-party usage. | |
* Version: 1.0 | |
* Author: support@wpo365.com | |
* Author URI: https://www.wpo365.com/ | |
* License: GPL2+ | |
*/ | |
// Prevent public access to this script | |
defined( 'ABSPATH' ) or die( ); | |
if ( ! function_exists( 'wp_set_auth_cookie' ) ) : | |
/** | |
* Sets the authentication cookies based on user ID. | |
* | |
* The $remember parameter increases the time that the cookie will be kept. The | |
* default the cookie is kept without remembering is two days. When $remember is | |
* set, the cookies will be kept for 14 days or two weeks. | |
* | |
* @since 2.5.0 | |
* @since 4.3.0 Added the `$token` parameter. | |
* | |
* @param int $user_id User ID. | |
* @param bool $remember Whether to remember the user. | |
* @param bool|string $secure Whether the auth cookie should only be sent over HTTPS. Default is an empty | |
* string which means the value of `is_ssl()` will be used. | |
* @param string $token Optional. User's session token to use for this cookie. | |
*/ | |
function wp_set_auth_cookie( $user_id, $remember = false, $secure = '', $token = '' ) { | |
if ( $remember ) { | |
/** | |
* Filters the duration of the authentication cookie expiration period. | |
* | |
* @since 2.8.0 | |
* | |
* @param int $length Duration of the expiration period in seconds. | |
* @param int $user_id User ID. | |
* @param bool $remember Whether to remember the user login. Default false. | |
*/ | |
$expiration = time() + apply_filters( 'auth_cookie_expiration', 14 * DAY_IN_SECONDS, $user_id, $remember ); | |
/* | |
* Ensure the browser will continue to send the cookie after the expiration time is reached. | |
* Needed for the login grace period in wp_validate_auth_cookie(). | |
*/ | |
$expire = $expiration + ( 12 * HOUR_IN_SECONDS ); | |
} else { | |
/** This filter is documented in wp-includes/pluggable.php */ | |
$expiration = time() + apply_filters( 'auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user_id, $remember ); | |
$expire = 0; | |
} | |
if ( '' === $secure ) { | |
$secure = is_ssl(); | |
} | |
// Front-end cookie is secure when the auth cookie is secure and the site's home URL uses HTTPS. | |
$secure_logged_in_cookie = $secure && 'https' === parse_url( get_option( 'home' ), PHP_URL_SCHEME ); | |
/** | |
* Filters whether the auth cookie should only be sent over HTTPS. | |
* | |
* @since 3.1.0 | |
* | |
* @param bool $secure Whether the cookie should only be sent over HTTPS. | |
* @param int $user_id User ID. | |
*/ | |
$secure = apply_filters( 'secure_auth_cookie', $secure, $user_id ); | |
/** | |
* Filters whether the logged in cookie should only be sent over HTTPS. | |
* | |
* @since 3.1.0 | |
* | |
* @param bool $secure_logged_in_cookie Whether the logged in cookie should only be sent over HTTPS. | |
* @param int $user_id User ID. | |
* @param bool $secure Whether the auth cookie should only be sent over HTTPS. | |
*/ | |
$secure_logged_in_cookie = apply_filters( 'secure_logged_in_cookie', $secure_logged_in_cookie, $user_id, $secure ); | |
if ( $secure ) { | |
$auth_cookie_name = SECURE_AUTH_COOKIE; | |
$scheme = 'secure_auth'; | |
} else { | |
$auth_cookie_name = AUTH_COOKIE; | |
$scheme = 'auth'; | |
} | |
if ( '' === $token ) { | |
$manager = WP_Session_Tokens::get_instance( $user_id ); | |
$token = $manager->create( $expiration ); | |
} | |
$auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, $token ); | |
$logged_in_cookie = wp_generate_auth_cookie( $user_id, $expiration, 'logged_in', $token ); | |
/** | |
* Fires immediately before the authentication cookie is set. | |
* | |
* @since 2.5.0 | |
* @since 4.9.0 The `$token` parameter was added. | |
* | |
* @param string $auth_cookie Authentication cookie value. | |
* @param int $expire The time the login grace period expires as a UNIX timestamp. | |
* Default is 12 hours past the cookie's expiration time. | |
* @param int $expiration The time when the authentication cookie expires as a UNIX timestamp. | |
* Default is 14 days from now. | |
* @param int $user_id User ID. | |
* @param string $scheme Authentication scheme. Values include 'auth' or 'secure_auth'. | |
* @param string $token User's session token to use for this cookie. | |
*/ | |
do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme, $token ); | |
/** | |
* Fires immediately before the logged-in authentication cookie is set. | |
* | |
* @since 2.6.0 | |
* @since 4.9.0 The `$token` parameter was added. | |
* | |
* @param string $logged_in_cookie The logged-in cookie value. | |
* @param int $expire The time the login grace period expires as a UNIX timestamp. | |
* Default is 12 hours past the cookie's expiration time. | |
* @param int $expiration The time when the logged-in authentication cookie expires as a UNIX timestamp. | |
* Default is 14 days from now. | |
* @param int $user_id User ID. | |
* @param string $scheme Authentication scheme. Default 'logged_in'. | |
* @param string $token User's session token to use for this cookie. | |
*/ | |
do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in', $token ); | |
/** | |
* Allows preventing auth cookies from actually being sent to the client. | |
* | |
* @since 4.7.4 | |
* | |
* @param bool $send Whether to send auth cookies to the client. | |
*/ | |
if ( ! apply_filters( 'send_auth_cookies', true ) ) { | |
return; | |
} | |
$php_version = explode( '.', \phpversion() ); | |
$same_site_as_option = intval( $php_version[0] ) >= 7 && intval( $php_version[1] ) >= 3; | |
if ( $same_site_as_option ) { | |
setcookie( $auth_cookie_name, $auth_cookie, array( "expires" => $expire, "path" => PLUGINS_COOKIE_PATH, "domain" => COOKIE_DOMAIN, "secure" => $secure, "httponly" => true, "SameSite" => "None" ) ); | |
setcookie( $auth_cookie_name, $auth_cookie, array( "expires" => $expire, "path" => ADMIN_COOKIE_PATH, "domain" => COOKIE_DOMAIN, "secure" => $secure, "httponly" => true, "SameSite" => "None" ) ); | |
setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, array( "expires" => $expire, "path" => COOKIEPATH, "domain" => COOKIE_DOMAIN, "secure" => $secure, "httponly" => true, "SameSite" => "None" ) ); | |
if ( COOKIEPATH != SITECOOKIEPATH ) { | |
setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, array( "expires" => $expire, "path" => SITECOOKIEPATH, "domain" => COOKIE_DOMAIN, "secure" => $secure, "httponly" => true, "SameSite" => "None" ) ); | |
} | |
} | |
else { | |
$_secure = $secure ? '; Secure' : ''; | |
header( "Set-Cookie: $auth_cookie_name=$auth_cookie; expires=$expire; path=" . PLUGINS_COOKIE_PATH . "; domain=" . COOKIE_DOMAIN . "; HttpOnly; SameSite=None" . $_secure ); | |
header( "Set-Cookie: $auth_cookie_name=$auth_cookie; expires=$expire; path=" . ADMIN_COOKIE_PATH . "; domain=" . COOKIE_DOMAIN . "; HttpOnly; SameSite=None" . $_secure ); | |
header( "Set-Cookie: " . LOGGED_IN_COOKIE . "=$logged_in_cookie; expires=$expire; path=" . COOKIEPATH . "; domain=" . COOKIE_DOMAIN . "; HttpOnly; SameSite=None" . $_secure ); | |
if ( COOKIEPATH != SITECOOKIEPATH ) { | |
header( "Set-Cookie: " . LOGGED_IN_COOKIE . "=$logged_in_cookie; expires=$expire; path=" . SITECOOKIEPATH . "; domain=" . COOKIE_DOMAIN . "; HttpOnly; SameSite=None" . $_secure ); | |
} | |
} | |
} | |
endif; |
Great plugin and much needed - will you be updating it to WordPress 6.11?
In my testing, this prevents access to the admin pages. Replacing $secure
in lines 152 and 154 with $secure_logged_in_cookie
fixes the problem.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great plugin and was exactly what I was looking for.
One thing I just what to know is was the security risk of overriding the wp_set_auth_cookie?
Could I limited the use to a slug or page id?