Code

Write a secure REST API endpoint with proper permission callbacks

A register_rest_route scenario that reasons through the gap between is_user_logged_in and real capability checks, plus param validation and rate-limit judgment calls.

Works with Claude / GPT2,100 uses 4.6

The prompt

code-secure-rest-api-endpoint
I need a REST endpoint `POST /wp-json/myplugin/v1/orders/{id}/refund` that a React
admin dashboard calls to trigger a partial refund. It needs to accept a JSON body
`{ "amount": 25.00, "reason": "damaged item" }`.

CONTEXT: [this endpoint currently exists with `'permission_callback' => function() {
return is_user_logged_in(); }` and a support rep flagged that a logged-in subscriber
from the storefront was somehow able to hit it in testing]

Fix this like a senior dev doing a security pass on an API surface, in order:
1. Explain precisely why `is_user_logged_in()` is the wrong check here: it verifies
   identity, not authorization, so any logged-in customer account passes it. Replace it
   with a proper `current_user_can()` check against a specific capability (not just
   `manage_options`, since a shop manager role should also be allowed, so map it to a
   custom capability like `process_refunds`).
2. Validate the route args with `args` schema in `register_rest_route()`: `id` must be
   a valid, existing order ID owned by a real order (not just numeric), `amount` must
   be a positive number not exceeding the order's remaining refundable total, and
   `reason` should be sanitized text with a max length.
3. Show the full `register_rest_route()` call plus the callback, using
   `WC_REST_Response` or `WP_REST_Response` with correct HTTP status codes (403 for
   permission failure, 404 for missing order, 422 for invalid amount, not a blanket 200
   with an error string in the body).
4. Flag the edge case: nonce vs application password auth. If the dashboard uses
   cookie auth, the endpoint also needs `X-WP-Nonce` verification via
   `wp_verify_nonce()`, since `permission_callback` alone doesn't protect against CSRF
   for cookie-authenticated requests, only against unauthorized users.
5. Recommend a lightweight rate limit or at least logging on this route, since refund
   endpoints are a common target for abuse if a capability check ever regresses again.

Replace the route, capability, and validation rules with your actual endpoint's needs.

The is_user_logged_in() mistake in step 1 is one of the most common REST API vulnerabilities in WordPress plugins, since it looks correct in a quick test with an admin account and only fails once a lower-privilege user tries it. Always test permission callbacks with the lowest-privilege role that should be denied, not just the highest one that should be allowed.