Skip to content

ultrafastwork/mailerlite-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Mailerlite Proxy Plugin

A secure proxy endpoint for Mailerlite API requests to keep API keys private and prevent exposure in public WordPress plugins.

Table of Contents


Overview

This plugin was created to solve a security issue where the Mailerlite API key was hardcoded in the Ultimate Dashboard plugin (a public WordPress plugin). By using this proxy, the API key is kept private on the server while the plugin communicates through a secure REST API endpoint.

Security Architecture

Ultimate Dashboard Plugin → Proxy Endpoint (this plugin) → Mailerlite API

Benefits:

  • API key is no longer exposed in public plugin code
  • Centralized API key management
  • Easier to rotate keys without updating multiple plugins

Known Limitation:

  • The proxy endpoint URL is still visible in the public plugin code
  • Potential for endpoint spam (mitigated by WordPress nonce and capability checks)

Quick Start

3-Step Setup

  1. Activate Plugin

    WordPress Admin → Plugins → Activate "Mailerlite Proxy"
    
  2. Secure API Key (Optional but Recommended)

    // Add to wp-config.php
    define( 'MAILERLITE_API_KEY', 'your-mailerlite-api-key-here' );
  3. Test

    Go to Ultimate Dashboard onboarding → Subscribe with test email
    

Installation

  1. Upload the mailerlite-proxy folder to /wp-content/plugins/
  2. Activate the plugin through the 'Plugins' menu in WordPress
  3. Configure the API key (see Configuration section below)
  4. Flush permalinks: SettingsPermalinksSave Changes

Configuration

Local Deployment

Option 1: Using wp-config.php (Recommended)

Add the following line to your wp-config.php file (above the "That's all, stop editing!" line):

define( 'MAILERLITE_API_KEY', 'your-mailerlite-api-key-here' );

Option 2: Environment Variable

If your hosting supports environment variables, set:

MAILERLITE_API_KEY=your-mailerlite-api-key-here

Then update line 151 in mailerlite-proxy.php:

$api_key = getenv( 'MAILERLITE_API_KEY' ) ?: 'fallback-key';

Option 3: Hardcode in Plugin (Development Only)

The plugin has a fallback API key hardcoded for development. For production, use Option 1 or 2.

Remote Deployment

For maximum security, deploy this plugin to a separate WordPress installation. See Remote Deployment Guide below.


API Documentation

Subscribe Endpoint

Endpoint: POST /wp-json/mailerlite-proxy/v1/subscribe

Authentication:

  • Local: WordPress REST API nonce (X-WP-Nonce header)
  • Remote: Proxy API Key (X-Proxy-API-Key header)

Required Capability: manage_options (local deployment only)

Parameters:

  • email (string, required) - Subscriber email address
  • name (string, required) - Subscriber name
  • group_id (string, required) - Mailerlite group ID

Group IDs

  • Onboarding Wizard: 112818510
  • Plugin Onboarding: 111311793

Usage Examples

JavaScript (wp.apiFetch)

wp.apiFetch({
	path: '/mailerlite-proxy/v1/subscribe',
	method: 'POST',
	data: {
		email: 'user@example.com',
		name: 'John Doe',
		group_id: '112818510'
	}
});

PHP (wp_remote_post)

$response = wp_remote_post(
	rest_url( 'mailerlite-proxy/v1/subscribe' ),
	[
		'body'    => wp_json_encode([
			'email'    => 'user@example.com',
			'name'     => 'John Doe',
			'group_id' => '112818510',
		]),
		'headers' => [
			'Content-Type' => 'application/json',
			'X-WP-Nonce'   => wp_create_nonce( 'wp_rest' ),
		],
		'timeout' => 15,
	]
);

if ( ! is_wp_error( $response ) ) {
	$response_code = wp_remote_retrieve_response_code( $response );
	if ( $response_code >= 200 && $response_code < 300 ) {
		// Success
	}
}

cURL (Testing)

curl -X POST https://yourdomain.com/wp-json/mailerlite-proxy/v1/subscribe \
  -H "Content-Type: application/json" \
  -H "X-WP-Nonce: YOUR_NONCE" \
  -d '{
    "email": "test@example.com",
    "name": "Test User",
    "group_id": "112818510"
  }'

Response Examples

Success:

{
	"success": true,
	"message": "Successfully subscribed to mailing list.",
	"data": {
		// Mailerlite API response data
	}
}

Error:

{
	"code": "invalid_email",
	"message": "Invalid or missing email address.",
	"data": {
		"status": 400
	}
}

Security

Security Features

  1. WordPress Nonce Verification - Prevents CSRF attacks
  2. Capability Check - Only users with manage_options capability can use the endpoint
  3. Input Sanitization - All inputs are sanitized before processing
  4. Email Validation - Ensures valid email addresses
  5. API Key Isolation - API key never exposed to client-side code
  6. Timing-Safe Comparison - Uses hash_equals() for API key validation

Authentication Methods

The proxy plugin supports two authentication methods:

1. WordPress Nonce (Local Deployment)

  • Used when proxy is on the same WordPress site
  • Requires logged-in user with manage_options capability
  • Header: X-WP-Nonce: [nonce]

2. Proxy API Key (Remote Deployment)

  • Used when proxy is on a different WordPress site
  • No user login required
  • Header: X-Proxy-API-Key: [your-secure-key]

Security Considerations

What's Protected

✅ Mailerlite API key never exposed to public
✅ Proxy API key in wp-config.php (not in code)
✅ API key authentication with hash_equals() (timing-attack safe)
✅ Separate server isolates sensitive operations

What's Still Visible

⚠️ Proxy endpoint URL visible in Ultimate Dashboard code
⚠️ Request structure visible in browser network tab

Additional Security Measures

Rate Limiting (Optional):

// Add to mailerlite-proxy.php in check_permission method
$user_id = get_current_user_id();
$transient_key = 'mailerlite_proxy_rate_limit_' . $user_id;
$request_count = get_transient( $transient_key );

if ( false === $request_count ) {
	set_transient( $transient_key, 1, HOUR_IN_SECONDS );
} elseif ( $request_count >= 10 ) { // Max 10 requests per hour
	return new WP_Error(
		'rate_limit_exceeded',
		__( 'Too many requests. Please try again later.', 'mailerlite-proxy' ),
		[ 'status' => 429 ]
	);
} else {
	set_transient( $transient_key, $request_count + 1, HOUR_IN_SECONDS );
}

IP Whitelist (Optional):

// Add to proxy plugin's check_permission() method
$allowed_ips = [ '123.456.789.0', '98.765.432.1' ];
$client_ip = $_SERVER['REMOTE_ADDR'];
if ( ! in_array( $client_ip, $allowed_ips, true ) ) {
	return new WP_Error( 'ip_blocked', 'Access denied', [ 'status' => 403 ] );
}

Testing & Verification

Pre-Activation Checklist

  • Plugin files created in wp-content/plugins/mailerlite-proxy/
  • Ultimate Dashboard subscribe classes updated
  • API key removed from Ultimate Dashboard plugin files
  • Permalinks flushed

Test Scenarios

Test 1: Onboarding Wizard Subscription

Steps:

  1. Navigate to Ultimate Dashboard onboarding wizard
  2. Fill in name and email fields
  3. Submit the subscription form
  4. Expected: Success message appears

Verification:

  • Check Mailerlite group 112818510 for new subscriber
  • Check browser console for any errors
  • Verify no API key visible in Network tab

Test 2: Plugin Onboarding Subscription

Steps:

  1. Navigate to Ultimate Dashboard plugin onboarding
  2. Fill in name and email fields
  3. Submit the subscription form
  4. Expected: Success message appears

Verification:

  • Check Mailerlite group 111311793 for new subscriber
  • Check browser console for any errors
  • Verify no API key visible in Network tab

Test 3: Error Handling - Invalid Email

Steps:

  1. Try subscribing with invalid email (e.g., "notanemail")
  2. Expected: Error message about invalid email

Verification:

  • Error message displayed to user
  • No subscription created in Mailerlite

Test 4: Error Handling - Empty Fields

Steps:

  1. Try subscribing with empty name or email
  2. Expected: Error message about required fields

Verification:

  • Error message displayed to user
  • No subscription created in Mailerlite

Test 5: Security - Unauthenticated Request

Steps:

  1. Log out of WordPress
  2. Try to access the proxy endpoint directly
  3. Expected: 403 Forbidden error

Verification:

  • Request blocked by permission check
  • Error message about authentication

Test 6: Security - Insufficient Permissions

Steps:

  1. Log in as a user without manage_options capability (e.g., Subscriber)
  2. Try to use the subscription form
  3. Expected: Permission error

Verification:

  • Request blocked by capability check
  • Error message about permissions

Network Inspection

What You Should See

Request to Proxy:

POST /wp-json/mailerlite-proxy/v1/subscribe
Headers:
  Content-Type: application/json
  X-WP-Nonce: [nonce-value]
Body:
  {
    "email": "test@example.com",
    "name": "Test User",
    "group_id": "112818510"
  }

What You Should NOT See

  • X-MailerLite-ApiKey header in browser requests
  • ❌ API key in request/response bodies
  • ❌ Direct requests to api.mailerlite.com

What the Server Does (Hidden from Browser)

Proxy Plugin → Mailerlite API
Headers:
  X-MailerLite-ApiKey: [hidden-api-key]
  Content-Type: application/json

Performance Benchmarks

Expected Response Times:

  • Proxy endpoint: < 100ms (local processing)
  • Mailerlite API: 200-500ms (external API)
  • Total (Local): 300-600ms
  • Total (Remote): 400-750ms (includes network latency)

If Slower:

  • Check server resources
  • Verify Mailerlite API status
  • Check network connectivity

Success Checklist

  • Plugin activated
  • API key secured (wp-config.php)
  • Test subscription successful
  • Subscriber appears in Mailerlite
  • No API key in browser network tab
  • Error handling works
  • Performance acceptable

Troubleshooting

Issue Cause Solution
Invalid security token Nonce verification failed Log in as admin, clear cache, verify REST API accessible
Permission denied User lacks manage_options Log in as Administrator
404 error Permalinks not flushed Settings → Permalinks → Save Changes
Mailerlite API error Invalid API key or group ID Check API key and group ID validity
Connection timeout Remote server unreachable Verify server is online, check DNS, test endpoint manually
Invalid proxy API key Keys don't match between sites Verify MAILERLITE_PROXY_API_KEY is identical on both sites
Proxy API key not configured Constant not defined on remote Add constant to remote server's wp-config.php
CORS errors Cross-origin request blocked WordPress REST API handles CORS by default, check server config

Detailed Solutions

"Invalid security token"

  1. Ensure user is logged in
  2. Clear browser cache
  3. Check if REST API is accessible
  4. Verify nonce is being sent in X-WP-Nonce header

"Mailerlite API error"

  1. Verify API key is correct
  2. Check group ID is valid
  3. Ensure server can reach api.mailerlite.com
  4. Check Mailerlite API status page

404 on Proxy Endpoint

  1. Go to Settings → Permalinks → Save Changes
  2. Deactivate and reactivate the plugin
  3. Check if REST API is enabled

Admin Notice Won't Dismiss

  1. Add to wp-config.php: define( 'MAILERLITE_API_KEY', 'your-key' );
  2. Or dismiss the notice (it will show again on next page load)

Remote Deployment Guide

For maximum security, deploy this plugin to a separate WordPress installation.

Architecture

Local Deployment (Default)

[Ultimate Dashboard Plugin]
         ↓ (WordPress Nonce)
[Mailerlite Proxy Plugin] (same site)
         ↓ (Mailerlite API Key)
[Mailerlite API]

Remote Deployment (Recommended for Production)

[Ultimate Dashboard Plugin] (public site)
         ↓ (Proxy API Key)
[Mailerlite Proxy Plugin] (private API server)
         ↓ (Mailerlite API Key)
[Mailerlite API]

Step-by-Step Setup

Step 1: Set Up Remote API Server

  1. Create a new WordPress installation

    Domain: api.yourdomain.com (or subdomain of your choice)
    
  2. Harden the WordPress installation

    • Disable XML-RPC
    • Disable file editing
    • Enable strong passwords
    • Install security plugin (e.g., Wordfence)
    • Keep WordPress core updated
    • Remove unused themes/plugins
  3. Upload the Mailerlite Proxy plugin

    Upload: wp-content/plugins/mailerlite-proxy/
    
  4. Activate the plugin

    WordPress Admin → Plugins → Activate "Mailerlite Proxy"
    

Step 2: Configure Remote API Server

Add these constants to wp-config.php on the remote API server:

// Mailerlite API key (keep this secret!)
define( 'MAILERLITE_API_KEY', 'your-mailerlite-api-key-here' );

// Proxy API key for authentication (generate a strong random key)
define( 'MAILERLITE_PROXY_API_KEY', 'your-secure-random-key-here' );

Generate a secure random key:

# Linux/Mac
openssl rand -base64 32

# Or use online generator
# https://www.random.org/strings/

Example:

define( 'MAILERLITE_PROXY_API_KEY', 'K8vN2pQ9mR5tY7wZ3xC6bV4nM1hG0jF8' );

Step 3: Configure Ultimate Dashboard Site

Add these constants to wp-config.php on the Ultimate Dashboard site (public site):

// Remote proxy endpoint URL
define( 'MAILERLITE_PROXY_URL', 'https://api.yourdomain.com/wp-json/mailerlite-proxy/v1/subscribe' );

// Proxy API key (must match the key on remote server)
define( 'MAILERLITE_PROXY_API_KEY', 'K8vN2pQ9mR5tY7wZ3xC6bV4nM1hG0jF8' );

Important: The MAILERLITE_PROXY_API_KEY must be identical on both sites.

Step 4: Test the Connection

  1. Test from Ultimate Dashboard site

    • Go to Ultimate Dashboard onboarding wizard
    • Fill in name and email
    • Submit subscription
  2. Check the response

    • Should see success message
    • Check Mailerlite dashboard for new subscriber
  3. Check logs

    • Remote server: Check WordPress error logs
    • Ultimate Dashboard site: Check browser console

Configuration Summary

Remote API Server (api.yourdomain.com)

File: wp-config.php

// Mailerlite API credentials
define( 'MAILERLITE_API_KEY', 'your-mailerlite-api-key-here' );

// Proxy authentication key
define( 'MAILERLITE_PROXY_API_KEY', 'K8vN2pQ9mR5tY7wZ3xC6bV4nM1hG0jF8' );

Plugins:

  • Mailerlite Proxy (active)
  • Security plugin (recommended)

Ultimate Dashboard Site (yourdomain.com)

File: wp-config.php

// Remote proxy endpoint
define( 'MAILERLITE_PROXY_URL', 'https://api.yourdomain.com/wp-json/mailerlite-proxy/v1/subscribe' );

// Proxy authentication key (same as remote server)
define( 'MAILERLITE_PROXY_API_KEY', 'K8vN2pQ9mR5tY7wZ3xC6bV4nM1hG0jF8' );

Plugins:

  • Ultimate Dashboard (with updated subscribe classes)

Remote Deployment Testing Checklist

Remote Server Tests

  • Plugin activated
  • MAILERLITE_API_KEY defined in wp-config.php
  • MAILERLITE_PROXY_API_KEY defined in wp-config.php
  • Endpoint accessible: /wp-json/mailerlite-proxy/v1/subscribe
  • SSL certificate valid (HTTPS)

Ultimate Dashboard Site Tests

  • MAILERLITE_PROXY_URL defined in wp-config.php
  • MAILERLITE_PROXY_API_KEY defined in wp-config.php
  • Subscription form works
  • Success message appears
  • Subscriber added to Mailerlite

Security Tests

  • API key not visible in browser network tab
  • Invalid API key rejected
  • Request without API key rejected
  • HTTPS enforced

Monitoring & Maintenance

What to Monitor

  1. Subscription Success Rate

    • Track successful vs failed subscriptions
    • Alert on sudden drops
  2. API Response Times

    • Monitor remote proxy latency
    • Alert on slow responses (>2 seconds)
  3. Error Logs

    • Check remote server logs daily
    • Look for authentication failures
    • Monitor for suspicious activity
  4. Mailerlite Account

    • Verify subscriptions are being added
    • Check for duplicate entries
    • Monitor API usage limits

Regular Maintenance

Weekly:

  • Review error logs
  • Check subscription success rate
  • Verify API keys still valid

Monthly:

  • Update WordPress core on API server
  • Update plugins on API server
  • Review security logs
  • Test failover procedures

Quarterly:

  • Rotate proxy API key
  • Security audit
  • Performance review
  • Update documentation

Rollback Plan

If remote deployment fails:

  1. Remove constants from Ultimate Dashboard site

    // Comment out or remove these lines
    // define( 'MAILERLITE_PROXY_URL', '...' );
    // define( 'MAILERLITE_PROXY_API_KEY', '...' );
  2. Install proxy plugin locally

    • Upload to Ultimate Dashboard site
    • Activate plugin
    • Add MAILERLITE_API_KEY to wp-config.php
  3. Test local deployment

    • Subscription should work with WordPress nonce
    • No remote API key needed

Changelog

1.0.0

  • Initial release
  • Secure proxy endpoint for Mailerlite subscriptions
  • WordPress REST API integration
  • Nonce and capability verification
  • Remote deployment support with API key authentication

Support

For issues or questions, contact MapSteps support.


License

This plugin is proprietary software developed by MapSteps.

Version: 1.0.0
Last Updated: 2025-10-06
Author: MapSteps

About

Secure proxy endpoint for Mailerlite API requests to keep API keys private.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages