Make WordPress Core

Opened 2 months ago

Closed 5 weeks ago

#65035 closed defect (bug) (fixed)

Abilities: Strip internal schema keywords from abilities REST responses

Reported by: jorgefilipecosta's profile jorgefilipecosta Owned by: jorgefilipecosta's profile jorgefilipecosta
Milestone: 7.0 Priority: normal
Severity: normal Version:
Component: Abilities API Keywords: has-patch has-unit-tests fixed-major dev-reviewed
Focuses: Cc:

Description

The Abilities REST API endpoint (/wp/v2/abilities) returns input_schema and output_schema that may contain WordPress-internal properties like sanitize_callback, validate_callback, and arg_options. These are not valid JSON Schema keywords and cause client-side JSON Schema validators to reject the schemas.

For example, a plugin registering an ability with register_ability() that includes sanitize_callback or arg_options in its schema arguments will surface those internal keywords in the REST response. Clients consuming the API (such as Gutenberg's AI tools integration) cannot validate these schemas without error.

Proposed Fix

Add a recursive strip_internal_schema_keywords() method to WP_REST_Abilities_V1_List_Controller that removes the three internal keywords from schemas before they appear in REST responses.

The method uses a denylist approach (array_diff_key() against a class constant INTERNAL_SCHEMA_KEYWORDS) rather than the allowlist approach (rest_get_allowed_schema_keywords() + array_intersect_key()) used in WP_REST_Server::get_data_for_route(). The denylist is the correct choice here because rest_get_allowed_schema_keywords() is missing valid JSON Schema keywords (allOf, not, definitions, dependencies, additionalItems) that would be silently stripped with the allowlist approach.

The recursive method traverses all JSON Schema sub-schema locations:

  • properties, patternProperties, definitions, dependencies (map-of-schemas)
  • not, additionalProperties, additionalItems (single sub-schema)
  • items (single schema or tuple array)
  • anyOf, oneOf, allOf (array-of-schemas)

Property-dependency arrays (numeric arrays in dependencies) are correctly skipped.

The stripping is applied to both input_schema and output_schema in prepare_item_for_response().

Test Coverage

  • Verifies internal keywords are stripped from top-level and nested properties in both input_schema and output_schema
  • Verifies internal keywords are stripped from all sub-schema locations (anyOf, oneOf, allOf, not, patternProperties, definitions, dependencies, additionalProperties, additionalItems, tuple-style items)
  • Verifies valid JSON Schema keywords are preserved
  • Verifies property-dependency arrays pass through unchanged

Change History (8)

This ticket was mentioned in PR #11451 on WordPress/wordpress-develop by @jorgefilipecosta.


2 months ago
#2

Track ticket: https://core.trac.wordpress.org/ticket/65035

Ability input_schema and output_schema may contain WordPress-internal properties like sanitize_callback, validate_callback, and arg_options that are not valid JSON Schema keywords. These cause client-side JSON Schema validators to fail.

This adds recursive stripping of internal keywords in prepare_item_for_response(), using a denylist approach (array_diff_key removing specific internal keywords defined in WP_REST_Abilities_Controller::INTERNAL_SCHEMA_KEYWORDS). This differs from the allowlist approach (rest_get_allowed_schema_keywords() + array_intersect_key()) used in WP_REST_Server::get_data_for_route() — the denylist is the correct choice here because rest_get_allowed_schema_keywords() is missing valid JSON Schema keywords (allOf, not, definitions, dependencies, additionalItems) that would get silently stripped with the allowlist approach.

Related Gutenberg PR: https://github.com/WordPress/gutenberg/pull/77029

#3 @gziolo
2 months ago

  • Keywords dev-reviewed added

#4 @jorgefilipecosta
2 months ago

  • Owner set to jorgefilipecosta
  • Resolution set to fixed
  • Status changed from new to closed

In 62221:

Abilities: Strip internal schema keywords from abilities REST responses.

Remove WordPress-internal properties (sanitize_callback, validate_callback, arg_options) from ability input_schema and output_schema fields in REST responses. These properties are used server-side but are not valid JSON Schema keywords and cause client-side validators to fail.

Props jorgefilipecosta, ocean90, gziolo.
Fixes #65035.

#5 @desrosj
7 weeks ago

  • Component changed from AI to Abilities API

Moving tickets related to the Abilities API to a new sub-component.

#6 @JeffPaul
5 weeks ago

  • Keywords fixed-major dev-feedback added; dev-reviewed removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening for merge to the 7.0 branch pending committer sign off.

#7 @gziolo
5 weeks ago

  • Keywords dev-reviewed added; dev-feedback removed

Let's make sure this is included in WP 7.0. Changes look good!

#8 @desrosj
5 weeks ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 62305:

Abilities: Strip internal schema keywords from abilities REST responses.

Remove WordPress-internal properties (sanitize_callback, validate_callback, arg_options) from ability input_schema and output_schema fields in REST responses. These properties are used server-side but are not valid JSON Schema keywords and cause client-side validators to fail.

Reviewed by gziolo, desrosj.
Merges [62221] to the 7.0 branch.

Props jorgefilipecosta, ocean90, gziolo, desrosj.
Fixes #65035.

Note: See TracTickets for help on using tickets.