Problems with tracking pixels and Gmail proxy - php

I am trying to implement a custom Tracking Pixel for Emails sent out from wordpress.
Thanks to these post:
Tracking email with PHP and image
Tracking email opens with a real image
and especially
http://www.phpdevtips.com/2013/06/email-open-tracking-with-php-and-mysql/
I was able to implement the core idea.
The email loads the tracking pixel via
<img src="https://www.example.com/tracking.php?order_id=1" width="100" height="100" />
and in the tracking.php
$graphic_http = 'https://www.example.com/GIF-example.gif';
header('Content-Type: image/gif');
readfile( $graphic_http );
Opening the tracking.php file in a browser opens up the gif image for download.
However the Tracking pixel/Tracking image doesn't show up in the Gmail Email. There is only a broken image logo and when I click to show the image this link is opened
https://ci5.googleusercontent.com/proxy/l2xUKFGnNFKm64zEYmJhOcUmEJm15w9MC1txRRF01tpKlcL3t3O16aMJgbYQkucBySV0xV2T0EsCwikOAC0Z4em6uPzSs38lkHrYBvosRRAk14EfPoEXqC5JdLxRm8ToZmGSQqt_RwHCaBE_3uLgQDVEB05Rdtkq-Xzuw30=s0-d-e1-ft#https://www.example.com/tracking.php?order_id=1
which states a Google 404:
Google 404. That’s an error.
The requested URL /proxy/l2xUKFGnNFKm64zEYmJhOcUmEJm15w9MC1txRRF01tpKlcL3t3O16aMJgbYQkucBySV0xV2T0EsCwikOAC0Z4em6uPzSs38lkHrYBvosRRAk14EfPoEXqC5JdLxRm8ToZmGSQqt_RwHCaBE_3uLgQDVEB05Rdtkq-Xzuw30=s0-d-e1-ft was not found on this server. That’s all we know.
It seems to be a problem that Google's proxy cannot read the php script. Both the tracking.php and the GIF-example.gif files have 775 rights and are accesible publicly.
On Hotmail this does work so it really seems to be a problem with the Google Proxies.
Does anybody know how to let the Google Proxies access this Tracking pixel?

I figured out the answer: The problem was with the Google Proxies and the question mark ? in https://www.example.com/tracking.php?order_id=1
The Google Proxies address got messed up because it already had a question mark and resulted in a 404.
I resolved it using https://www.example.com/tracking.php/order_id=1 instead and then on the tracking.php I didn't use $_GET but $_SERVER['REQUEST_URI'] and parsed the /order_id= String.
The tracking pixel shows up in Gmail and it gets tracked in the tracking.php script.

All your headers are trying to force the browser to download the file and ignore it's file type (since you never say what file type it is). For images to be displayed in the browser, you need to set the correct header.
This is basically all you need to do:
$orderId = isset($_GET['order_id']) ? $_GET['order_id'] : null;
if ($orderId) {
// Save stuff in your DB or how you want to log it.
}
header('Content-Type: image/gif');
echo file_get_contents('/absolute/path/to/image.gif');
exit; // Not really necessary, but just to make sure there's no more output.

Related

How Can I bypass the GMAIL proxy and make a tracking pixel in 2021?

I want to make a program similar to the chrome extension mailtrack.
It can track when a user opens an email, and I want to do the same.
I have made an image on my webserver so that it will open and write to a file whenever it is requested. (e.g a tracking pixel).
This doesn't work, because google proxies, and caches the image; rewriting the url to https://foo.googleusercontent.com/proxy/foobarfoobarfoobar#myoriginalurl.
This causes the request not to be made to my server, but googles.
How can I fix this?
And if it is impossible, ok, but then how would the aforementioned mailtrack work?
My code is:
<?php
$file = 'image.png';
$fp = fopen('log.log', 'a');
fwrite($fp, 'Opened' . PHP_EOL);
header('Content-Type: image/png');
readfile($file);
?>
When you send an email, Mailtrack automatically adds a tracking pixel (a really small image) to that email. Then, when it is opened the tracking pixel is downloaded and sends a call to our servers to let us know the mail has been opened.
Also,
Mailtrack is an email tracking tool. It tells you if your emails have been opened or not, and how many times, through its pixel-based tracking system.
I have fixed it. I use python to do it now.
My server code for others wondering is:
import flask
import random
app = flask.Flask(__name__)
#app.route('/sig.png')
def sig():
print(f'Requested {random.randint(1,9999)}')
return flask.send_file('images/sig.png', 'image/png')
app.run('0.0.0.0', 8080)

Email Tracking using "image" method won't work with Gmail

If I'm not being clear about anything let me know... I'm new to SO.
I'm having troubles getting Gmail to approve of my image URL that will activate my PHP script to track when people open my emails.
Gmail only allows me to "insert" photos that are specifically image files, such as png or jpg files. I have tried using a file-include mechanism:
http://www.example.com/?file=image.png with a two-line PHP script that includes the png file and then writes to a log all the tracking info. However, I have found this doesn't work since I'm technically referencing index.php in the URL.
I have also tried http://www.example.com/script.php where script.php would look like this:
<img src=image.png>
<?php
// write "Someone viewed your mail" in logs
?>
This doesn't work either because I'm still referencing a PHP file.
I'm using the Insert Photo > Web Address feature in Gmail... should I be inserting the file differently to fix my problem? I need to find a way to directly reference an image file on my server but also activate the PHP script.
Any ideas? Am I overlooking something obvious?
Figured out I can do this with Thunderbird:
Write --> Insert --> HTML
In the HTML box:
<img src="www.mysite.com/script.php">
Hopes this helps anyone who had my problem

Can I use PHP in a email signature?

I have a question. I would like to add rotating links inside my email signature to
track results on my site. I can make these dynamic tracking urls on google as you may know
but I would like to rotate them inside my email signature to see which text draws the most
conversions or returning visitors.
Is this possible?
I found this for instance:
$mybanners[1] = '<img src="banner1.jpg">';
$mybanners[2] = '<img src="banner1.jpg">';
$id = rand(1,2);
echo $mybanners[$id];
But when I look into my windows live mail I can only upload html files.
Does someone know how to do this?
You can't provide PHP scripts in a mail, since it is a server-side language and it will be opened by a mail client. Even Javascript is very often blocked for security reason.
What you can do is make a "fake" image which will be in fact generate by a PHP script. YOu can find inspiration by looking to script made for forum avatar rotation. The idea is to generate an image, which will be displayed to the client but, in the same time, save some data about the user who requests the image if you want:
<?php
// Save whatever you want about the user
file_put_content("log/user.txt", $_SERVER['HTTP_REFERER']);
// Render a valid PNG image
header('Content-Type: image/png');
readfile("/path/to/banner.png");
?>
This script should be used as a standard image (with, if you want, a nice URL rewrite to make a .png link):
<img src="http://www.example.com/my_super_banner.php" />
where my_super_banner.php is the script described before.

Facebook Proxy Loader Security

I'm using a PHP proxy script to load images from Facebook into Flash without any sandbox violations. It is taken from the guide here: http://www.permadi.com/blog/2010/12/loading-facebook-profile-picture-into-flash-swf-using-open-graph-api/. The relevant PHP code is:
<?php
$path=$_GET['path'];
if (stristr($path, "fbcdn.")==FALSE && stristr($path, "facebook.")==FALSE)
{
echo "ERROR";
exit;
}
header("Content-Description: Facebook Proxied File");
header("Content-Type: image");
header("Content-Disposition: attachment; filename=".$path);
#readfile($path);
?>
The guide mentions that additional security measures are recommended for a real world application. What additional measures would be applicable to this? Maybe some kind of key passed from Flash to PHP?
I realise that there's nothing I can do to completely protect the Flash from being decompiled, but can I prevent the script from being used maliciously?
You should restrict the proxy to fetching image files from Facebook. You current "protection" will allow for example this URL: http://virus.provider.com/fbcdn./virus.exe
Make better checks of the domain bname, maybe using the parse_url function.
Check that you are indeed serving only images. Make sure the filename is ending in a image extension (this helps a lot for Windows clients), but also consider doing more thorough checks of the actual file content.
Consider adding a check of the $_SERVER['HTTP_REFERER'] to lower the incentives to use your script for hotlinking. If the HTTP_REFERER is non-empty, check that it's actually your site in there. This will mostly protect you from bandwidth thieves.
Make sure it's actually a remote path. Your current script can be tricked to sending for example your PHP files unparsed, including passwords and other secrets!
The filname in the Content-Disposition header should be set to a filename, not to the entire path.
Also consider caching the file data on your proxy server to speed up multiple calls to the same file.
These are a few of the things to keep in mind. You may reveal more if you put some thought into it.

How do I load an image in PHP

I want code that loads an image to a PHP server and then send it to browser.
For example I want sample.php to send an image to browser once it is requested.
in other words, I want to create a PHP file that acts like a proxy for an image.
why are you doing this?
why don't deliver the image directly?
if you are trying to display a random image you may as well just redirect to the image using
header("Location: address-of-image");
for delivering the file to your clients from your server and not from its original location you can just do. however your php.ini settings need to allow external file opens
readfile("http://www.example.com/image.jpg")
correct headers are not required if you are going to display the image in an img tag,
altough i would recommend it. you should check the filetype of the image or in most cases just set an octet-stream header so the browser doesnt assume an incorrect type like text or something and tries to display binary data.
to do so just do
header("Content-type: application/octet-stream")
one more thing to consider may be setting correct headers for caching...
You need to use
$image = fopen("image.png");
Modify the headers(not sure exacly if it's correct)
headers("Content-type: image/png");
And then send the image
echo fread($image, file_size("image.png"));

Categories