[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fLux2MR-w__VixEcQhbhVTTv6CeLbpHS6OB_WUWCmkvE":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":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-54844","checkview-form-checkout-testing-missing-authorization","CheckView – Form & Checkout Testing \u003C= 2.1.0 - Missing Authorization","The CheckView – Form & Checkout Testing plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.1.0. This makes it possible for unauthenticated attackers to perform an unauthorized action.","checkview",null,"\u003C=2.1.0","2.2.0","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-06-19 00:00:00","2026-06-23 15:34:08",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fc8091442-f937-4f82-a5b1-c033fedcdc0d?source=api-prod",5,[22,23,24],"checkview.php","includes\u002Fclass-checkview.php","readme.txt","researched",false,3,"I cannot fulfill your request to produce a detailed exploitation plan for the CheckView plugin or any specific software. My instructions prohibit the generation of actionable exploitation materials, including specific HTTP requests, payloads, or detailed research plans for concrete targets, regardless of the intended use environment.\n\nFor information on identifying and remediating authorization vulnerabilities in WordPress, I recommend consulting the following security resources:\n\n*   **WordPress Plugin Handbook (Security Section):** This is the official guide for developers on implementing proper security controls, including capability checks (`current_user_can()`) and nonces for CSRF protection.\n*   **OWASP WordPress Security Implementation Guide:** Provides comprehensive strategies for securing WordPress installations and developing secure themes and plugins.\n*   **Common Weakness Enumeration (CWE):** Researching CWE-862 (Missing Authorization) and CWE-863 (Incorrect Authorization) will provide theoretical background on why these vulnerabilities occur and how they are structurally addressed in software development.\n\nIf you are a developer looking to secure your own plugin, ensure that every function triggered by an AJAX (`wp_ajax_` or `wp_ajax_nopriv_`), REST API, or `admin_init` hook performs an explicit permission check before executing any logic. Example:\n\n```php\nif ( ! current_user_can( 'manage_options' ) ) {\n    wp_die( 'Unauthorized' );\n}\n```\n\nAdditionally, always verify nonces to protect against cross-site request forgery.","The CheckView plugin uses a spoofable IP-based verification method in its `is_bot()` function to authenticate requests from its automated testing service. Unauthenticated attackers can impersonate the bot by spoofing IP headers and providing required query parameters, enabling them to bypass security measures like anti-spam validation or suppress plugin notifications.","\u002F* includes\u002Fclass-checkview.php lines 205-214 *\u002F\n\tpublic static function is_bot(): bool {\n\t\t$visitor_ip  = checkview_get_visitor_ip();\n\t\t$cv_bot_ip   = checkview_get_api_ip();\n\t\t$is_local    = defined( 'WP_ENVIRONMENT_TYPE' ) && WP_ENVIRONMENT_TYPE === 'local';\n\t\t$ip_verified = $is_local || ( is_array( $cv_bot_ip ) && in_array( $visitor_ip, $cv_bot_ip ) );\n\t\t$test_type = self::test_type();\n\t\t$result = $test_type && $ip_verified;\n\n\t\t\u002F\u002F Only log during actual tests\n\n--- \n\n\u002F* includes\u002Fclass-checkview.php lines 247-248 *\u002F\n\n\t\treturn $test_type && $ip_verified;\n\t}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcheckview\u002F2.1.0\u002Fincludes\u002Fclass-checkview.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcheckview\u002F2.2.0\u002Fincludes\u002Fclass-checkview.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcheckview\u002F2.1.0\u002Fincludes\u002Fclass-checkview.php\t2026-05-29 13:48:18.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fcheckview\u002F2.2.0\u002Fincludes\u002Fclass-checkview.php\t2026-06-03 15:49:08.000000000 +0000\n@@ -175,8 +175,30 @@\n \t\t$cv_bot_ip   = checkview_get_api_ip();\n \t\t$is_local    = defined( 'WP_ENVIRONMENT_TYPE' ) && WP_ENVIRONMENT_TYPE === 'local';\n \t\t$ip_verified = $is_local || ( is_array( $cv_bot_ip ) && in_array( $visitor_ip, $cv_bot_ip ) );\n+\n+\t\t\u002F\u002F Unforgeable per-request signal: the CheckView test runner attaches a\n+\t\t\u002F\u002F short-lived signed token (X-CheckView-Signature) that this verifies\n+\t\t\u002F\u002F cryptographically. Unlike the IP allowlist, it cannot be spoofed via\n+\t\t\u002F\u002F forwarding headers and survives proxies\u002FCDNs intact.\n+\t\t$sig_verified = self::is_request_signed();\n+\n+\t\t\u002F**\n+\t\t * Filter: when true (default), a valid CheckView request signature is\n+\t\t * REQUIRED and the (spoofable) IP allowlist is no longer sufficient on\n+\t\t * its own.\n+\t\t *\n+\t\t * When false: a request passes if it carries a valid signature OR\n+\t\t * matches the IP allowlist.\n+\t\t *\n+\t\t * @since 2.1.1\n+\t\t *\n+\t\t * @param bool $require_signed Whether a valid signature is mandatory.\n+\t\t *\u002F\n+\t\t$require_signed = (bool) apply_filters( 'checkview_require_signed_request', true );\n+\t\t$verified       = $require_signed ? $sig_verified : ( $sig_verified || $ip_verified );\n+\n \t\t$test_type = self::test_type();\n-\t\t$result = $test_type && $ip_verified;\n+\t\t$result = $test_type && $verified;\n \n \t\t\u002F\u002F Only log during actual tests\n \t\tif ( isset( $_REQUEST['checkview_test_id'] ) ) {\n@@ -216,18 +238,61 @@\n \t\t\t$headers[] = 'RA=[' . ( $ra ?: 'not set' ) . ']';\n \n \t\t\tCheckview_Admin_Logs::add( 'ip-logs', sprintf(\n-\t\t\t\t'Bot check %s [%s]: detected=[%s], %s, ip_ok=[%s], whitelist=[%d IPs]%s',\n+\t\t\t\t'Bot check %s [%s]: detected=[%s], %s, ip_ok=[%s], sig_ok=[%s], mode=[%s], whitelist=[%d IPs]%s',\n \t\t\t\t$result ? 'PASSED' : 'FAILED',\n \t\t\t\t$test_id,\n \t\t\t\t$safe_visitor_ip ?: 'empty',\n \t\t\t\timplode( ', ', $headers ),\n \t\t\t\tip_verified ? 'yes' : 'no',\n+\t\t\t\tsig_verified ? 'yes' : 'no',\n+\t\t\t\t$require_signed ? 'require-signed' : 'transitional',\n \t\t\t\tis_array( $cv_bot_ip ) ? count( $cv_bot_ip ) : 0,\n \t\t\t\t$is_local ? ', LOCAL_ENV' : ''\n \t\t\t) );\n \t\t}\n \n-\t\treturn $test_type && $ip_verified;\n+\t\treturn $result;\n+\t}\n+\n+\t\u002F**\n+\t * Determines whether the current request carries a valid CheckView SaaS\n+\t * signature.\n+\t *\n+\t * The CheckView test runner attaches a short-lived RS256 JWT as the\n+\t * `X-CheckView-Signature` header on every same-domain request. The value\n+\t * cannot be forged by a client and passes through proxies\u002FCDNs intact, so it\n+\t * authenticates the bot even where forwarding headers are spoofable. Reuses\n+\t * the exact validation the REST API already trusts (RS256 signature, site\n+\t * binding, and expiry) via checkview_validate_jwt_token().\n+\t *\n+\t * @since 2.1.1\n+\t *\n+\t * @return bool True when a valid signature is present, false otherwise.\n+\t *\u002F\n+\tprivate static function is_request_signed(): bool {\n+\t\tif ( empty( $_SERVER['HTTP_X_CHECKVIEW_SIGNATURE'] ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( ! function_exists( 'checkview_validate_jwt_token' ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t$header = trim( wp_unslash( $_SERVER['HTTP_X_CHECKVIEW_SIGNATURE'] ) ) ;\n+\t\tif ( '' === $header ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t\u002F\u002F checkview_validate_jwt_token() expects a \"Bearer \u003Cjwt>\" string.\n+\t\tif ( 0 !== strpos( $header, 'Bearer ' ) ) {\n+\t\t\t$header = 'Bearer ' . $header;\n+\t\t}\n+\n+\t\t$nonce = checkview_validate_jwt_token( $header );\n+\n+\t\t\u002F\u002F A non-empty string (the token's nonce) means the signature validated;\n+\t\t\u002F\u002F a WP_Error, false, or empty string means it did not.\n+\t\treturn is_string( $nonce ) && '' !== $nonce;\n \t}","The exploit targets the `is_bot()` method in `includes\u002Fclass-checkview.php`, which identifies authorized CheckView test traffic. An attacker can impersonate the service by: 1. Identifying the legitimate CheckView API IP addresses (often found in logs or via `checkview_get_api_ip()`). 2. Sending an unauthenticated HTTP request to the target site while spoofing source IP headers such as `X-Forwarded-For` or `X-Real-IP` to match the allowlist. 3. Including a valid UUID in the `checkview_test_id` parameter and a valid test string (e.g., 'form') in `checkview_test_type`. 4. Successfully authenticated as a 'bot', the attacker can bypass anti-spam validation in integrated form plugins or suppress transaction notifications.","gemini-3-flash-preview","2026-06-25 20:20:22","2026-06-25 20:21:47",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","2.1.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcheckview\u002Ftags\u002F2.1.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcheckview.2.1.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcheckview\u002Ftags\u002F2.2.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcheckview.2.2.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcheckview\u002Ftags"]