Skip to main content

Unsubscribe link obfusucate email and campaignid via php

To obfuscate the email and campaign ID in an unsubscribe link using PHP, you should encode the data into a single, signed token (e.g., using hash_hmac) rather than including the raw values in the URL query parameters. This approach prevents bots from harvesting emails and ensures the data's integrity. 

1. Generating the Obfuscated Link
First, you need a secret key stored securely on your server. When generating the email, you'll create a unique token for each recipient by combining the email and campaign ID and signing it with your secret key. 

php
<?php
// Define a strong, secret key in your configuration
define('SECRET_KEY', 'your_very_strong_server_secret_key_here');

// Data to obfuscate
$email = 'useremail@example.com';
$campaign_id = 123;

// Combine data into a single string
$data = $email . '|' . $campaign_id;

// Generate a signature (HMAC) of the data
$signature = hash_hmac('sha256', $data, SECRET_KEY);

// Base64-url encode the data for safe URL transmission
$encoded_data = rtrim(strtr(base64_encode($data), '+/', '-_'), '=');

// Create the final token (data.signature format)
$token = $encoded_data . '.' . $signature;

// Construct the unsubscribe link
$unsubscribe_url = "yourdomain.com" . urlencode($token);

echo '<a href="' . htmlspecialchars($unsubscribe_url) . '">Unsubscribe</a>';
?>

2. Processing the Link in unsubscribe.php 
When a user clicks the link, the unsubscribe.php script will validate the token before processing the request.

php
<?php
// Define the same secret key used for generation
define('SECRET_KEY', 'your_very_strong_server_secret_key_here');

if (isset($_GET['token'])) {
    $token = $_GET['token'];
    $parts = explode('.', $token);

    if (count($parts) === 2) {
        $encoded_data = $parts[0];
        $received_signature = $parts[1];

        // Decode the data part
        $data = base64_decode(strtr($encoded_data, '-_', '+/'));

        // Re-calculate the expected signature
        $expected_signature = hash_hmac('sha256', $data, SECRET_KEY);

        // Verify the signature
        if (hash_equals($expected_signature, $received_signature)) {
            // Token is valid and has not been tampered with
            list($email, $campaign_id) = explode('|', $data);

            // Validate the email format and campaign ID type
            if (filter_var($email, FILTER_VALIDATE_EMAIL) && is_numeric($campaign_id)) {
                // Perform the unsubscribe action (e.g., update your database)
                // Example: update_user_status($email, $campaign_id, 'unsubscribed');
                echo "You have been successfully unsubscribed from campaign " . htmlspecialchars($campaign_id) . ".";
            } else {
                echo "Invalid data in token.";
            }
        } else {
            // Invalid signature - potential tampering
            echo "Invalid or tampered unsubscribe link.";
        }
    } else {
        echo "Invalid token format.";
    }
} else {
    echo "No token provided.";
}

// Helper function for secure string comparison (prevents timing attacks)
function hash_equals_safe($str1, $str2) {
    if(strlen($str1) !== strlen($str2)) {
        return false;
    }
    $res = 0;
    for ($i = 0; $i < strlen($str1); $i++) {
        $res |= ord($str1[$i]) ^ ord($str2[$i]);
    }
    return $res === 0;
}

// Use hash_equals_safe($expected_signature, $received_signature) in PHP < 5.6
if (!function_exists('hash_equals')) {
    function hash_equals($str1, $str2) {
        // ... implementation from above ...
        return hash_equals_safe($str1, $str2);
    }
}
?>
This method securely encodes the necessary information while preventing the raw email and campaign ID from being openly visible or easily abused. 

Best Practice
Consider adding the List-Unsubscribe header to your emails. This allows email clients (like Gmail or Outlook) to provide a native "Unsubscribe" button within their interface, improving deliverability and user experience. 

php
// When sending the email (using PHPMailer as an example):
$mail->addCustomHeader('List-Unsubscribe', '<yourdomain.com' . urlencode($token) . '>');
$mail->addCustomHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click'); // For one-click handling