[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$flgy1x5l5vNm7PRnbyhuTlfQ-iSTHaH2cuSwy0SjYNdY":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":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"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":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2026-12428","blocks-for-acf-fields-missing-authorization-to-authenticated-author-arbitrary-acf-field-value-disclosure-via-id-paramete","Blocks for ACF Fields \u003C= 1.6.2 - Missing Authorization to Authenticated (Author+) Arbitrary ACF Field Value Disclosure via 'id' Parameter","The Blocks for ACF Fields plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the get_all_values() function in the \u002Fwp-json\u002Facf-field-blocks\u002Fv1\u002Fvalues REST endpoint in versions up to, and including, 1.6.2. The permission_callback only verifies the generic publish_posts capability and the handler passes a user-supplied id parameter directly to get_field_objects() without verifying that the requesting user is authorized to read the target object. This makes it possible for authenticated attackers, with Author-level access and above, to read ACF field values from arbitrary posts (including private posts, drafts, posts by other users, and other ACF-supported objects) that they should not have access to.","acf-field-blocks",null,"\u003C=1.6.2","1.6.3","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Missing Authorization","2026-07-08 20:36:42","2026-07-09 09:31:23",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ffc48f75d-a2e8-49ea-9bfa-a27a61ff8a84?source=api-prod",1,[22,23,24,25,26],"acf-field-blocks.php","inc\u002Fblocks\u002Fclass-acf-embed.php","inc\u002Fclass-fields.php","inc\u002Fclass-rest.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-12428\n\nThis plan outlines the systematic approach to exploiting a Missing Authorization vulnerability in the **Blocks for ACF Fields** plugin (\u003C= 1.6.2), which allows authenticated users (Author level and above) to disclose arbitrary Advanced Custom Fields (ACF) values from any post or object ID.\n\n## 1. Vulnerability Summary\n- **Vulnerability:** Missing Authorization\n- **Location:** `inc\u002Fclass-rest.php` (specifically the `get_all_values()` callback for the `\u002Fwp-json\u002Facf-field-blocks\u002Fv1\u002Fvalues` REST endpoint).\n- **Cause:** The `permission_callback` for the `\u002Fvalues` endpoint only verifies the `publish_posts` capability. The implementation of `get_all_values()` (as described in the vulnerability report and supported by the `Rest::register_routes` structure) accepts a user-controlled `id` parameter and passes it to ACF functions (like `get_field_objects()`) without verifying if the current user has permission to read the specific post associated with that `id`.\n\n## 2. Attack Vector Analysis\n- **REST Endpoint:** `\u002Fwp-json\u002Facf-field-blocks\u002Fv1\u002Fvalues`\n- **HTTP Method:** `GET` (READABLE)\n- **Vulnerable Parameter:** `id` (Target Post\u002FObject ID)\n- **Authentication Required:** Authenticated (Author role or higher). The `publish_posts` capability is granted to Authors, Editors, and Administrators by default.\n- **Preconditions:**\n    - The target WordPress site must have Advanced Custom Fields (ACF) or Secure Custom Fields (SCF) installed and active.\n    - Sensitive data must be stored in ACF fields attached to a post that the Author normally cannot access (e.g., a Private Post, a Draft, or a post belonging to another user).\n\n## 3. Code Flow\n1. **Registration:** `ACFFieldBlocks\\Rest::register_routes()` registers the endpoint:\n   ```php\n   register_rest_route(\n       'acf-field-blocks\u002Fv1',\n       '\u002Fvalues',\n       array(\n           'methods'             => \\WP_REST_Server::READABLE,\n           'callback'            => array( $this, 'get_all_values' ),\n           'permission_callback' => function() {\n               return current_user_can('publish_posts');\n           }\n       )\n   );\n   ```\n2. **Access:** An Author-level user accesses the endpoint via a GET request with an `id` parameter.\n3. **Execution (Inferred from Patch):** The `get_all_values($request)` method retrieves the `id` via `$request->get_param('id')`.\n4. **Sink:** It calls `get_field_objects($id)` (an ACF function). This function retrieves all fields for the given ID. Because the plugin does not check if the user can `edit_post` or `read_post` for that specific `$id`, the data is returned in the REST response.\n\n## 4. Nonce Acquisition Strategy\nTo interact with the WordPress REST API using cookie-based authentication, a `_wpnonce` or `X-WP-Nonce` header is required. This nonce is tied to the `wp_rest` action.\n\n1. **Shortcode Identification:** The plugin uses the `[acf_field_block]` or \"ACF Field\" block.\n2. **Setup:** Create a test page containing the block.\n3. **Browser Execution:**\n    - Log in to the WordPress dashboard as the **Author** user.\n    - Navigate to `wp-admin\u002Findex.php`.\n    - Use `browser_eval` to extract the REST nonce usually available in the `wpApiSettings` object or via a specific call.\n    - **JS Script:** `window.wpApiSettings ? window.wpApiSettings.nonce : \"\"`.\n    - Alternatively, fetch `wp-admin\u002Fadmin-ajax.php?action=rest-nonce` to get a fresh nonce for the `wp_rest` action.\n\n## 5. Exploitation Strategy\nThe goal is to use an Author account to read ACF field values from a Private Post created by an Administrator.\n\n### Step-by-Step Plan:\n1. **Target Identification:** Determine the ID of a Private Post containing sensitive ACF data (e.g., Post ID 123).\n2. **Login:** Authenticate as the **Author** user.\n3. **Nonce Retrieval:** Obtain the `wp_rest` nonce.\n4. **Data Extraction:** Send a GET request to the vulnerable endpoint.\n\n**HTTP Request (via `http_request` tool):**\n- **Method:** `GET`\n- **URL:** `http:\u002F\u002F\u003CTARGET_URL>\u002Fwp-json\u002Facf-field-blocks\u002Fv1\u002Fvalues?id=123`\n- **Headers:**\n    - `X-WP-Nonce: \u003CNONCE_VALUE>`\n    - `Content-Type: application\u002Fjson`\n- **Expected Response:** A JSON object containing the `label`, `name`, and `value` of all ACF fields associated with Post 123.\n\n## 6. Test Data Setup\n1. **Admin User Actions:**\n    - Create a new ACF Field Group (e.g., \"Internal Secrets\").\n    - Add a Text field named `api_key_secret`.\n    - Set the location to \"Post Type is equal to Post\".\n    - Create a **Private Post** (ID $TARGET_ID).\n    - Populate the `api_key_secret` field with a value: `SUPER_SECRET_TOKEN_2026`.\n2. **Attacker User Action:**\n    - Create a user with the **Author** role.\n\n## 7. Expected Results\n- The request should return a `200 OK` status code.\n- The JSON body should contain the data from the Private Post:\n  ```json\n  {\n    \"api_key_secret\": {\n      \"key\": \"field_xxxxxxxx\",\n      \"label\": \"API Key Secret\",\n      \"name\": \"api_key_secret\",\n      \"type\": \"text\",\n      \"value\": \"SUPER_SECRET_TOKEN_2026\",\n      ...\n    }\n  }\n  ```\n- If the vulnerability is patched, the endpoint should return a `403 Forbidden` or restricted data.\n\n## 8. Verification Steps\n1. **Manual Check:** Verify the returned `value` matches the one set by the Admin in the Private Post.\n2. **WP-CLI Comparison:**\n   ```bash\n   # Confirm the post is indeed private and not accessible by Author normally\n   wp post get \u003CTARGET_ID> --user=author_user_login\n   # This should fail or return \"Invalid post ID\" if standard permissions are working.\n   ```\n\n## 9. Alternative Approaches\n- **Brute Forcing IDs:** If the specific target ID is unknown, the agent can iterate through common IDs (1 to 100) to find hidden ACF metadata.\n- **Other Object Types:** Test `id` values for other ACF-supported objects, such as `user_1` (to read metadata of the Admin user) or `term_5` (taxonomy metadata), as `get_field_objects()` accepts these string-based ID formats.","The Blocks for ACF Fields plugin for WordPress is vulnerable to unauthorized disclosure of data via its REST API in versions up to 1.6.2. Due to a missing object-level capability check in the get_all_values() function, authenticated users with Author-level access or higher can retrieve sensitive Advanced Custom Fields (ACF) values for any post, user, or object ID, including those they lack permissions to view.","\u002F\u002F inc\u002Fclass-rest.php lines 88-100\n\t\tregister_rest_route(\n\t\t\t$namespace,\n\t\t\t'\u002Fvalues',\n\t\t\tarray(\n\t\t\t\t'methods'             => \\WP_REST_Server::READABLE,\n\t\t\t\t'callback'            => array( $this, 'get_all_values' ),\n\t\t\t\t'args'                => array(),\n\t\t\t\t'permission_callback' => function() {\n\t\t\t\t\treturn current_user_can('publish_posts');\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\n---\n\n\u002F\u002F inc\u002Fclass-rest.php lines 291-314 (implementation inferred from patch diff context)\n\tpublic function get_all_values( \\WP_REST_Request $request ) {\n\t\t$post_id = $request->get_param( 'id' );\n\n\t\tif ( empty( $post_id ) ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t$fields = get_field_objects( $post_id, false, true, false );\n\t\t$values = array();\n\n\t\tif ( ! empty( $fields ) ) {\n\t\t\tforeach ( $fields as $field ) {\n\t\t\t\t$values[ $field['name'] ] = $field;\n\t\t\t}\n\t\t}\n\n\t\treturn apply_filters( 'acf_field_blocks_rest_values', $values );\n\t}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Facf-field-blocks\u002F1.6.1\u002Finc\u002Fclass-rest.php\t2026-01-02 02:36:54.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Facf-field-blocks\u002F1.6.3\u002Finc\u002Fclass-rest.php\t2026-06-27 06:48:40.000000000 +0000\n@@ -299,6 +299,15 @@\n \t\t\treturn [];\n \t\t}\n \n+\t\t\u002F\u002F The id can point at any object, so check object-level access before reading.\n+\t\tif ( ! $this->current_user_can_read_object( $post_id ) ) {\n+\t\t\treturn new \\WP_Error(\n+\t\t\t\t'rest_forbidden',\n+\t\t\t\t__( 'You are not allowed to read the field values of this object.', 'acf-field-blocks' ),\n+\t\t\t\tarray( 'status' => rest_authorization_required_code() )\n+\t\t\t);\n+\t\t}\n+\n \t\t$fields = get_field_objects( $post_id, false, true, false );\n \t\t$values = array();\n \n@@ -314,4 +323,57 @@\n \t\treturn apply_filters( 'acf_field_blocks_rest_values', $values );\n \t}\n \n+\t\u002F**\n+\t * Check whether the current user may read the ACF values of the given object id.\n+\t *\n+\t * @since  1.6.3\n+\t *\n+\t * @param  int|string $post_id ACF object id.\n+\t * @return bool                True if the current user may read the object.\n+\t *\u002F\n+\tprivate function current_user_can_read_object( $post_id ) {\n+\t\t\u002F\u002F Decode the id the same way ACF does, so the check matches what gets read.\n+\t\tif ( function_exists( 'acf_decode_post_id' ) ) {\n+\t\t\t$decoded = acf_decode_post_id( $post_id );\n+\t\t\t$type    = $decoded['type'];\n+\t\t\t$id      = $decoded['id'];\n+\t\t} elseif ( is_numeric( $post_id ) ) {\n+\t\t\t$type = 'post';\n+\t\t\t$id   = $post_id;\n+\t\t} else {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tswitch ( $type ) {\n+\t\t\tcase 'post':\n+\t\t\t\t$id = (int) $id;\n+\t\t\t\treturn $id && current_user_can( 'read_post', $id );\n+\n+\t\t\tcase 'user':\n+\t\t\t\t\u002F\u002F Allow your own profile; otherwise require edit access to the user.\n+\t\t\t\t$id = (int) $id;\n+\t\t\t\treturn $id && ( get_current_user_id() === $id || current_user_can( 'edit_user', $id ) );\n+\n+\t\t\tcase 'comment':\n+\t\t\t\t$id      = (int) $id;\n+\t\t\t\t$comment = $id ? get_comment( $id ) : null;\n+\t\t\t\treturn $comment && ( current_user_can( 'moderate_comments' )\n+\t\t\t\t\t|| current_user_can( 'read_post', (int) $comment->comment_post_ID ) );\n+\n+\t\t\tcase 'term':\n+\t\t\t\t\u002F\u002F Terms are public taxonomy data; just confirm it exists.\n+\t\t\t\t$id = (int) $id;\n+\t\t\t\treturn $id > 0 && term_exists( $id ) !== null;\n+\n+\t\t\tcase 'option':\n+\t\t\tcase 'block':\n+\t\t\t\t\u002F\u002F Shared store, not a per-object resource. Already gated by publish_posts.\n+\t\t\t\treturn true;\n+\n+\t\t\tdefault:\n+\t\t\t\t\u002F\u002F Unknown\u002Fsensitive types (blog, woo_order, ...).\n+\t\t\t\treturn current_user_can( 'manage_options' );\n+\t\t}\n+\t}\n+","The exploit requires an authenticated user account with the 'publish_posts' capability (typically Author, Editor, or Administrator roles). The attacker first obtains a valid WordPress REST API nonce. They then send a GET request to the `\u002Fwp-json\u002Facf-field-blocks\u002Fv1\u002Fvalues` endpoint, supplying an arbitrary target ID in the 'id' parameter (e.g., a post ID for a private draft or a user ID such as 'user_1'). Because the plugin lacks object-level permission verification for the provided ID, it calls the ACF get_field_objects() function on the target and returns a JSON response containing all associated custom field metadata and sensitive values, even if the attacker should not have access to that specific object.","gemini-3-flash-preview","2026-07-15 22:23:19","2026-07-15 22:24:02",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","1.6.1","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-field-blocks\u002Ftags\u002F1.6.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Facf-field-blocks.1.6.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-field-blocks\u002Ftags\u002F1.6.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Facf-field-blocks.1.6.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-field-blocks\u002Ftags"]