Skip to content

Conversation

Ref34t
Copy link
Contributor

@Ref34t Ref34t commented Sep 30, 2025

Summary

Changes Made

Documentation Improvements

  • docs/2.getting-started.md: Replaced 22-line manual permission checking example with clean 8-line execute() pattern
  • docs/4.using-abilities.md: Eliminated manual permission checking anti-patterns, added advanced error handling section showing how to handle specific error types

REST API Controller Update

  • includes/rest-api/endpoints/class-wp-rest-abilities-run-controller.php: Updated permission check to use strict comparison (true !==) for consistency with execute() pattern

Discussion Point

As @gziolo noted, this isn't a security vulnerability since each ability's execute() method already performs comprehensive permission checking. The REST API controller creates a two-layer permission model:

  1. REST API layer: Pre-check via run_ability_permissions_check()
  2. Ability execution layer: Full check via execute()

The controller's permission callback is architecturally unique because it dynamically checks permissions for any ability. We could consider simplifying by removing the separate permission callback and relying entirely on execute()'s error handling.

Open to feedback on this approach.

Test plan

  • Verify documentation examples follow recommended execute() pattern
  • Confirm no manual permission checking anti-patterns remain in docs
  • Test REST API endpoint permission handling

Copy link

github-actions bot commented Sep 30, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @mohamed.khaled@9hdigital.com.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: mohamed.khaled@9hdigital.com.

Co-authored-by: justlevine <justlevine@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: Ref34t <mokhaled@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

codecov bot commented Sep 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.92%. Comparing base (80f47ee) to head (0fd3448).

Additional details and impacted files
@@             Coverage Diff              @@
##              trunk      #95      +/-   ##
============================================
- Coverage     85.69%   84.92%   -0.78%     
  Complexity      103      103              
============================================
  Files            16       16              
  Lines           776      776              
  Branches         86       85       -1     
============================================
- Hits            665      659       -6     
- Misses          111      117       +6     
Flag Coverage Δ
javascript 92.66% <ø> (ø)
unit 81.89% <100.00%> (-1.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gziolo
Copy link
Member

gziolo commented Sep 30, 2025

REST API security vulnerability

I don't think we are really experiencing a security vulnerability here, because every ability handles permissions check individually during execution as discussed in #76 (comment). That being said, we can iterate on the handling because the run controller is unique, as its permissions check model differs for each ability.

@gziolo gziolo added the [Type] Bug Something isn't working label Sep 30, 2025
@gziolo
Copy link
Member

gziolo commented Oct 1, 2025

This PR needs a rebase to resolve conflicts after #94 landed. This would help to review the changes proposed in this PR.

@Ref34t
Copy link
Contributor Author

Ref34t commented Oct 1, 2025

@gziolo on it

Mohamed Khaled added 3 commits October 1, 2025 11:03
… examples

- Eliminate all manual permission checking examples that could lead to security vulnerabilities
- Add advanced error handling section with specific error code handling
- Update variable names for consistency across examples
- Address @justlevine's feedback about documentation anti-patterns
Change permission check from loose to strict comparison in run_ability_permissions_check().
The previous pattern `if ( ! $ability->check_permission( $input ) )` would incorrectly
pass WP_Error objects as truthy, potentially allowing unauthorized access.

Fixed by using `if ( true !== $ability->check_permission( $input ) )` to properly
handle both false and WP_Error return values.
The strict permission checking now correctly catches input validation
failures in the permission check phase, returning 403 instead of
allowing invalid requests to proceed to execution-specific validation.

Updated 4 failing tests to expect 403 status and appropriate error codes:
- test_resource_ability_requires_get
- test_get_request_with_non_array_input
- test_post_request_with_non_array_input
- test_input_validation_failure_returns_error
@Ref34t Ref34t force-pushed the feature/fix-documentation-clean branch from 9df7d76 to bb906c3 Compare October 1, 2025 08:05
@Ref34t Ref34t changed the title Fix documentation anti-patterns and REST API security vulnerability docs: Improve permission checking documentation and examples Oct 1, 2025
@Ref34t
Copy link
Contributor Author

Ref34t commented Oct 1, 2025

I've updated the PR title and description - you're right that this isn't a security vulnerability.

The reason: even if the REST API permission check had the WP_Error truthiness issue, execute() on line 136 would still block unauthorized access since it performs its own permission check internally.

This update improves code correctness by using strict comparison (true !==) to properly handle all return types from check_permissions(), but it's not fixing an actual security hole due to the two-layer permission model.

Once abilities are registered, they can be retrieved and executed using global functions from the Abilities API.

## Getting a Specific Ability (`wp_get_ability`)
**Getting a Specific Ability (`wp_get_ability`)**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been known to misread diffs on mobile 🫣 but if all these reverted to **, then it's a leak from #96 and should be changed back to semantic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved 0fd3448

@Ref34t Ref34t requested a review from justlevine October 2, 2025 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants