Generating a VERP address
The task now is to generate a secure return-path, which is not bulky, and cannot be mimicked by an attacker. A very simple VERP address for a mail to bob@somewhere.com will be:
bounces-bob=somehwere.com@example.com
Since it can be easily exploited by an attacker, we need to also include a hash generated with a secret key, along with the address. Please note that the secret key is only visible to the sender and in no way to the receiver or an attacker.
Therefore, a standard VERP address will be of the form:
bounces-{ prefix }-{hash(prefix,secretkey) }@sender_domain
PHP has its own hash-generating functions that can make things easier. Since PHP’s hmacs cannot be decoded, but only compared, the idea will be to adjust the recipient email ID in the prefix part of the VERP address along with its hash. On receipt, the prefix and the hash can be compared to validate the integrity of the bounce.
We will string replace the ‘@’ in the recipient email ID to attach it along with the hash.
You need to edit your email headers to generate the custom return-path, and make sure you pass it as the fifth argument to the php::mail() function to tell your exim MTA to set it as the default envelope sender. $to = “bob@somewhere.com”; $from = “alice@example.com”; $subject = “This is the message subject “; $body = ‘This is the message body’; /** Altering the return path */ $alteredReturnPath = self::generateVERPAddress( $to ); $headers[ ‘Return-Path’] = $alteredReturnPath; $envelopeSender= ‘ -f ‘. $alteredReturnPath;
mail( $to, $subject, $body, $headers, $envelopeSender ); /** We need to produce a return address of the form - * bounces-{ prefix }- {hash(prefix) }@sender_domain, where prefix can be * string_ replaced(to_address ) */ public generateVERPAddress( $to ) { global $hashAlgorithm = ‘md5’; global $hashSecretKey = ‘myKey’; $emailDomain = ‘example.com’; $addressPrefix = str_replace( '@', '.', $to );
$verpAddress = hash_hmac( $hashAlgorithm , $to, $hashSecretKey );
$returnPath = bounes. ‘-’.$addressPrefix.’-’. $verpAddress. ‘@’. $emailDomain;
return $returnPath;
}
Including security features is yet another concern and can be done effectively by adding the current timestamp value (in UNIX time) in the VERP prefix. This will make it easy for the bounce processor to decode the email delivery time and add additional protection by brute-forcing the hash. Decoding and comparing the value of the timestamp with the current timestamp will also help to understand how old the bounce is.
Therefore, a more secure VERP address will look like what follows: bounces-{ to_address }-{ delivery_timestamp }-{ encode ( to_ address-delivery & timestamp ), secretKey }@somewhere.com
The current timestamp can be generated in PHP by:
$current_timestamp = time();
There’s still work to do before the email is sent, as the local MTA at example.com may try to set its own custom
return-path for messages it transmits. In the example below, we adjust the exim configuration on the MTA to override this behaviour. $ sudo nano /etc/exim4/exim4.conf # Do not remove Return Path header return_path_remove = false # Remove the field errors_to from the current router configuration. # This will enable exim to use the fifth param of php::mail() prefixed by -f to be set as the default # envelope sender
Every email ID will correspond to a user_id field in a standard user database, and this can be used instead of an email ID to generate a tidy and easy to look up VERP hash.