WooCommerce REST API Security: The Defaults Are Right, So Check What Changed Them.
Every WooCommerce admin endpoint returned 401 unauthenticated on both stores we tested. The risk comes from what gets added afterwards.
Short answer: woocommerce rest api security is sound out of the box. Every admin endpoint refuses an unauthenticated request. The Store API is public deliberately, because it powers the block storefront. What is worth auditing is everything added on top: API keys, plugin endpoints and custom routes.
I probed a test store and a live one rather than assuming either way.
What answers, and what does not

request, and the two that answer are meant to.*
| Endpoint | Test store | woocommerce.com | By design? |
|---|---|---|---|
/wc/v3/orders | 401 | 401 | yes, admin API, key required |
/wc/v3/customers | 401 | 401 | yes |
/wc/v3/products | 401 | not tested | yes |
/wc/v3/reports/sales | 401 | not tested | yes |
/wc/store/v1/products | 200 | 200 | yes, powers the block storefront |
/wc/store/v1/cart | 200 | not tested | yes, session-scoped, returns your cart only |
Caveat: two stores, one test and one live, checked once. This does not prove every WooCommerce install behaves the same; it proves the defaults are correct on the two I could verify directly, which is a reasonable basis for trusting the defaults and auditing what was added on top instead.
The Store API returning 200 is not a finding. It exists so a block-based storefront can fetch products and cart contents from the browser. The cart endpoint is session-scoped: it returns your cart, keyed to your cookie, not anybody else’s.
I checked that specifically while testing cart caching, and two separate sessions returned entirely different payloads, which is the correct behaviour.
What is actually worth checking for WooCommerce REST API security

and none of them announce themselves.*
| Failure | How it looks | How to find it |
|---|---|---|
| API key issued read/write, never revoked | 401 to you, 200 to whoever holds it | Settings → Advanced → REST API, check last-access dates |
| plugin registers its own unauthenticated endpoint | 200 | read /wp-json/, look at every unfamiliar namespace |
custom permission_callback returning true | 200 | code review, or probe the routes it advertises |
| order data exposed via search or export endpoint | 200 | probe with a query string; some exporters skip auth on parameters |
The second row is the most common by a distance. Every plugin that registers a namespace under /wp-json/ adds surface, and the REST index lists them all for anybody who asks.
The first row is the one with the longest tail. An API key issued to a developer, an integration, or a migration tool three years ago is still valid until somebody revokes it. WooCommerce records a last-access date against each key, which makes the review quick: anything unused for months is a credential nobody is monitoring.
Probing a store

or 403 on those four is worth investigating immediately.*
Reading the namespace list is the step I would not skip on an inherited store. Unfamiliar namespaces are where custom code and abandoned integrations live, and they are frequently the work of somebody who is no longer available to explain them.
It is the same instinct as reading the abilities a site exposes before connecting anything to it: inventory first, opinions afterwards.
Keeping it that way
Three habits, none expensive.
Review API keys quarterly. Revoke anything with no recent access. A key is a credential, and credentials outlive the projects that needed them.
Re-probe after every plugin addition. A new namespace appearing is normal; a new namespace answering unauthenticated is not.
Watch the wider information-disclosure surface too. A store that also hands out its usernames through the REST API gives an attacker both halves of what a credential attack needs.
Never issue read/write when read will do. Most integrations that ask for full access need to list products, and the difference matters enormously on the day the key leaks.
Protuno’s free audit checks whether a WooCommerce admin endpoint answers unauthenticated, from the domain alone, alongside storefront and checkout reachability. Straight with you as on every post here: Till, the eCommerce agent that would re-probe after each deploy, is built and named but not live yet.
Run the four-endpoint loop on every store you look after. It takes seconds per site, and the expected result is four 401s. Anything else is your afternoon.
Comments