Rate Limiting Guide

Rate Limiting is available for CoCart Plus or higher. This is optional and disabled by default. It can be enabled by following these instructions or if alternatively install the rate limiter plugin and configure the options in your wp-config.php file.

The main purpose was to prevent abuse on endpoints from excessive calls and performance degradation on the machine running the store.

Rate limit tracking is controlled by either USER ID (logged in) or IP ADDRESS (unauthenticated requests).

It also offers standard support for running behind a proxy, load balancer, etc. This also optional and disabled by default.

Limit information

A default maximum of 25 requests can be made within a 10-second time frame. These can be changed through an options filter.

Methods restricted by Rate Limiting

POST, PUT, PATCH, and DELETE

Rate Limiting options via filter

A filter is available for setting options for rate limiting:

add_filter( 'cocart_api_rate_limit_options', function() {
	return [
		'enabled' => false, // enables/disables Rate Limiting. Default: false
		'proxy_support' => false, // enables/disables Proxy support. Default: false
		'limit' => 25, // limit of request per timeframe. Default: 25
		'seconds' => 10, // timeframe in seconds. Default: 10
	];
} );

Rate Limiting options via wp-config.php

These constants can be added to your wp-config.php which will override the default values if you have installed the rate limiter plugin.

define( 'COCART_RATE_LIMITING_ENABLED', true );
define( 'COCART_RATE_LIMITING_PROXY_SUPPORT', false );
define( 'COCART_RATE_LIMITING_LIMIT', 25 );
define( 'COCART_RATE_LIMITING_SECONDS', 10 );

Proxy standard support

If the store is running behind a proxy, load balancer, cache service, CDNs, etc. keying limits by IP is supported through standard IP forwarding headers, namely:

X_REAL_IP|CLIENT_IP Custom popular implementations that simplify obtaining the origin IP for the request
X_FORWARDED_FOR De-facto standard header for identifying the originating IP, Documentation
X_FORWARDED Documentation, RFC 7239

This is disabled by default.

Limit usage information observability

Current limit information can be observed via custom response headers:

RateLimit-Limit Maximum requests per time frame.
RateLimit-Remaining Requests available during current time frame.
RateLimit-Reset Unix timestamp of next time frame reset.
RateLimit-Retry-After Seconds until requests are unblocked again. Only shown when the limit is reached.

Response headers example

RateLimit-Limit: 5
RateLimit-Remaining: 0
RateLimit-Reset: 1654880642
RateLimit-Retry-After: 28

Tracking limit abuses

This uses a modified wc_rate_limit table with an additional remaining column for tracking the request count in any given request window. A custom action cocart_api_rate_limit_exceeded was implemented for extendibility in tracking such abuses.

Custom tracking usage example

add_action(
    'cocart_api_rate_limit_exceeded',
    function ( $offending_ip ) { /* Custom tracking implementation */ }
);

Testing Guide

Without proxy support

1. Enable Rate Limiting by using the options filter.
2. In a short window, keep making API requests.
3. Check that RateLimit-xxx headers change on each request.
4. Check that once you’ve hit the limit, an error response is returned. You can modify the limits using the options filter to make it easier to test.

With proxy support, do the same as before and

1. Enable proxy support.
2. Make your requests with one of the following request headers containing always the same IP address:

User Facing Testing

1. Enable Rate Limiting by using the options filter.
2. Try to adding an item many times over or access `/wp-json/cocart/v2/cart/add-item` beyond current limits (currently 25 requests under 10 seconds)
3. Ensure you get presented with an error “Too many requests. Please wait xx seconds before trying again.

Was this helpful to you?