Created
May 22, 2026 10:34
-
-
Save stingray82/9de7495b92a322d67fca71ce3540e020 to your computer and use it in GitHub Desktop.
CraftForms - Security MU
This file contains hidden or 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 | |
| /** | |
| * CraftForms backend — security measures. | |
| * Place in: wp-content/mu-plugins/craftforms-backend.php | |
| */ | |
| if ( ! defined( 'ABSPATH' ) ) { | |
| exit; | |
| } | |
| if ( ! defined( 'CF_LOGIN_SLUG' ) ) { | |
| define( 'CF_LOGIN_SLUG', 'Yoursecurelogin' ); // Rename this | |
| } | |
| define( 'CF_LOCKDOWN_OPTION', 'cf_backend_lockdown_enabled' ); | |
| define( 'CF_LOCKDOWN_UNTIL_OPTION', 'cf_backend_lockdown_disabled_until' ); | |
| define( 'CF_LOCKDOWN_WINDOW', 15 * MINUTE_IN_SECONDS ); | |
| function cf_lockdown_enabled() { | |
| $enabled = get_option( CF_LOCKDOWN_OPTION, '1' ); | |
| $disabled_until = (int) get_option( CF_LOCKDOWN_UNTIL_OPTION, 0 ); | |
| if ( $enabled === '0' ) { | |
| if ( $disabled_until > time() ) { | |
| return false; | |
| } | |
| update_option( CF_LOCKDOWN_OPTION, '1', false ); | |
| delete_option( CF_LOCKDOWN_UNTIL_OPTION ); | |
| return true; | |
| } | |
| return true; | |
| } | |
| function cf_lockdown_remaining_text() { | |
| $disabled_until = (int) get_option( CF_LOCKDOWN_UNTIL_OPTION, 0 ); | |
| if ( $disabled_until <= time() ) { | |
| return ''; | |
| } | |
| $mins = max( 1, ceil( ( $disabled_until - time() ) / MINUTE_IN_SECONDS ) ); | |
| return $mins . ' min' . ( $mins === 1 ? '' : 's' ); | |
| } | |
| // ── Admin bar switch ──────────────────────────────────────────────────────── | |
| add_action( 'admin_bar_menu', function ( $wp_admin_bar ) { | |
| if ( ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) { | |
| return; | |
| } | |
| $enabled = cf_lockdown_enabled(); | |
| $remaining = cf_lockdown_remaining_text(); | |
| $wp_admin_bar->add_node( [ | |
| 'id' => 'cf-lockdown-toggle', | |
| 'title' => $enabled | |
| ? 'CraftForms Lockdown: ON' | |
| : 'CraftForms Lockdown: OFF' . ( $remaining ? ' — ' . $remaining : '' ), | |
| 'href' => wp_nonce_url( | |
| admin_url( 'admin-post.php?action=cf_toggle_lockdown' ), | |
| 'cf_toggle_lockdown' | |
| ), | |
| 'meta' => [ | |
| 'title' => $enabled | |
| ? 'Click to disable for 15 minutes' | |
| : 'Click to turn back on now', | |
| ], | |
| ] ); | |
| if ( ! $enabled ) { | |
| $wp_admin_bar->add_node( [ | |
| 'id' => 'cf-lockdown-extend', | |
| 'parent' => 'cf-lockdown-toggle', | |
| 'title' => 'Extend OFF by 15 mins', | |
| 'href' => wp_nonce_url( | |
| admin_url( 'admin-post.php?action=cf_extend_lockdown_off' ), | |
| 'cf_extend_lockdown_off' | |
| ), | |
| ] ); | |
| $wp_admin_bar->add_node( [ | |
| 'id' => 'cf-lockdown-enable-now', | |
| 'parent' => 'cf-lockdown-toggle', | |
| 'title' => 'Turn back ON now', | |
| 'href' => wp_nonce_url( | |
| admin_url( 'admin-post.php?action=cf_enable_lockdown_now' ), | |
| 'cf_enable_lockdown_now' | |
| ), | |
| ] ); | |
| } | |
| }, 100 ); | |
| add_action( 'admin_post_cf_toggle_lockdown', function () { | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| wp_die( 'Permission denied.' ); | |
| } | |
| check_admin_referer( 'cf_toggle_lockdown' ); | |
| if ( cf_lockdown_enabled() ) { | |
| update_option( CF_LOCKDOWN_OPTION, '0', false ); | |
| update_option( CF_LOCKDOWN_UNTIL_OPTION, time() + CF_LOCKDOWN_WINDOW, false ); | |
| } else { | |
| update_option( CF_LOCKDOWN_OPTION, '1', false ); | |
| delete_option( CF_LOCKDOWN_UNTIL_OPTION ); | |
| } | |
| wp_safe_redirect( wp_get_referer() ?: admin_url() ); | |
| exit; | |
| } ); | |
| add_action( 'admin_post_cf_extend_lockdown_off', function () { | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| wp_die( 'Permission denied.' ); | |
| } | |
| check_admin_referer( 'cf_extend_lockdown_off' ); | |
| $current_until = (int) get_option( CF_LOCKDOWN_UNTIL_OPTION, time() ); | |
| $new_until = max( time(), $current_until ) + CF_LOCKDOWN_WINDOW; | |
| update_option( CF_LOCKDOWN_OPTION, '0', false ); | |
| update_option( CF_LOCKDOWN_UNTIL_OPTION, $new_until, false ); | |
| wp_safe_redirect( wp_get_referer() ?: admin_url() ); | |
| exit; | |
| } ); | |
| add_action( 'admin_post_cf_enable_lockdown_now', function () { | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| wp_die( 'Permission denied.' ); | |
| } | |
| check_admin_referer( 'cf_enable_lockdown_now' ); | |
| update_option( CF_LOCKDOWN_OPTION, '1', false ); | |
| delete_option( CF_LOCKDOWN_UNTIL_OPTION ); | |
| wp_safe_redirect( wp_get_referer() ?: admin_url() ); | |
| exit; | |
| } ); | |
| // ── REST API restriction ──────────────────────────────────────────────────── | |
| add_filter( 'rest_pre_dispatch', function ( $result, $server, $request ) { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return $result; | |
| } | |
| $route = $request->get_route(); | |
| $allowed_routes = [ | |
| '/craftforms/', | |
| '/webhook/capture/', | |
| ]; | |
| foreach ( $allowed_routes as $allowed_route ) { | |
| if ( strpos( $route, $allowed_route ) === 0 ) { | |
| return $result; | |
| } | |
| } | |
| return new WP_Error( | |
| 'rest_restricted', | |
| 'REST API is disabled on this installation.', | |
| [ 'status' => 403 ] | |
| ); | |
| }, 10, 3 ); | |
| // ── XML-RPC ───────────────────────────────────────────────────────────────── | |
| add_filter( 'xmlrpc_enabled', function ( $enabled ) { | |
| return cf_lockdown_enabled() ? false : $enabled; | |
| } ); | |
| // ── Login URL / wp-admin blocking ─────────────────────────────────────────── | |
| add_action( 'init', function () { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return; | |
| } | |
| global $pagenow; | |
| $request_path = parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ); | |
| $request_path = untrailingslashit( $request_path ); | |
| if ( $request_path === '/' . CF_LOGIN_SLUG ) { | |
| global $error; | |
| $error = $error ?? null; | |
| $user_login = ''; | |
| require_once ABSPATH . 'wp-login.php'; | |
| exit; | |
| } | |
| if ( $pagenow === 'wp-login.php' || $request_path === '/wp-login.php' ) { | |
| status_header( 404 ); | |
| nocache_headers(); | |
| exit( 'Not found.' ); | |
| } | |
| if ( | |
| ! is_user_logged_in() | |
| && strpos( $request_path, '/wp-admin' ) === 0 | |
| && $request_path !== '/wp-admin/admin-ajax.php' | |
| && $request_path !== '/wp-admin/admin-post.php' | |
| ) { | |
| status_header( 404 ); | |
| nocache_headers(); | |
| exit( 'Not found.' ); | |
| } | |
| }, 1 ); | |
| add_filter( 'site_url', function ( $url, $path, $scheme ) { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return $url; | |
| } | |
| if ( 'wp-login.php' === $path && in_array( $scheme, [ 'login', 'login_post' ], true ) ) { | |
| return home_url( CF_LOGIN_SLUG ); | |
| } | |
| return $url; | |
| }, 10, 3 ); | |
| add_filter( 'login_url', function ( $url, $redirect, $force_reauth ) { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return $url; | |
| } | |
| $custom = home_url( CF_LOGIN_SLUG ); | |
| if ( $redirect ) { | |
| $custom = add_query_arg( 'redirect_to', urlencode( $redirect ), $custom ); | |
| } | |
| return $custom; | |
| }, 10, 3 ); | |
| add_filter( 'logout_url', function ( $url ) { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return $url; | |
| } | |
| return str_replace( 'wp-login.php', CF_LOGIN_SLUG, $url ); | |
| } ); | |
| // ── Block public frontend ─────────────────────────────────────────────────── | |
| add_action( 'template_redirect', function () { | |
| if ( ! cf_lockdown_enabled() ) { | |
| return; | |
| } | |
| if ( is_user_logged_in() ) { | |
| return; | |
| } | |
| status_header( 403 ); | |
| nocache_headers(); | |
| exit( 'Forbidden.' ); | |
| } ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment