Skip to content

Add rate limiting to POST /consent endpoint to prevent database flooding #195

@betayazilim

Description

@betayazilim

Description

The POST /pressidium-cookie-consent/v1/consent REST endpoint (registered at includes/Admin/Settings/Settings_API.php:1280-1330) uses __return_true as its permission callback, which is necessary since unauthenticated visitors need to record their consent.

However, there is no rate limiting, throttling, or abuse prevention on this endpoint. An attacker could flood the pressidium_cookie_consents table with fake consent records by scripting rapid POST requests.

Current code (line 1328):

'permission_callback' => '__return_true',

Impact

  • Database growth: Each request inserts a row into the custom table. Automated abuse could generate millions of rows.
  • Disk/storage exhaustion: On shared hosting, this could fill available storage.
  • Admin performance: The consent records admin page would become slow with millions of rows.
  • Audit integrity: Fake records would pollute legitimate consent logs, undermining their value for GDPR proof-of-consent.

Suggested Mitigations

  1. IP-based throttle: Limit consent records per IP address per time window (e.g., max 5 per minute per IP)
  2. UUID validation: The uuid parameter is currently any string — validate it as a proper UUID v4 format
  3. Cookie check: Only accept consent from clients that have the consent cookie set (preventing blind POST attacks)
  4. Nonce via script: Generate a one-time token in wp_localize_script and require it on the endpoint

Example throttle implementation:

$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$transient_key = 'pcc_consent_rate_' . md5( $ip );
$count = (int) get_transient( $transient_key );

if ( $count >= 5 ) {
    return new WP_Error( 'rate_limited', 'Too many requests', array( 'status' => 429 ) );
}

set_transient( $transient_key, $count + 1, MINUTE_IN_SECONDS );

Environment

  • Plugin version: 1.9.1

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request
No fields configured for Feature.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions