From b97cee43952da3d0c3b6507615e6feed7d943d50 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Sat, 4 Oct 2025 11:00:33 +0200 Subject: [PATCH] Update wordpress.md --- .../pentesting-web/wordpress.md | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index b935c8f67..c25e585e4 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -447,15 +447,6 @@ Detection checklist - Review REST registrations for privileged callbacks that lack robust `permission_callback` checks and instead rely on request headers. - Look for usages of core user-management functions (`wp_insert_user`, `wp_create_user`) inside REST handlers that are gated only by header values. -Hardening - -- Never derive authentication or authorization from client-controlled headers. -- If a reverse proxy must inject identity, terminate trust at the proxy and strip inbound copies (e.g., `unset X-Wcpay-Platform-Checkout-User` at the edge), then pass a signed token and verify it server-side. -- For REST routes performing privileged actions, require `current_user_can()` checks and a strict `permission_callback` (do NOT use `__return_true`). -- Prefer first-party auth (cookies, application passwords, OAuth) over header “impersonation”. - -References: see the links at the end of this page for a public case and broader analysis. - ### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0) WordPress themes and plugins frequently expose AJAX handlers through the `wp_ajax_` and `wp_ajax_nopriv_` hooks. When the **_nopriv_** variant is used **the callback becomes reachable by unauthenticated visitors**, so any sensitive action must additionally implement: @@ -511,31 +502,6 @@ Other impactful targets include plugin/theme `.php` files (to break security plu * Concatenation of unsanitised user input into paths (look for `$_POST`, `$_GET`, `$_REQUEST`). * Absence of `check_ajax_referer()` and `current_user_can()`/`is_user_logged_in()`. -#### Hardening - -```php -function secure_remove_font_family() { - if ( ! is_user_logged_in() ) { - wp_send_json_error( 'forbidden', 403 ); - } - check_ajax_referer( 'litho_fonts_nonce' ); - - $fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) ); - $srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily; - - if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) { - wp_send_json_error( 'invalid path', 400 ); - } - // … proceed … -} -add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' ); -// 🔒 NO wp_ajax_nopriv_ registration -``` - -> [!TIP] -> **Always** treat any write/delete operation on disk as privileged and double-check: -> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`). - --- ### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role") @@ -565,12 +531,6 @@ Why it’s exploitable - If a user previously had higher privileges saved in `_asenha_view_admin_as_original_roles` and was downgraded, they can restore them by hitting the reset path. - In some deployments, any authenticated user could trigger a reset for another username still present in `viewing_admin_as_role_are` (broken authorization). -Attack prerequisites - -- Vulnerable plugin version with the feature enabled. -- Target account has a stale high-privilege role stored in user meta from earlier use. -- Any authenticated session; missing nonce/capability on the reset flow. - Exploitation (example) ```bash @@ -591,21 +551,6 @@ Detection checklist - Modify roles via `add_role()` / `remove_role()` without `current_user_can()` and `wp_verify_nonce()` / `check_admin_referer()`. - Authorize based on a plugin option array (e.g., `viewing_admin_as_role_are`) instead of the actor’s capabilities. -Hardening - -- Enforce capability checks on every state-changing branch (e.g., `current_user_can('manage_options')` or stricter). -- Require nonces for all role/permission mutations and verify them: `check_admin_referer()` / `wp_verify_nonce()`. -- Never trust request-supplied usernames; resolve the target user server-side based on the authenticated actor and explicit policy. -- Invalidate “original roles” state on profile/role updates to avoid stale high-privilege restoration: - -```php -add_action( 'profile_update', function( $user_id ) { - delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); -}, 10, 1 ); -``` - -- Consider storing minimal state and using time-limited, capability-guarded tokens for temporary role switches. - --- ### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)